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

1226 lines
336 KiB
JSON

{
"address": "0xBDF3e6A0c721117B69150D00D9Fb27873023E4Df",
"abi": [
{
"inputs": [
{
"internalType": "uint256",
"name": "nativeTokenMaxBorrowLimitCap_",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "errorId_",
"type": "uint256"
}
],
"name": "FluidLiquidityCalcsError",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "errorId_",
"type": "uint256"
}
],
"name": "FluidLiquidityError",
"type": "error"
},
{
"anonymous": false,
"inputs": [],
"name": "BorrowRateMaxCap",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "newStatus",
"type": "uint256"
}
],
"name": "LogChangeStatus",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "LogCollectRevenue",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "address[]",
"name": "supplyTokens",
"type": "address[]"
},
{
"indexed": false,
"internalType": "address[]",
"name": "borrowTokens",
"type": "address[]"
}
],
"name": "LogPauseUser",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "address[]",
"name": "supplyTokens",
"type": "address[]"
},
{
"indexed": false,
"internalType": "address[]",
"name": "borrowTokens",
"type": "address[]"
}
],
"name": "LogUnpauseUser",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "bool",
"name": "value",
"type": "bool"
}
],
"indexed": false,
"internalType": "struct Structs.AddressBool[]",
"name": "authsStatus",
"type": "tuple[]"
}
],
"name": "LogUpdateAuths",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "supplyExchangePrice",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "borrowExchangePrice",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "borrowRate",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "utilization",
"type": "uint256"
}
],
"name": "LogUpdateExchangePrices",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "bool",
"name": "value",
"type": "bool"
}
],
"indexed": false,
"internalType": "struct Structs.AddressBool[]",
"name": "guardiansStatus",
"type": "tuple[]"
}
],
"name": "LogUpdateGuardians",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "kink",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationZero",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationKink",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationMax",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct Structs.RateDataV1Params[]",
"name": "tokenRateDatas",
"type": "tuple[]"
}
],
"name": "LogUpdateRateDataV1s",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "kink1",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "kink2",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationZero",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationKink1",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationKink2",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationMax",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct Structs.RateDataV2Params[]",
"name": "tokenRateDatas",
"type": "tuple[]"
}
],
"name": "LogUpdateRateDataV2s",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "revenueCollector",
"type": "address"
}
],
"name": "LogUpdateRevenueCollector",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "fee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxUtilization",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct Structs.TokenConfig[]",
"name": "tokenConfigs",
"type": "tuple[]"
}
],
"name": "LogUpdateTokenConfigs",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "user",
"type": "address"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint8",
"name": "mode",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseDebtCeiling",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxDebtCeiling",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct Structs.UserBorrowConfig[]",
"name": "userBorrowConfigs",
"type": "tuple[]"
}
],
"name": "LogUpdateUserBorrowConfigs",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct Structs.AddressUint256[]",
"name": "userClasses",
"type": "tuple[]"
}
],
"name": "LogUpdateUserClasses",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "user",
"type": "address"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint8",
"name": "mode",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseWithdrawalLimit",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct Structs.UserSupplyConfig[]",
"name": "userSupplyConfigs",
"type": "tuple[]"
}
],
"name": "LogUpdateUserSupplyConfigs",
"type": "event"
},
{
"inputs": [],
"name": "NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newStatus_",
"type": "uint256"
}
],
"name": "changeStatus",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "tokens_",
"type": "address[]"
}
],
"name": "collectRevenue",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user_",
"type": "address"
},
{
"internalType": "address[]",
"name": "supplyTokens_",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "borrowTokens_",
"type": "address[]"
}
],
"name": "pauseUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user_",
"type": "address"
},
{
"internalType": "address[]",
"name": "supplyTokens_",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "borrowTokens_",
"type": "address[]"
}
],
"name": "unpauseUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "bool",
"name": "value",
"type": "bool"
}
],
"internalType": "struct Structs.AddressBool[]",
"name": "authsStatus_",
"type": "tuple[]"
}
],
"name": "updateAuths",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "tokens_",
"type": "address[]"
}
],
"name": "updateExchangePrices",
"outputs": [
{
"internalType": "uint256[]",
"name": "supplyExchangePrices_",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "borrowExchangePrices_",
"type": "uint256[]"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "bool",
"name": "value",
"type": "bool"
}
],
"internalType": "struct Structs.AddressBool[]",
"name": "guardiansStatus_",
"type": "tuple[]"
}
],
"name": "updateGuardians",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "kink",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationZero",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationKink",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationMax",
"type": "uint256"
}
],
"internalType": "struct Structs.RateDataV1Params[]",
"name": "tokensRateData_",
"type": "tuple[]"
}
],
"name": "updateRateDataV1s",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "kink1",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "kink2",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationZero",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationKink1",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationKink2",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rateAtUtilizationMax",
"type": "uint256"
}
],
"internalType": "struct Structs.RateDataV2Params[]",
"name": "tokensRateData_",
"type": "tuple[]"
}
],
"name": "updateRateDataV2s",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "revenueCollector_",
"type": "address"
}
],
"name": "updateRevenueCollector",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "fee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxUtilization",
"type": "uint256"
}
],
"internalType": "struct Structs.TokenConfig[]",
"name": "tokenConfigs_",
"type": "tuple[]"
}
],
"name": "updateTokenConfigs",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "user",
"type": "address"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint8",
"name": "mode",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseDebtCeiling",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxDebtCeiling",
"type": "uint256"
}
],
"internalType": "struct Structs.UserBorrowConfig[]",
"name": "userBorrowConfigs_",
"type": "tuple[]"
}
],
"name": "updateUserBorrowConfigs",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"internalType": "struct Structs.AddressUint256[]",
"name": "userClasses_",
"type": "tuple[]"
}
],
"name": "updateUserClasses",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "user",
"type": "address"
},
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint8",
"name": "mode",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseWithdrawalLimit",
"type": "uint256"
}
],
"internalType": "struct Structs.UserSupplyConfig[]",
"name": "userSupplyConfigs_",
"type": "tuple[]"
}
],
"name": "updateUserSupplyConfigs",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x9e417ed3a7839bc91191ce5d86ad878e10a238e1b4b125b61ca16ff5b1169625",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x0Ed35B1609Ec45c7079E80d11149a52717e4859A",
"contractAddress": null,
"transactionIndex": 147,
"gasUsed": "5157833",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x2793f8f9440f8488b65dba0f4be99eb71bd5e589be9252bb6c070ded9279e167",
"transactionHash": "0x9e417ed3a7839bc91191ce5d86ad878e10a238e1b4b125b61ca16ff5b1169625",
"logs": [],
"blockNumber": 19959831,
"cumulativeGasUsed": "25852264",
"status": 1,
"byzantium": true
},
"args": [
"100000000000000000000000000"
],
"numDeployments": 2,
"solcInputHash": "033d84042c3fe6a1afa58a71e8e52d69",
"metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nativeTokenMaxBorrowLimitCap_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidLiquidityCalcsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidLiquidityError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BorrowRateMaxCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newStatus\",\"type\":\"uint256\"}],\"name\":\"LogChangeStatus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LogCollectRevenue\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"supplyTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"borrowTokens\",\"type\":\"address[]\"}],\"name\":\"LogPauseUser\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"supplyTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"borrowTokens\",\"type\":\"address[]\"}],\"name\":\"LogUnpauseUser\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"struct Structs.AddressBool[]\",\"name\":\"authsStatus\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateAuths\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"supplyExchangePrice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"borrowExchangePrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"borrowRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"utilization\",\"type\":\"uint256\"}],\"name\":\"LogUpdateExchangePrices\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"struct Structs.AddressBool[]\",\"name\":\"guardiansStatus\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateGuardians\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"kink\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationZero\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationKink\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationMax\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct Structs.RateDataV1Params[]\",\"name\":\"tokenRateDatas\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateRateDataV1s\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"kink1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"kink2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationZero\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationKink1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationKink2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationMax\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct Structs.RateDataV2Params[]\",\"name\":\"tokenRateDatas\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateRateDataV2s\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"revenueCollector\",\"type\":\"address\"}],\"name\":\"LogUpdateRevenueCollector\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxUtilization\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct Structs.TokenConfig[]\",\"name\":\"tokenConfigs\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateTokenConfigs\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseDebtCeiling\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxDebtCeiling\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct Structs.UserBorrowConfig[]\",\"name\":\"userBorrowConfigs\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateUserBorrowConfigs\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct Structs.AddressUint256[]\",\"name\":\"userClasses\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateUserClasses\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseWithdrawalLimit\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct Structs.UserSupplyConfig[]\",\"name\":\"userSupplyConfigs\",\"type\":\"tuple[]\"}],\"name\":\"LogUpdateUserSupplyConfigs\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newStatus_\",\"type\":\"uint256\"}],\"name\":\"changeStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"name\":\"collectRevenue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user_\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"supplyTokens_\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"borrowTokens_\",\"type\":\"address[]\"}],\"name\":\"pauseUser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user_\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"supplyTokens_\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"borrowTokens_\",\"type\":\"address[]\"}],\"name\":\"unpauseUser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"internalType\":\"struct Structs.AddressBool[]\",\"name\":\"authsStatus_\",\"type\":\"tuple[]\"}],\"name\":\"updateAuths\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"name\":\"updateExchangePrices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"supplyExchangePrices_\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"borrowExchangePrices_\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"internalType\":\"struct Structs.AddressBool[]\",\"name\":\"guardiansStatus_\",\"type\":\"tuple[]\"}],\"name\":\"updateGuardians\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"kink\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationZero\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationKink\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationMax\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.RateDataV1Params[]\",\"name\":\"tokensRateData_\",\"type\":\"tuple[]\"}],\"name\":\"updateRateDataV1s\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"kink1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"kink2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationZero\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationKink1\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationKink2\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateAtUtilizationMax\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.RateDataV2Params[]\",\"name\":\"tokensRateData_\",\"type\":\"tuple[]\"}],\"name\":\"updateRateDataV2s\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revenueCollector_\",\"type\":\"address\"}],\"name\":\"updateRevenueCollector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxUtilization\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.TokenConfig[]\",\"name\":\"tokenConfigs_\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseDebtCeiling\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxDebtCeiling\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserBorrowConfig[]\",\"name\":\"userBorrowConfigs_\",\"type\":\"tuple[]\"}],\"name\":\"updateUserBorrowConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.AddressUint256[]\",\"name\":\"userClasses_\",\"type\":\"tuple[]\"}],\"name\":\"updateUserClasses\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseWithdrawalLimit\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserSupplyConfig[]\",\"name\":\"userSupplyConfigs_\",\"type\":\"tuple[]\"}],\"name\":\"updateUserSupplyConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"changeStatus(uint256)\":{\"params\":{\"newStatus_\":\"new status status = 2 -> pause, status = 1 -> resume.\"}},\"collectRevenue(address[])\":{\"details\":\"Note that this can revert if token balance is < revenueAmount (utilization > 100%)\",\"params\":{\"tokens_\":\"array of tokens to collect revenue for\"}},\"pauseUser(address,address[],address[])\":{\"params\":{\"borrowTokens_\":\"token addresses to pause borrowings for\",\"supplyTokens_\":\"token addresses to pause withdrawals for\",\"user_\":\"address of user to pause operations for\"}},\"unpauseUser(address,address[],address[])\":{\"params\":{\"borrowTokens_\":\"token addresses to unpause borrowings for\",\"supplyTokens_\":\"token addresses to unpause withdrawals for\",\"user_\":\"address of user to unpause operations for\"}},\"updateAuths((address,bool)[])\":{\"params\":{\"authsStatus_\":\"array of structs setting allowed status for an address. status true => add auth, false => remove auth\"}},\"updateExchangePrices(address[])\":{\"params\":{\"tokens_\":\"tokens to update exchange prices for\"},\"returns\":{\"borrowExchangePrices_\":\"new borrow rates of overall system for each token\",\"supplyExchangePrices_\":\"new supply rates of overall system for each token\"}},\"updateGuardians((address,bool)[])\":{\"params\":{\"guardiansStatus_\":\"array of structs setting allowed status for an address. status true => add guardian, false => remove guardian\"}},\"updateRateDataV1s((address,uint256,uint256,uint256,uint256)[])\":{\"params\":{\"tokensRateData_\":\"array of RateDataV1Params with rate data to set for each token\"}},\"updateRateDataV2s((address,uint256,uint256,uint256,uint256,uint256,uint256)[])\":{\"params\":{\"tokensRateData_\":\"array of RateDataV2Params with rate data to set for each token\"}},\"updateRevenueCollector(address)\":{\"params\":{\"revenueCollector_\":\"new revenue collector address\"}},\"updateTokenConfigs((address,uint256,uint256,uint256)[])\":{\"params\":{\"tokenConfigs_\":\"contains token address, fee & utilization threshold\"}},\"updateUserBorrowConfigs((address,address,uint8,uint256,uint256,uint256,uint256)[])\":{\"params\":{\"userBorrowConfigs_\":\"struct array containing user borrow config, see `UserBorrowConfig` struct for more info\"}},\"updateUserClasses((address,uint256)[])\":{\"params\":{\"userClasses_\":\"struct array of uint256 value to assign for each user address\"}},\"updateUserSupplyConfigs((address,address,uint8,uint256,uint256,uint256)[])\":{\"params\":{\"userSupplyConfigs_\":\"struct array containing user supply config, see `UserSupplyConfig` struct for more info\"}}},\"title\":\"Fluid Liquidity AdminModule\",\"version\":1},\"userdoc\":{\"events\":{\"BorrowRateMaxCap()\":{\"notice\":\"emitted if the calculated borrow rate surpassed max borrow rate (16 bits) and was capped at maximum value 65535\"},\"LogChangeStatus(uint256)\":{\"notice\":\"emitted when status is changed (paused / unpaused)\"},\"LogCollectRevenue(address,uint256)\":{\"notice\":\"emitted when revenue is collected\"},\"LogPauseUser(address,address[],address[])\":{\"notice\":\"emitted when a user gets certain tokens paused\"},\"LogUnpauseUser(address,address[],address[])\":{\"notice\":\"emitted when a user gets certain tokens unpaused\"},\"LogUpdateAuths((address,bool)[])\":{\"notice\":\"emitted when allowed auths are updated\"},\"LogUpdateExchangePrices(address,uint256,uint256,uint256,uint256)\":{\"notice\":\"emitted when exchange prices and borrow rate are updated\"},\"LogUpdateGuardians((address,bool)[])\":{\"notice\":\"emitted when allowed guardians are updated\"},\"LogUpdateRateDataV1s((address,uint256,uint256,uint256,uint256)[])\":{\"notice\":\"emitted when token rate data is updated with rate data v1\"},\"LogUpdateRateDataV2s((address,uint256,uint256,uint256,uint256,uint256,uint256)[])\":{\"notice\":\"emitted when token rate data is updated with rate data v2\"},\"LogUpdateRevenueCollector(address)\":{\"notice\":\"emitted when revenue collector address is updated\"},\"LogUpdateTokenConfigs((address,uint256,uint256,uint256)[])\":{\"notice\":\"emitted when token configs are updated\"},\"LogUpdateUserBorrowConfigs((address,address,uint8,uint256,uint256,uint256,uint256)[])\":{\"notice\":\"emitted when user borrow configs are updated\"},\"LogUpdateUserClasses((address,uint256)[])\":{\"notice\":\"emitted when user classes are updated\"},\"LogUpdateUserSupplyConfigs((address,address,uint8,uint256,uint256,uint256)[])\":{\"notice\":\"emitted when user supply configs are updated\"}},\"kind\":\"user\",\"methods\":{\"changeStatus(uint256)\":{\"notice\":\"changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths.\"},\"collectRevenue(address[])\":{\"notice\":\"collects revenue for tokens to configured revenueCollector address.\"},\"pauseUser(address,address[],address[])\":{\"notice\":\"pause operations for a particular user in class 0 (class 1 users can't be paused by guardians). Only callable by Guardians.\"},\"unpauseUser(address,address[],address[])\":{\"notice\":\"unpause operations for a particular user in class 0 (class 1 users can't be paused by guardians). Only callable by Guardians.\"},\"updateAuths((address,bool)[])\":{\"notice\":\"adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract. auths can be helpful in reducing governance overhead where it's not needed.\"},\"updateExchangePrices(address[])\":{\"notice\":\"gets the current updated exchange prices for n tokens and updates all prices, rates related data in storage.\"},\"updateGuardians((address,bool)[])\":{\"notice\":\"adds/removes guardians. Only callable by Governance.\"},\"updateRateDataV1s((address,uint256,uint256,uint256,uint256)[])\":{\"notice\":\"update tokens rate data version 1. Only callable by Auths.\"},\"updateRateDataV2s((address,uint256,uint256,uint256,uint256,uint256,uint256)[])\":{\"notice\":\"update tokens rate data version 2. Only callable by Auths.\"},\"updateRevenueCollector(address)\":{\"notice\":\"changes the revenue collector address (contract that is sent revenue). Only callable by Governance.\"},\"updateTokenConfigs((address,uint256,uint256,uint256)[])\":{\"notice\":\"updates token configs: fee charge on borrowers interest & storage update utilization threshold. Only callable by Auths.\"},\"updateUserBorrowConfigs((address,address,uint8,uint256,uint256,uint256,uint256)[])\":{\"notice\":\"setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits. Only callable by Auths.\"},\"updateUserClasses((address,uint256)[])\":{\"notice\":\"updates user classes: 0 is for new protocols, 1 is for established protocols. Only callable by Auths.\"},\"updateUserSupplyConfigs((address,address,uint8,uint256,uint256,uint256)[])\":{\"notice\":\"sets user supply configs per token basis. Eg: with interest or interest-free and automated limits. Only callable by Auths.\"}},\"notice\":\"Fluid Liquidity auth protected methods to configure things such as: guardians, auths, governance, revenue, token configs, allowances etc. Accessibility of methods is restricted to Governance, Auths or Guardians. Governance is Auth & Governance by default\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/liquidity/adminModule/main.sol\":\"FluidLiquidityAdminModule\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"@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\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9b72f93be69ca894d8492c244259615c4a742afc8d63720dbc8bb81087d9b238\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"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/events.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { Structs } from \\\"./structs.sol\\\";\\n\\ncontract Events is Structs {\\n /// @notice emitted when allowed auths are updated\\n event LogUpdateAuths(AddressBool[] authsStatus);\\n\\n /// @notice emitted when allowed guardians are updated\\n event LogUpdateGuardians(AddressBool[] guardiansStatus);\\n\\n /// @notice emitted when revenue collector address is updated\\n event LogUpdateRevenueCollector(address indexed revenueCollector);\\n\\n /// @notice emitted when status is changed (paused / unpaused)\\n event LogChangeStatus(uint256 indexed newStatus);\\n\\n /// @notice emitted when user classes are updated\\n event LogUpdateUserClasses(AddressUint256[] userClasses);\\n\\n /// @notice emitted when token configs are updated\\n event LogUpdateTokenConfigs(TokenConfig[] tokenConfigs);\\n\\n /// @notice emitted when user supply configs are updated\\n event LogUpdateUserSupplyConfigs(UserSupplyConfig[] userSupplyConfigs);\\n\\n /// @notice emitted when user borrow configs are updated\\n event LogUpdateUserBorrowConfigs(UserBorrowConfig[] userBorrowConfigs);\\n\\n /// @notice emitted when a user gets certain tokens paused\\n event LogPauseUser(address user, address[] supplyTokens, address[] borrowTokens);\\n\\n /// @notice emitted when a user gets certain tokens unpaused\\n event LogUnpauseUser(address user, address[] supplyTokens, address[] borrowTokens);\\n\\n /// @notice emitted when token rate data is updated with rate data v1\\n event LogUpdateRateDataV1s(RateDataV1Params[] tokenRateDatas);\\n\\n /// @notice emitted when token rate data is updated with rate data v2\\n event LogUpdateRateDataV2s(RateDataV2Params[] tokenRateDatas);\\n\\n /// @notice emitted when revenue is collected\\n event LogCollectRevenue(address indexed token, uint256 indexed amount);\\n\\n /// @notice emitted when exchange prices and borrow rate are updated\\n event LogUpdateExchangePrices(\\n address indexed token,\\n uint256 indexed supplyExchangePrice,\\n uint256 indexed borrowExchangePrice,\\n uint256 borrowRate,\\n uint256 utilization\\n );\\n}\\n\",\"keccak256\":\"0xaaab5be04a1832e8d95c46ce041ae85db1ff71090e2cfc72c1d675af3943bdec\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/adminModule/main.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport { FixedPointMathLib } from \\\"solmate/src/utils/FixedPointMathLib.sol\\\";\\n\\nimport { BigMathMinified } from \\\"../../libraries/bigMathMinified.sol\\\";\\nimport { LiquidityCalcs } from \\\"../../libraries/liquidityCalcs.sol\\\";\\nimport { LiquiditySlotsLink } from \\\"../../libraries/liquiditySlotsLink.sol\\\";\\nimport { Events } from \\\"./events.sol\\\";\\nimport { Structs } from \\\"./structs.sol\\\";\\nimport { CommonHelpers } from \\\"../common/helpers.sol\\\";\\nimport { IFluidLiquidityAdmin } from \\\"../interfaces/iLiquidity.sol\\\";\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\nimport { Error } from \\\"../error.sol\\\";\\n\\nabstract contract AdminModuleConstants is Error {\\n /// @dev hard cap value for max borrow limit, used as sanity check. Usually 10x of total supply.\\n uint256 public immutable NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP;\\n\\n constructor(uint256 nativeTokenMaxBorrowLimitCap_) {\\n if (nativeTokenMaxBorrowLimitCap_ == 0) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n\\n NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP = nativeTokenMaxBorrowLimitCap_;\\n }\\n}\\n\\n/// @notice Fluid Liquidity Governance only related methods\\nabstract contract GovernanceModule is IFluidLiquidityAdmin, CommonHelpers, Events, AdminModuleConstants {\\n /// @notice only governance guard\\n modifier onlyGovernance() {\\n if (_getGovernanceAddr() != msg.sender) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__OnlyGovernance);\\n }\\n _;\\n }\\n\\n /// @dev checks that `value_` is a valid address (not zero address)\\n function _checkValidAddress(address value_) internal pure {\\n if (value_ == address(0)) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__AddressZero);\\n }\\n }\\n\\n /// @dev checks that `value_` address is a contract (which includes address zero check)\\n function _checkIsContractOrNativeAddress(address value_) internal view {\\n if (value_.code.length == 0 && value_ != NATIVE_TOKEN_ADDRESS) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__AddressNotAContract);\\n }\\n }\\n\\n /// @dev checks that `token_` decimals are between `MIN_TOKEN_DECIMALS` and `MAX_TOKEN_DECIMALS` (inclusive).\\n function _checkTokenDecimalsRange(address token_) internal view {\\n uint8 decimals_ = token_ == NATIVE_TOKEN_ADDRESS ? NATIVE_TOKEN_DECIMALS : IERC20Metadata(token_).decimals();\\n if (decimals_ < MIN_TOKEN_DECIMALS || decimals_ > MAX_TOKEN_DECIMALS) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__TokenInvalidDecimalsRange);\\n }\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateAuths(AddressBool[] calldata authsStatus_) external onlyGovernance {\\n uint256 length_ = authsStatus_.length;\\n for (uint256 i; i < length_; ) {\\n _checkValidAddress(authsStatus_[i].addr);\\n\\n _isAuth[authsStatus_[i].addr] = authsStatus_[i].value ? 1 : 0;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateAuths(authsStatus_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateGuardians(AddressBool[] calldata guardiansStatus_) external onlyGovernance {\\n uint256 length_ = guardiansStatus_.length;\\n for (uint256 i; i < length_; ) {\\n _checkValidAddress(guardiansStatus_[i].addr);\\n\\n _isGuardian[guardiansStatus_[i].addr] = guardiansStatus_[i].value ? 1 : 0;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateGuardians(guardiansStatus_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateRevenueCollector(address revenueCollector_) external onlyGovernance {\\n _checkValidAddress(revenueCollector_);\\n\\n _revenueCollector = revenueCollector_;\\n\\n emit LogUpdateRevenueCollector(revenueCollector_);\\n }\\n}\\n\\nabstract contract AuthInternals is Error, CommonHelpers, Events {\\n /// @dev computes rata data packed uint256 for version 1 rate input params telling desired values\\n /// at different uzilitation points (0%, kink, 100%)\\n /// @param rataDataV1Params_ rata data params for a given token\\n /// @return rateData_ packed uint256 rate data\\n function _computeRateDataPackedV1(\\n RateDataV1Params memory rataDataV1Params_\\n ) internal pure returns (uint256 rateData_) {\\n if (rataDataV1Params_.rateAtUtilizationZero > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_ZERO);\\n }\\n if (rataDataV1Params_.rateAtUtilizationKink > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_KINK);\\n }\\n if (rataDataV1Params_.rateAtUtilizationMax > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_MAX);\\n }\\n if (\\n // kink must not be 0 or >= 100% (being 0 or 100% would lead to division through 0 at calculation time)\\n rataDataV1Params_.kink == 0 ||\\n rataDataV1Params_.kink >= FOUR_DECIMALS ||\\n // for the last part of rate curve a spike increase must be present as utilization grows.\\n // declining rate is supported before kink. kink to max must be increasing.\\n // @dev Note rates can be equal, that leads to a 0 slope which is supported in calculation code.\\n rataDataV1Params_.rateAtUtilizationKink > rataDataV1Params_.rateAtUtilizationMax\\n ) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n\\n rateData_ =\\n 1 | // version\\n (rataDataV1Params_.rateAtUtilizationZero << LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO) |\\n (rataDataV1Params_.kink << LiquiditySlotsLink.BITS_RATE_DATA_V1_UTILIZATION_AT_KINK) |\\n (rataDataV1Params_.rateAtUtilizationKink << LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) |\\n (rataDataV1Params_.rateAtUtilizationMax << LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX);\\n }\\n\\n /// @dev computes rata data packed uint256 for rate version 2 input params telling desired values\\n /// at different uzilitation points (0%, kink1, kink2, 100%)\\n /// @param rataDataV2Params_ rata data params for a given token\\n /// @return rateData_ packed uint256 rate data\\n function _computeRateDataPackedV2(\\n RateDataV2Params memory rataDataV2Params_\\n ) internal pure returns (uint256 rateData_) {\\n if (rataDataV2Params_.rateAtUtilizationZero > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_ZERO);\\n }\\n if (rataDataV2Params_.rateAtUtilizationKink1 > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_KINK1);\\n }\\n if (rataDataV2Params_.rateAtUtilizationKink2 > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_KINK2);\\n }\\n if (rataDataV2Params_.rateAtUtilizationMax > X16) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__RATE_AT_UTIL_MAX_V2);\\n }\\n if (\\n // kink can not be 0, >= 100% or >= kink2 (would lead to division through 0 at calculation time)\\n rataDataV2Params_.kink1 == 0 ||\\n rataDataV2Params_.kink1 >= FOUR_DECIMALS ||\\n rataDataV2Params_.kink1 >= rataDataV2Params_.kink2 ||\\n // kink2 can not be >= 100% (must be > kink1 already checked)\\n rataDataV2Params_.kink2 >= FOUR_DECIMALS ||\\n // for the last part of rate curve a spike increase must be present as utilization grows.\\n // declining rate is supported before kink2. kink2 to max must be increasing.\\n // @dev Note rates can be equal, that leads to a 0 slope which is supported in calculation code.\\n rataDataV2Params_.rateAtUtilizationKink2 > rataDataV2Params_.rateAtUtilizationMax\\n ) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n\\n rateData_ =\\n 2 | // version\\n (rataDataV2Params_.rateAtUtilizationZero << LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO) |\\n (rataDataV2Params_.kink1 << LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1) |\\n (rataDataV2Params_.rateAtUtilizationKink1 <<\\n LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) |\\n (rataDataV2Params_.kink2 << LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2) |\\n (rataDataV2Params_.rateAtUtilizationKink2 <<\\n LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) |\\n (rataDataV2Params_.rateAtUtilizationMax << LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX);\\n }\\n\\n /// @dev updates the exchange prices in storage for `token_` and returns `supplyExchangePrice_` and `borrowExchangePrice_`.\\n /// Recommended to use only in a method that later calls `_updateExchangePricesAndRates()`.\\n function _updateExchangePrices(\\n address token_\\n ) internal returns (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) {\\n uint256 exchangePricesAndConfig_ = _exchangePricesAndConfig[token_];\\n\\n // calculate the new exchange prices based on earned interest\\n (supplyExchangePrice_, borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(exchangePricesAndConfig_);\\n\\n // ensure values written to storage do not exceed the dedicated bit space in packed uint256 slots\\n if (supplyExchangePrice_ > X64 || borrowExchangePrice_ > X64) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXCHANGE_PRICES);\\n }\\n\\n // write updated exchangePrices_ for token to storage\\n _exchangePricesAndConfig[token_] =\\n (exchangePricesAndConfig_ &\\n // mask to update bits: 58-218 (timestamp and exchange prices)\\n 0xfffffffff80000000000000000000000000000000000000003ffffffffffffff) |\\n (block.timestamp << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) |\\n (supplyExchangePrice_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) |\\n (borrowExchangePrice_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE);\\n\\n emit LogUpdateExchangePrices(\\n token_,\\n supplyExchangePrice_,\\n borrowExchangePrice_,\\n exchangePricesAndConfig_ & X16, // borrow rate is unchanged -> read from exchangePricesAndConfig_\\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14 // utilization is unchanged -> read from exchangePricesAndConfig_\\n );\\n\\n return (supplyExchangePrice_, borrowExchangePrice_);\\n }\\n\\n /// @dev updates the exchange prices + rates in storage for `token_` and returns `supplyExchangePrice_` and `borrowExchangePrice_`\\n function _updateExchangePricesAndRates(\\n address token_\\n ) internal returns (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) {\\n uint256 exchangePricesAndConfig_ = _exchangePricesAndConfig[token_];\\n // calculate the new exchange prices based on earned interest\\n (supplyExchangePrice_, borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(exchangePricesAndConfig_);\\n\\n uint256 totalAmounts_ = _totalAmounts[token_];\\n\\n // calculate updated ratios\\n // set supplyRatio_ = supplyWithInterest here, using that value for total supply before finish calc supplyRatio\\n uint256 supplyRatio_ = ((BigMathMinified.fromBigNumber(\\n (totalAmounts_ & X64),\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n ) * supplyExchangePrice_) / EXCHANGE_PRICES_PRECISION);\\n // set borrowRatio_ = borrowWithInterest here, using that value for total borrow before finish calc borrowRatio\\n uint256 borrowRatio_ = ((BigMathMinified.fromBigNumber(\\n (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST) & X64,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n ) * borrowExchangePrice_) / EXCHANGE_PRICES_PRECISION);\\n\\n uint256 supplyInterestFree_ = BigMathMinified.fromBigNumber(\\n (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE) & X64,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n uint256 borrowInterestFree_ = BigMathMinified.fromBigNumber(\\n // no & mask needed for borrow interest free as it occupies the last bits in the storage slot\\n (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE),\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n // calculate utilization: totalBorrow / totalSupply. If no supply, utilization must be 0 (avoid division by 0)\\n uint256 utilization_ = 0;\\n if (supplyRatio_ > 0 || supplyInterestFree_ > 0) {\\n utilization_ = (((borrowRatio_ + borrowInterestFree_) * FOUR_DECIMALS) /\\n (supplyRatio_ + supplyInterestFree_));\\n }\\n\\n // finish calculating supply & borrow ratio\\n // ########## calculating supply ratio ##########\\n // supplyRatio_ holds value of supplyWithInterest below\\n if (supplyRatio_ > supplyInterestFree_) {\\n // supplyRatio_ is ratio with 1 bit as 0 as supply interest raw is bigger\\n supplyRatio_ = ((supplyInterestFree_ * FOUR_DECIMALS) / supplyRatio_) << 1;\\n // because of checking to divide by bigger amount, ratio can never be > 100%\\n } else if (supplyRatio_ < supplyInterestFree_) {\\n // supplyRatio_ is ratio with 1 bit as 1 as supply interest free is bigger\\n supplyRatio_ = (((supplyRatio_ * FOUR_DECIMALS) / supplyInterestFree_) << 1) | 1;\\n // because of checking to divide by bigger amount, ratio can never be > 100%\\n } else {\\n // supplies match exactly (supplyWithInterest == supplyInterestFree)\\n if (supplyRatio_ > 0) {\\n // supplies are not 0 -> set ratio to 1 (with first bit set to 0, doesn't matter)\\n supplyRatio_ = FOUR_DECIMALS << 1;\\n } else {\\n // if total supply = 0\\n supplyRatio_ = 0;\\n }\\n }\\n\\n // ########## calculating borrow ratio ##########\\n // borrowRatio_ holds value of borrowWithInterest below\\n if (borrowRatio_ > borrowInterestFree_) {\\n // borrowRatio_ is ratio with 1 bit as 0 as borrow interest raw is bigger\\n borrowRatio_ = ((borrowInterestFree_ * FOUR_DECIMALS) / borrowRatio_) << 1;\\n // because of checking to divide by bigger amount, ratio can never be > 100%\\n } else if (borrowRatio_ < borrowInterestFree_) {\\n // borrowRatio_ is ratio with 1 bit as 1 as borrow interest free is bigger\\n borrowRatio_ = (((borrowRatio_ * FOUR_DECIMALS) / borrowInterestFree_) << 1) | 1;\\n // because of checking to divide by bigger amount, ratio can never be > 100%\\n } else {\\n // borrows match exactly (borrowWithInterest == borrowInterestFree)\\n if (borrowRatio_ > 0) {\\n // borrows are not 0 -> set ratio to 1 (with first bit set to 0, doesn't matter)\\n borrowRatio_ = FOUR_DECIMALS << 1;\\n } else {\\n // if total borrows = 0\\n borrowRatio_ = 0;\\n }\\n }\\n\\n // updated borrow rate from utilization\\n uint256 borrowRate_ = LiquidityCalcs.calcBorrowRateFromUtilization(_rateData[token_], utilization_);\\n\\n // ensure values written to storage do not exceed the dedicated bit space in packed uint256 slots\\n if (supplyExchangePrice_ > X64 || borrowExchangePrice_ > X64) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXCHANGE_PRICES);\\n }\\n if (utilization_ > X14) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__UTILIZATION);\\n }\\n\\n // write updated exchangePrices_ for token to storage\\n _exchangePricesAndConfig[token_] =\\n (exchangePricesAndConfig_ &\\n // mask to update bits: 0-15 (borrow rate), 30-43 (utilization), 58-248 (timestamp, exchange prices, ratios)\\n 0xfe000000000000000000000000000000000000000000000003fff0003fff0000) |\\n borrowRate_ | // already includes an overflow check in `calcBorrowRateFromUtilization`\\n (utilization_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) |\\n (block.timestamp << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) |\\n (supplyExchangePrice_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) |\\n (borrowExchangePrice_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) |\\n // ratios can never be > 100%, no overflow check needed\\n (supplyRatio_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_RATIO) |\\n (borrowRatio_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_RATIO);\\n\\n emit LogUpdateExchangePrices(token_, supplyExchangePrice_, borrowExchangePrice_, borrowRate_, utilization_);\\n\\n return (supplyExchangePrice_, borrowExchangePrice_);\\n }\\n}\\n\\n/// @notice Fluid Liquidity Auths only related methods\\nabstract contract AuthModule is AuthInternals, GovernanceModule {\\n using BigMathMinified for uint256;\\n\\n /// @dev max update on storage threshold as a sanity check. threshold is in 1e2, so 500 = 5%.\\n /// A higher threshold is not allowed as it would cause the borrow rate to be updated too rarely.\\n uint256 private constant MAX_TOKEN_CONFIG_UPDATE_THRESHOLD = 500;\\n\\n /// @dev only auths guard\\n modifier onlyAuths() {\\n if (_isAuth[msg.sender] & 1 != 1 && _getGovernanceAddr() != msg.sender) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__OnlyAuths);\\n }\\n _;\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function collectRevenue(address[] calldata tokens_) external onlyAuths {\\n address payable revenueCollector_ = payable(_revenueCollector);\\n if (revenueCollector_ == address(0)) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__RevenueCollectorNotSet);\\n }\\n\\n uint256 length_ = tokens_.length;\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(tokens_[i]);\\n\\n bool isNativeToken_ = tokens_[i] == NATIVE_TOKEN_ADDRESS;\\n\\n // get revenue amount with updated interest etc.\\n uint256 revenueAmount_ = LiquidityCalcs.calcRevenue(\\n _totalAmounts[tokens_[i]],\\n _exchangePricesAndConfig[tokens_[i]],\\n isNativeToken_ ? address(this).balance : IERC20(tokens_[i]).balanceOf(address(this))\\n );\\n\\n if (revenueAmount_ > 0) {\\n // transfer token amount to revenueCollector address\\n if (isNativeToken_) {\\n Address.sendValue(revenueCollector_, revenueAmount_);\\n } else {\\n SafeERC20.safeTransfer(IERC20(tokens_[i]), revenueCollector_, revenueAmount_);\\n }\\n }\\n\\n emit LogCollectRevenue(tokens_[i], revenueAmount_);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function changeStatus(uint256 newStatus_) external onlyAuths {\\n if (newStatus_ == 0 || newStatus_ > 2) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n\\n _status = newStatus_;\\n\\n emit LogChangeStatus(newStatus_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateRateDataV1s(RateDataV1Params[] calldata tokensRateData_) external onlyAuths {\\n uint256 length_ = tokensRateData_.length;\\n uint256 rateData_;\\n\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(tokensRateData_[i].token);\\n\\n // token that is being listed must have between 6 and 18 decimals.\\n // setting rate data is the first step for listing a token, so this check blocks any\\n // unsupported token to ever be listed at Liquidity\\n _checkTokenDecimalsRange(tokensRateData_[i].token);\\n\\n rateData_ = _rateData[tokensRateData_[i].token];\\n\\n // apply current rate data to exchange prices before updating to new rate data\\n if (rateData_ != 0) {\\n _updateExchangePrices(tokensRateData_[i].token);\\n }\\n\\n _rateData[tokensRateData_[i].token] = _computeRateDataPackedV1(tokensRateData_[i]);\\n\\n if (rateData_ != 0) {\\n // apply new rate data to borrow rate\\n _updateExchangePricesAndRates(tokensRateData_[i].token);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateRateDataV1s(tokensRateData_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateRateDataV2s(RateDataV2Params[] calldata tokensRateData_) external onlyAuths {\\n uint256 length_ = tokensRateData_.length;\\n uint256 rateData_;\\n\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(tokensRateData_[i].token);\\n\\n // token that is being listed must have between 6 and 18 decimals.\\n // setting rate data is the first step for listing a token, so this check blocks any\\n // unsupported token to ever be listed at Liquidity\\n _checkTokenDecimalsRange(tokensRateData_[i].token);\\n\\n rateData_ = _rateData[tokensRateData_[i].token];\\n\\n // apply current rate data to exchange prices before updating to new rate data\\n if (rateData_ != 0) {\\n _updateExchangePrices(tokensRateData_[i].token);\\n }\\n\\n _rateData[tokensRateData_[i].token] = _computeRateDataPackedV2(tokensRateData_[i]);\\n\\n if (rateData_ != 0) {\\n // apply new rate data to borrow rate\\n _updateExchangePricesAndRates(tokensRateData_[i].token);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateRateDataV2s(tokensRateData_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateTokenConfigs(TokenConfig[] calldata tokenConfigs_) external onlyAuths {\\n uint256 length_ = tokenConfigs_.length;\\n uint256 exchangePricesAndConfig_;\\n uint256 supplyExchangePrice_;\\n uint256 borrowExchangePrice_;\\n\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(tokenConfigs_[i].token);\\n if (_rateData[tokenConfigs_[i].token] == 0) {\\n // rate data must be configured before token config\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidConfigOrder);\\n }\\n if (tokenConfigs_[i].fee > FOUR_DECIMALS) {\\n // fee can not be > 100%\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__FEE);\\n }\\n if (tokenConfigs_[i].maxUtilization > FOUR_DECIMALS) {\\n // borrows above 100% should never be possible\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__MAX_UTILIZATION);\\n }\\n if (tokenConfigs_[i].threshold > MAX_TOKEN_CONFIG_UPDATE_THRESHOLD) {\\n // update on storage threshold can not be > MAX_TOKEN_CONFIG_UPDATE_THRESHOLD\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__THRESHOLD);\\n }\\n\\n exchangePricesAndConfig_ = _exchangePricesAndConfig[tokenConfigs_[i].token];\\n\\n // extract 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 // calculate the current exchange prices based on earned interest before updating fee + timestamp in storage\\n (supplyExchangePrice_, borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(\\n exchangePricesAndConfig_\\n );\\n\\n // ensure values written to storage do not exceed the dedicated bit space in packed uint256 slots\\n if (supplyExchangePrice_ > X64 || borrowExchangePrice_ > X64) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXCHANGE_PRICES);\\n }\\n } else {\\n // exchange prices can only increase once set so if either one is 0, the other must be 0 too.\\n supplyExchangePrice_ = EXCHANGE_PRICES_PRECISION;\\n borrowExchangePrice_ = EXCHANGE_PRICES_PRECISION;\\n\\n _listedTokens.push(tokenConfigs_[i].token);\\n }\\n\\n // max utilization of 100% is default, configs2 slot is not used in that case\\n bool usesConfigs2_ = tokenConfigs_[i].maxUtilization != FOUR_DECIMALS;\\n\\n _exchangePricesAndConfig[tokenConfigs_[i].token] =\\n // mask to set bits 16-29 (fee), 44-218 (update storage threshold, timestamp, exchange prices)\\n // and flag for uses configs2 at bit 249\\n (exchangePricesAndConfig_ & 0xfdfffffff80000000000000000000000000000000000000000000fffc000ffff) |\\n (tokenConfigs_[i].fee << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_FEE) |\\n (tokenConfigs_[i].threshold << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UPDATE_THRESHOLD) |\\n (block.timestamp << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) |\\n (supplyExchangePrice_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) |\\n (borrowExchangePrice_ << LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) |\\n ((uint256(usesConfigs2_ ? 1 : 0)) << uint256(LiquiditySlotsLink.BITS_EXCHANGE_PRICES_USES_CONFIGS2));\\n\\n _configs2[tokenConfigs_[i].token] =\\n // set max utilization at bits 0-14\\n (_configs2[tokenConfigs_[i].token] &\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000) |\\n (usesConfigs2_ ? tokenConfigs_[i].maxUtilization : 0);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateTokenConfigs(tokenConfigs_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateUserClasses(AddressUint256[] calldata userClasses_) external onlyAuths {\\n uint256 length_ = userClasses_.length;\\n for (uint256 i = 0; i < length_; ) {\\n if (userClasses_[i].value > 1) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n _checkIsContractOrNativeAddress(userClasses_[i].addr);\\n\\n _userClass[userClasses_[i].addr] = userClasses_[i].value;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateUserClasses(userClasses_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateUserSupplyConfigs(UserSupplyConfig[] memory userSupplyConfigs_) external onlyAuths {\\n uint256 userSupplyData_;\\n uint256 totalAmounts_;\\n uint256 totalSupplyRawInterest_;\\n uint256 totalSupplyInterestFree_;\\n uint256 supplyConversion_;\\n uint256 withdrawLimitConversion_;\\n uint256 supplyExchangePrice_;\\n\\n for (uint256 i; i < userSupplyConfigs_.length; ) {\\n _checkIsContractOrNativeAddress(userSupplyConfigs_[i].user);\\n _checkIsContractOrNativeAddress(userSupplyConfigs_[i].token);\\n if (_exchangePricesAndConfig[userSupplyConfigs_[i].token] == 0) {\\n // token config must be configured before setting any user supply config\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidConfigOrder);\\n }\\n if (\\n userSupplyConfigs_[i].mode > 1 ||\\n // can not set expand duration to 0 as that could cause a division by 0 in LiquidityCalcs.\\n // having expand duration as 0 is anyway not an expected config so removing the possibility for that.\\n // if no expansion is wanted, simply set expandDuration to 1 and expandPercent to 0.\\n userSupplyConfigs_[i].expandDuration == 0\\n ) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n if (userSupplyConfigs_[i].expandPercent > FOUR_DECIMALS) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXPAND_PERCENT);\\n }\\n if (userSupplyConfigs_[i].expandDuration > X24) {\\n // duration is max 24 bits\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXPAND_DURATION);\\n }\\n if (userSupplyConfigs_[i].baseWithdrawalLimit == 0) {\\n // base withdrawal limit can not be 0. As a side effect, this ensures that there is no supply config\\n // where all values would be 0, so configured users can be differentiated in the mapping.\\n revert FluidLiquidityError(ErrorTypes.AdminModule__LimitZero);\\n }\\n // @dev baseWithdrawalLimit has no max bits amount as it is in normal token amount & converted to BigNumber\\n\\n // get current user config data from storage\\n userSupplyData_ = _userSupplyData[userSupplyConfigs_[i].user][userSupplyConfigs_[i].token];\\n\\n // if userSupplyData_ == 0 (new setup) or if mode is unchanged, normal update is possible.\\n // else if mode changes, values have to be converted from raw <> normal etc.\\n if (\\n userSupplyData_ == 0 ||\\n (userSupplyData_ & 1 == 0 && userSupplyConfigs_[i].mode == 0) ||\\n (userSupplyData_ & 1 == 1 && userSupplyConfigs_[i].mode == 1)\\n ) {\\n // Updating user data on storage\\n\\n _userSupplyData[userSupplyConfigs_[i].user][userSupplyConfigs_[i].token] =\\n // mask to update first bit + bits 162-217 (expand percentage, expand duration, base limit)\\n (userSupplyData_ & 0xfffffffffc00000000000003fffffffffffffffffffffffffffffffffffffffe) |\\n (userSupplyConfigs_[i].mode) | // at first bit\\n (userSupplyConfigs_[i].expandPercent << LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) |\\n (userSupplyConfigs_[i].expandDuration << LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) |\\n // convert base withdrawal limit to BigNumber for storage (10 | 8). (below this, 100% can be withdrawn)\\n (userSupplyConfigs_[i].baseWithdrawalLimit.toBigNumber(\\n SMALL_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n ) << LiquiditySlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT);\\n } else {\\n // mode changes -> values have to be converted from raw <> normal etc.\\n\\n // if the mode changes then update _exchangePricesAndConfig related data in storage always\\n // update exchange prices timely before applying changes that affect utilization, rate etc.\\n _updateExchangePrices(userSupplyConfigs_[i].token);\\n\\n // get updated exchange prices for the token\\n (supplyExchangePrice_, ) = LiquidityCalcs.calcExchangePrices(\\n _exchangePricesAndConfig[userSupplyConfigs_[i].token]\\n );\\n\\n totalAmounts_ = _totalAmounts[userSupplyConfigs_[i].token];\\n totalSupplyRawInterest_ = BigMathMinified.fromBigNumber(\\n (totalAmounts_ & X64),\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n totalSupplyInterestFree_ = BigMathMinified.fromBigNumber(\\n (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE) & X64,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n // read current user supply & withdraw limit values\\n // here supplyConversion_ = user supply amount\\n supplyConversion_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_AMOUNT) & X64;\\n supplyConversion_ =\\n (supplyConversion_ >> DEFAULT_EXPONENT_SIZE) <<\\n (supplyConversion_ & DEFAULT_EXPONENT_MASK);\\n\\n withdrawLimitConversion_ =\\n (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT) &\\n X64; // here withdrawLimitConversion_ = previous user withdraw limit\\n withdrawLimitConversion_ =\\n (withdrawLimitConversion_ >> DEFAULT_EXPONENT_SIZE) <<\\n (withdrawLimitConversion_ & DEFAULT_EXPONENT_MASK);\\n\\n // conversion of balance and limit according to the mode change\\n if (userSupplyData_ & 1 == 0 && userSupplyConfigs_[i].mode == 1) {\\n // Changing balance from interest free to with interest -> normal amounts to raw amounts\\n // -> must divide by exchange price.\\n\\n // decreasing interest free total supply\\n totalSupplyInterestFree_ = totalSupplyInterestFree_ > supplyConversion_\\n ? totalSupplyInterestFree_ - supplyConversion_\\n : 0;\\n\\n supplyConversion_ = (supplyConversion_ * EXCHANGE_PRICES_PRECISION) / supplyExchangePrice_;\\n withdrawLimitConversion_ =\\n (withdrawLimitConversion_ * EXCHANGE_PRICES_PRECISION) /\\n supplyExchangePrice_;\\n\\n // increasing raw (with interest) total supply\\n totalSupplyRawInterest_ += supplyConversion_;\\n } else if (userSupplyData_ & 1 == 1 && userSupplyConfigs_[i].mode == 0) {\\n // Changing balance from with interest to interest free-> raw amounts to normal amounts\\n // -> must multiply by exchange price.\\n\\n // decreasing raw (with interest) supply\\n totalSupplyRawInterest_ = totalSupplyRawInterest_ > supplyConversion_\\n ? totalSupplyRawInterest_ - supplyConversion_\\n : 0;\\n\\n supplyConversion_ = (supplyConversion_ * supplyExchangePrice_) / EXCHANGE_PRICES_PRECISION;\\n withdrawLimitConversion_ =\\n (withdrawLimitConversion_ * supplyExchangePrice_) /\\n EXCHANGE_PRICES_PRECISION;\\n\\n // increasing interest free total supply\\n totalSupplyInterestFree_ += supplyConversion_;\\n }\\n\\n // change new converted amounts to BigNumber for storage\\n supplyConversion_ = supplyConversion_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n );\\n withdrawLimitConversion_ = withdrawLimitConversion_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN // withdrawal limit stores the amount that must stay supplied after withdrawal\\n );\\n\\n // Updating user data on storage\\n _userSupplyData[userSupplyConfigs_[i].user][userSupplyConfigs_[i].token] =\\n // mask to set bits 0-128 and 162-217 (all except last process timestamp)\\n (userSupplyData_ & 0xfffffffffc00000000000003fffffffe00000000000000000000000000000000) |\\n (userSupplyConfigs_[i].mode) |\\n (supplyConversion_ << LiquiditySlotsLink.BITS_USER_SUPPLY_AMOUNT) | // BigNumber converted can not overflow\\n (withdrawLimitConversion_ << LiquiditySlotsLink.BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT) | // BigNumber converted can not overflow\\n (userSupplyConfigs_[i].expandPercent << LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) |\\n (userSupplyConfigs_[i].expandDuration << LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) |\\n // convert base withdrawal limit to BigNumber for storage (10 | 8). (below this, 100% can be withdrawn)\\n (userSupplyConfigs_[i].baseWithdrawalLimit.toBigNumber(\\n SMALL_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n ) << LiquiditySlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT);\\n\\n // change new total amounts to BigNumber for storage\\n totalSupplyRawInterest_ = totalSupplyRawInterest_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n );\\n totalSupplyInterestFree_ = totalSupplyInterestFree_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n );\\n\\n // Updating total supplies on storage\\n _totalAmounts[userSupplyConfigs_[i].token] =\\n // mask to set bits 0-127\\n (totalAmounts_ & 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000) |\\n (totalSupplyRawInterest_) | // BigNumber converted can not overflow\\n (totalSupplyInterestFree_ << LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE); // BigNumber converted can not overflow\\n\\n // trigger update borrow rate, utilization, ratios etc.\\n _updateExchangePricesAndRates(userSupplyConfigs_[i].token);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateUserSupplyConfigs(userSupplyConfigs_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateUserBorrowConfigs(UserBorrowConfig[] memory userBorrowConfigs_) external onlyAuths {\\n uint256 userBorrowData_;\\n uint256 totalAmounts_;\\n uint256 totalBorrowRawInterest_;\\n uint256 totalBorrowInterestFree_;\\n uint256 borrowingConversion_;\\n uint256 debtCeilingConversion_;\\n uint256 borrowExchangePrice_;\\n\\n for (uint256 i; i < userBorrowConfigs_.length; ) {\\n _checkIsContractOrNativeAddress(userBorrowConfigs_[i].user);\\n _checkIsContractOrNativeAddress(userBorrowConfigs_[i].token);\\n if (_exchangePricesAndConfig[userBorrowConfigs_[i].token] == 0) {\\n // token config must be configured before setting any user borrow config\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidConfigOrder);\\n }\\n if (\\n userBorrowConfigs_[i].mode > 1 ||\\n // max debt ceiling must not be smaller than base debt ceiling. Also covers case where max = 0 but base > 0\\n userBorrowConfigs_[i].baseDebtCeiling > userBorrowConfigs_[i].maxDebtCeiling ||\\n // can not set expand duration to 0 as that could cause a division by 0 in LiquidityCalcs.\\n // having expand duration as 0 is anyway not an expected config so removing the possibility for that.\\n // if no expansion is wanted, simply set expandDuration to 1 and expandPercent to 0.\\n userBorrowConfigs_[i].expandDuration == 0 ||\\n // sanity check that max borrow limit can never be more than 10x the total token supply.\\n // protects against that even if someone could artificially inflate token supply to a point where\\n // Fluid precision trade-offs could become problematic, can not inflate too much.\\n (userBorrowConfigs_[i].maxDebtCeiling >\\n (\\n userBorrowConfigs_[i].token == NATIVE_TOKEN_ADDRESS\\n ? NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP\\n : 10 * IERC20(userBorrowConfigs_[i].token).totalSupply()\\n ))\\n ) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\\n }\\n if (userBorrowConfigs_[i].expandPercent > X14) {\\n // expandPercent is max 14 bits\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXPAND_PERCENT_BORROW);\\n }\\n if (userBorrowConfigs_[i].expandDuration > X24) {\\n // duration is max 24 bits\\n revert FluidLiquidityError(ErrorTypes.AdminModule__ValueOverflow__EXPAND_DURATION_BORROW);\\n }\\n if (userBorrowConfigs_[i].baseDebtCeiling == 0 || userBorrowConfigs_[i].maxDebtCeiling == 0) {\\n // limits can not be 0. As a side effect, this ensures that there is no borrow config\\n // where all values would be 0, so configured users can be differentiated in the mapping.\\n revert FluidLiquidityError(ErrorTypes.AdminModule__LimitZero);\\n }\\n // @dev baseDebtCeiling & maxDebtCeiling have no max bits amount as they are in normal token amount\\n // and then converted to BigNumber\\n\\n // get current user config data from storage\\n userBorrowData_ = _userBorrowData[userBorrowConfigs_[i].user][userBorrowConfigs_[i].token];\\n\\n // if userBorrowData_ == 0 (new setup) or if mode is unchanged, normal update is possible.\\n // else if mode changes, values have to be converted from raw <> normal etc.\\n if (\\n userBorrowData_ == 0 ||\\n (userBorrowData_ & 1 == 0 && userBorrowConfigs_[i].mode == 0) ||\\n (userBorrowData_ & 1 == 1 && userBorrowConfigs_[i].mode == 1)\\n ) {\\n // Updating user data on storage\\n\\n _userBorrowData[userBorrowConfigs_[i].user][userBorrowConfigs_[i].token] =\\n // mask to update first bit (mode) + bits 162-235 (debt limit values)\\n (userBorrowData_ & 0xfffff0000000000000000003fffffffffffffffffffffffffffffffffffffffe) |\\n (userBorrowConfigs_[i].mode) |\\n (userBorrowConfigs_[i].expandPercent << LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) |\\n (userBorrowConfigs_[i].expandDuration << LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_DURATION) |\\n // convert base debt limit to BigNumber for storage (10 | 8). (borrow is always possible below this)\\n (userBorrowConfigs_[i].baseDebtCeiling.toBigNumber(\\n SMALL_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n ) << LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) |\\n // convert max debt limit to BigNumber for storage (10 | 8). (no borrowing ever possible above this)\\n (userBorrowConfigs_[i].maxDebtCeiling.toBigNumber(\\n SMALL_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n ) << LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT);\\n } else {\\n // mode changes -> values have to be converted from raw <> normal etc.\\n\\n // if the mode changes then update _exchangePricesAndConfig related data in storage always\\n // update exchange prices timely before applying changes that affect utilization, rate etc.\\n _updateExchangePrices(userBorrowConfigs_[i].token);\\n\\n // get updated exchange prices for the token\\n (, borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(\\n _exchangePricesAndConfig[userBorrowConfigs_[i].token]\\n );\\n\\n totalAmounts_ = _totalAmounts[userBorrowConfigs_[i].token];\\n totalBorrowRawInterest_ = BigMathMinified.fromBigNumber(\\n (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST) & X64,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n totalBorrowInterestFree_ = BigMathMinified.fromBigNumber(\\n // no & mask needed for borrow interest free as it occupies the last bits in the storage slot\\n (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE),\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n // read current user borrowing & borrow limit values\\n borrowingConversion_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_AMOUNT) & X64; // here borrowingConversion_ = user borrow amount\\n borrowingConversion_ =\\n (borrowingConversion_ >> DEFAULT_EXPONENT_SIZE) <<\\n (borrowingConversion_ & DEFAULT_EXPONENT_MASK);\\n\\n debtCeilingConversion_ =\\n (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT) &\\n X64; // here debtCeilingConversion_ = previous user borrow limit\\n debtCeilingConversion_ =\\n (debtCeilingConversion_ >> DEFAULT_EXPONENT_SIZE) <<\\n (debtCeilingConversion_ & DEFAULT_EXPONENT_MASK);\\n\\n // conversion of balance and limit according to the mode change\\n if (userBorrowData_ & 1 == 0 && userBorrowConfigs_[i].mode == 1) {\\n // Changing balance from interest free to with interest -> normal amounts to raw amounts\\n // -> must divide by exchange price.\\n\\n // decreasing interest free total borrow; total = total - user borrow\\n totalBorrowInterestFree_ = totalBorrowInterestFree_ > borrowingConversion_\\n ? totalBorrowInterestFree_ - borrowingConversion_\\n : 0;\\n\\n // round up for user borrow amount\\n borrowingConversion_ = FixedPointMathLib.mulDivUp(\\n borrowingConversion_,\\n EXCHANGE_PRICES_PRECISION,\\n borrowExchangePrice_\\n );\\n debtCeilingConversion_ =\\n (debtCeilingConversion_ * EXCHANGE_PRICES_PRECISION) /\\n borrowExchangePrice_;\\n\\n // increasing raw (with interest) total borrow\\n totalBorrowRawInterest_ += borrowingConversion_;\\n } else if (userBorrowData_ & 1 == 1 && userBorrowConfigs_[i].mode == 0) {\\n // Changing balance from with interest to interest free-> raw amounts to normal amounts\\n // -> must multiply by exchange price.\\n\\n // decreasing raw (with interest) borrow; total = total - user borrow raw\\n totalBorrowRawInterest_ = totalBorrowRawInterest_ > borrowingConversion_\\n ? totalBorrowRawInterest_ - borrowingConversion_\\n : 0;\\n\\n // round up for user borrow amount\\n borrowingConversion_ = FixedPointMathLib.mulDivUp(\\n borrowingConversion_,\\n borrowExchangePrice_,\\n EXCHANGE_PRICES_PRECISION\\n );\\n debtCeilingConversion_ =\\n (debtCeilingConversion_ * borrowExchangePrice_) /\\n EXCHANGE_PRICES_PRECISION;\\n\\n // increasing interest free total borrow\\n totalBorrowInterestFree_ += borrowingConversion_;\\n }\\n\\n // change new converted amounts to BigNumber for storage\\n borrowingConversion_ = borrowingConversion_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_UP\\n );\\n debtCeilingConversion_ = debtCeilingConversion_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n );\\n\\n // Updating user data on storage\\n _userBorrowData[userBorrowConfigs_[i].user][userBorrowConfigs_[i].token] =\\n // mask to update bits 0-128 and bits 162-235 (all except last process timestamp)\\n (userBorrowData_ & 0xfffff0000000000000000003fffffffe00000000000000000000000000000000) |\\n (userBorrowConfigs_[i].mode) |\\n (borrowingConversion_ << LiquiditySlotsLink.BITS_USER_BORROW_AMOUNT) | // BigNumber converted can not overflow\\n (debtCeilingConversion_ << LiquiditySlotsLink.BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT) | // BigNumber converted can not overflow\\n (userBorrowConfigs_[i].expandPercent << LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) |\\n (userBorrowConfigs_[i].expandDuration << LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_DURATION) |\\n // convert base debt limit to BigNumber for storage (10 | 8). (borrow is always possible below this)\\n (userBorrowConfigs_[i].baseDebtCeiling.toBigNumber(\\n SMALL_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n ) << LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) |\\n // convert max debt limit to BigNumber for storage (10 | 8). (no borrowing ever possible above this)\\n (userBorrowConfigs_[i].maxDebtCeiling.toBigNumber(\\n SMALL_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_DOWN\\n ) << LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT);\\n\\n // change new total amounts to BigNumber for storage\\n totalBorrowRawInterest_ = totalBorrowRawInterest_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_UP\\n );\\n totalBorrowInterestFree_ = totalBorrowInterestFree_.toBigNumber(\\n DEFAULT_COEFFICIENT_SIZE,\\n DEFAULT_EXPONENT_SIZE,\\n BigMathMinified.ROUND_UP\\n );\\n\\n // Updating total borrowings on storage\\n _totalAmounts[userBorrowConfigs_[i].token] =\\n // mask to set bits 128-255\\n (totalAmounts_ & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) |\\n (totalBorrowRawInterest_ << LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST) | // BigNumber converted can not overflow\\n (totalBorrowInterestFree_ << LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE); // BigNumber converted can not overflow\\n\\n // trigger update borrow rate, utilization, ratios etc.\\n _updateExchangePricesAndRates(userBorrowConfigs_[i].token);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit LogUpdateUserBorrowConfigs(userBorrowConfigs_);\\n }\\n}\\n\\n/// @notice Fluid Liquidity Guardians only related methods\\nabstract contract GuardianModule is AuthModule {\\n /// @dev only guardians guard\\n modifier onlyGuardians() {\\n if (_isGuardian[msg.sender] & 1 != 1 && _getGovernanceAddr() != msg.sender) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__OnlyGuardians);\\n }\\n _;\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function pauseUser(\\n address user_,\\n address[] calldata supplyTokens_,\\n address[] calldata borrowTokens_\\n ) public onlyGuardians {\\n _checkIsContractOrNativeAddress(user_);\\n if (_userClass[user_] == 1) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__UserNotPausable);\\n }\\n\\n uint256 userData_;\\n\\n // pause supply tokens\\n uint256 length_ = supplyTokens_.length;\\n\\n if (length_ > 0) {\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(supplyTokens_[i]);\\n // userData_ => userSupplyData_\\n userData_ = _userSupplyData[user_][supplyTokens_[i]];\\n if (userData_ == 0) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__UserNotDefined);\\n }\\n // set last bit of _userSupplyData (pause flag) to 1\\n _userSupplyData[user_][supplyTokens_[i]] =\\n userData_ |\\n (1 << LiquiditySlotsLink.BITS_USER_SUPPLY_IS_PAUSED);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n // pause borrow tokens\\n length_ = borrowTokens_.length;\\n\\n if (length_ > 0) {\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(borrowTokens_[i]);\\n // userData_ => userBorrowData_\\n userData_ = _userBorrowData[user_][borrowTokens_[i]];\\n if (userData_ == 0) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__UserNotDefined);\\n }\\n // set last bit of _userBorrowData (pause flag) to 1\\n _userBorrowData[user_][borrowTokens_[i]] =\\n userData_ |\\n (1 << LiquiditySlotsLink.BITS_USER_BORROW_IS_PAUSED);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n emit LogPauseUser(user_, supplyTokens_, borrowTokens_);\\n }\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function unpauseUser(\\n address user_,\\n address[] calldata supplyTokens_,\\n address[] calldata borrowTokens_\\n ) public onlyGuardians {\\n _checkIsContractOrNativeAddress(user_);\\n\\n uint256 userData_;\\n\\n // unpause supply tokens\\n uint256 length_ = supplyTokens_.length;\\n\\n if (length_ > 0) {\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(supplyTokens_[i]);\\n // userData_ => userSupplyData_\\n userData_ = _userSupplyData[user_][supplyTokens_[i]];\\n if ((userData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_IS_PAUSED) & 1 != 1) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__UserNotPaused);\\n }\\n\\n // set last bit of _userSupplyData (pause flag) to 0\\n _userSupplyData[user_][supplyTokens_[i]] =\\n userData_ &\\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n // unpause borrow tokens\\n length_ = borrowTokens_.length;\\n\\n if (length_ > 0) {\\n for (uint256 i; i < length_; ) {\\n _checkIsContractOrNativeAddress(borrowTokens_[i]);\\n // userData_ => userBorrowData_\\n userData_ = _userBorrowData[user_][borrowTokens_[i]];\\n if ((userData_ >> LiquiditySlotsLink.BITS_USER_BORROW_IS_PAUSED) & 1 != 1) {\\n revert FluidLiquidityError(ErrorTypes.AdminModule__UserNotPaused);\\n }\\n // set last bit of _userBorrowData (pause flag) to 0\\n _userBorrowData[user_][borrowTokens_[i]] =\\n userData_ &\\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n emit LogUnpauseUser(user_, supplyTokens_, borrowTokens_);\\n }\\n}\\n\\n/// @title Fluid Liquidity AdminModule\\n/// @notice Fluid Liquidity auth protected methods to configure things such as:\\n/// guardians, auths, governance, revenue, token configs, allowances etc.\\n/// Accessibility of methods is restricted to Governance, Auths or Guardians. Governance is Auth & Governance by default\\ncontract FluidLiquidityAdminModule is AdminModuleConstants, GuardianModule {\\n constructor(uint256 nativeTokenMaxBorrowLimitCap_) AdminModuleConstants(nativeTokenMaxBorrowLimitCap_) {}\\n\\n /// @inheritdoc IFluidLiquidityAdmin\\n function updateExchangePrices(\\n address[] calldata tokens_\\n ) external returns (uint256[] memory supplyExchangePrices_, uint256[] memory borrowExchangePrices_) {\\n uint256 tokensLength_ = tokens_.length;\\n\\n supplyExchangePrices_ = new uint256[](tokensLength_);\\n borrowExchangePrices_ = new uint256[](tokensLength_);\\n\\n for (uint256 i; i < tokensLength_; ) {\\n _checkIsContractOrNativeAddress(tokens_[i]);\\n (supplyExchangePrices_[i], borrowExchangePrices_[i]) = _updateExchangePricesAndRates(tokens_[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5e247c87971413bdeb132167abf03a1ef661aad5eeb30d5bc36c7f510aeb4096\",\"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/common/helpers.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { Variables } from \\\"./variables.sol\\\";\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\nimport { Error } from \\\"../error.sol\\\";\\n\\n/// @dev ReentrancyGuard based on OpenZeppelin implementation.\\n/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.8/contracts/security/ReentrancyGuard.sol\\nabstract contract ReentrancyGuard is Variables, Error {\\n uint8 internal constant REENTRANCY_NOT_ENTERED = 1;\\n uint8 internal constant REENTRANCY_ENTERED = 2;\\n\\n constructor() {\\n // on logic contracts, switch reentrancy to entered so no call is possible (forces delegatecall)\\n _status = REENTRANCY_ENTERED; \\n }\\n\\n /// @dev Prevents a contract from calling itself, directly or indirectly.\\n /// See OpenZeppelin implementation for more info\\n modifier reentrancy() {\\n // On the first call to nonReentrant, _status will be NOT_ENTERED\\n if (_status == REENTRANCY_ENTERED) {\\n revert FluidLiquidityError(ErrorTypes.LiquidityHelpers__Reentrancy);\\n }\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = REENTRANCY_ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = REENTRANCY_NOT_ENTERED;\\n }\\n}\\n\\nabstract contract CommonHelpers is ReentrancyGuard {\\n /// @dev Returns the current admin (governance).\\n function _getGovernanceAddr() internal view returns (address governance_) {\\n assembly {\\n governance_ := sload(GOVERNANCE_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0818447e79488c3da0fde292ae7219cf2a819951ad5d4456fb297082e5e83a9b\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/common/variables.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract ConstantVariables {\\n /// @dev Storage slot with the admin of the contract. Logic from \\\"proxy.sol\\\".\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\\n bytes32 internal constant GOVERNANCE_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\\n\\n /// @dev address that is mapped to the chain native token\\n address internal constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n /// @dev limit for triggering a revert if sent along excess `msg.value` is bigger than this amount\\n uint256 internal constant NATIVE_AMOUNT_EXCESS_LIMIT = 1e9;\\n /// @dev decimals for native token\\n // !! Double check compatibility with all code if this ever changes for a deployment !!\\n uint8 internal constant NATIVE_TOKEN_DECIMALS = 18;\\n\\n /// @dev Minimum token decimals for any token that can be listed at Liquidity (inclusive)\\n uint8 internal constant MIN_TOKEN_DECIMALS = 6;\\n /// @dev Maximum token decimals for any token that can be listed at Liquidity (inclusive)\\n uint8 internal constant MAX_TOKEN_DECIMALS = 18;\\n\\n /// @dev Ignoring leap years\\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\\n\\n /// @dev limit any total amount to be half of type(uint128).max (~3.4e38) at type(int128).max (~1.7e38) as safety\\n /// measure for any potential overflows / unexpected outcomes. This is checked for total borrow / supply.\\n uint256 internal constant MAX_TOKEN_AMOUNT_CAP = uint256(uint128(type(int128).max));\\n\\n /// @dev time after which a write to storage of exchangePricesAndConfig will happen always.\\n uint256 internal constant FORCE_STORAGE_WRITE_AFTER_TIME = 1 days;\\n\\n /// @dev constants used for BigMath conversion from and to storage\\n uint256 internal constant SMALL_COEFFICIENT_SIZE = 10;\\n uint256 internal constant DEFAULT_COEFFICIENT_SIZE = 56;\\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\\n\\n /// @dev constants to increase readability for using bit masks\\n uint256 internal constant FOUR_DECIMALS = 1e4;\\n uint256 internal constant TWELVE_DECIMALS = 1e12;\\n uint256 internal constant X8 = 0xff;\\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\\ncontract Variables is ConstantVariables {\\n /// @dev address of contract that gets sent the revenue. Configurable by governance\\n address internal _revenueCollector;\\n\\n // 12 bytes empty\\n\\n // ----- storage slot 1 ------\\n\\n /// @dev paused status: status = 1 -> normal. status = 2 -> paused.\\n /// not tightly packed with revenueCollector address to allow for potential changes later that improve gas more\\n /// (revenueCollector is only rarely used by admin methods, where optimization is not as important).\\n /// to be replaced with transient storage once EIP-1153 Transient storage becomes available with dencun upgrade.\\n uint256 internal _status;\\n\\n // ----- storage slot 2 ------\\n\\n /// @dev 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.\\n /// Governance is auth by default\\n mapping(address => uint256) internal _isAuth;\\n\\n // ----- storage slot 3 ------\\n\\n /// @dev Guardians can pause lower class users\\n /// Governance can add/remove guardians\\n /// Governance is guardian by default\\n mapping(address => uint256) internal _isGuardian;\\n\\n // ----- storage slot 4 ------\\n\\n /// @dev 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 mapping(address => uint256) internal _userClass;\\n\\n // ----- storage slot 5 ------\\n\\n /// @dev exchange prices and token config per token: token -> exchange prices & config\\n /// First 16 bits => 0- 15 => borrow rate (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 14 bits => 16- 29 => fee on interest from borrowers to lenders (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383). configurable.\\n /// Next 14 bits => 30- 43 => last stored utilization (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\\n /// Next 14 bits => 44- 57 => update on storage threshold (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383). configurable.\\n /// Next 33 bits => 58- 90 => last update timestamp (enough until 16 March 2242 -> max value 8589934591)\\n /// Next 64 bits => 91-154 => supply exchange price (1e12 -> max value 18_446_744,073709551615)\\n /// Next 64 bits => 155-218 => borrow exchange price (1e12 -> max value 18_446_744,073709551615)\\n /// Next 1 bit => 219-219 => if 0 then ratio is supplyInterestFree / supplyWithInterest else ratio is supplyWithInterest / supplyInterestFree\\n /// Next 14 bits => 220-233 => supplyRatio: supplyInterestFree / supplyWithInterest (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\\n /// Next 1 bit => 234-234 => if 0 then ratio is borrowInterestFree / borrowWithInterest else ratio is borrowWithInterest / borrowInterestFree\\n /// Next 14 bits => 235-248 => borrowRatio: borrowInterestFree / borrowWithInterest (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\\n /// Next 1 bit => 249-249 => flag for token uses config storage slot 2. (signals SLOAD for additional config slot is needed during execution)\\n /// Last 6 bits => 250-255 => empty for future use\\n /// if more free bits are needed in the future, update on storage threshold bits could be reduced to 7 bits\\n /// (can plan to add `MAX_TOKEN_CONFIG_UPDATE_THRESHOLD` but need to adjust more bits)\\n /// if more bits absolutely needed then we can convert fee, utilization, update on storage threshold,\\n /// supplyRatio & borrowRatio from 14 bits to 10bits (1023 max number) where 1000 = 100% & 1 = 0.1%\\n mapping(address => uint256) internal _exchangePricesAndConfig;\\n\\n // ----- storage slot 6 ------\\n\\n /// @dev Rate related data per token: token -> rate data\\n /// READ (SLOAD): all actions; WRITE (SSTORE): only on set config admin actions\\n /// token => rate related data\\n /// First 4 bits => 0-3 => rate version\\n /// rest of the bits are rate dependent:\\n\\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 => empty for future use\\n\\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 => empty for future use\\n mapping(address => uint256) internal _rateData;\\n\\n // ----- storage slot 7 ------\\n\\n /// @dev total supply / borrow amounts for with / without interest per token: token -> amounts\\n /// First 64 bits => 0- 63 => total supply with interest in raw (totalSupply = totalSupplyRaw * supplyExchangePrice); BigMath: 56 | 8\\n /// Next 64 bits => 64-127 => total interest free supply in normal token amount (totalSupply = totalSupply); BigMath: 56 | 8\\n /// Next 64 bits => 128-191 => total borrow with interest in raw (totalBorrow = totalBorrowRaw * borrowExchangePrice); BigMath: 56 | 8\\n /// Next 64 bits => 192-255 => total interest free borrow in normal token amount (totalBorrow = totalBorrow); BigMath: 56 | 8\\n mapping(address => uint256) internal _totalAmounts;\\n\\n // ----- storage slot 8 ------\\n\\n /// @dev user supply data per token: user -> token -> data\\n /// First 1 bit => 0 => mode: user supply with or without interest\\n /// 0 = without, amounts are in normal (i.e. no need to multiply with exchange price)\\n /// 1 = with interest, amounts are in raw (i.e. must multiply with exchange price to get actual token amounts)\\n /// Next 64 bits => 1- 64 => user supply amount (normal or raw depends on 1st bit); BigMath: 56 | 8\\n /// Next 64 bits => 65-128 => previous user withdrawal limit (normal or raw depends on 1st bit); BigMath: 56 | 8\\n /// Next 33 bits => 129-161 => last triggered process timestamp (enough until 16 March 2242 -> max value 8589934591)\\n /// Next 14 bits => 162-175 => expand withdrawal limit percentage (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383).\\n /// @dev shrinking is instant\\n /// Next 24 bits => 176-199 => withdrawal limit expand duration in seconds.(Max value 16_777_215; ~4_660 hours, ~194 days)\\n /// Next 18 bits => 200-217 => base withdrawal limit: below this, 100% withdrawals can be done (normal or raw depends on 1st bit); BigMath: 10 | 8\\n /// Next 37 bits => 218-254 => empty for future use\\n /// Last bit => 255-255 => is user paused (1 = paused, 0 = not paused)\\n mapping(address => mapping(address => uint256)) internal _userSupplyData;\\n\\n // ----- storage slot 9 ------\\n\\n /// @dev user borrow data per token: user -> token -> data\\n /// First 1 bit => 0 => mode: user borrow with or without interest\\n /// 0 = without, amounts are in normal (i.e. no need to multiply with exchange price)\\n /// 1 = with interest, amounts are in raw (i.e. must multiply with exchange price to get actual token amounts)\\n /// Next 64 bits => 1- 64 => user borrow amount (normal or raw depends on 1st bit); BigMath: 56 | 8\\n /// Next 64 bits => 65-128 => previous user debt ceiling (normal or raw depends on 1st bit); BigMath: 56 | 8\\n /// Next 33 bits => 129-161 => last triggered process timestamp (enough until 16 March 2242 -> max value 8589934591)\\n /// Next 14 bits => 162-175 => expand debt ceiling percentage (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\\n /// @dev shrinking is instant\\n /// Next 24 bits => 176-199 => debt ceiling expand duration in seconds (Max value 16_777_215; ~4_660 hours, ~194 days)\\n /// Next 18 bits => 200-217 => base debt ceiling: below this, there's no debt ceiling limits (normal or raw depends on 1st bit); BigMath: 10 | 8\\n /// Next 18 bits => 218-235 => max debt ceiling: absolute maximum debt ceiling can expand to (normal or raw depends on 1st bit); BigMath: 10 | 8\\n /// Next 19 bits => 236-254 => empty for future use\\n /// Last bit => 255-255 => is user paused (1 = paused, 0 = not paused)\\n mapping(address => mapping(address => uint256)) internal _userBorrowData;\\n\\n // ----- storage slot 10 ------\\n\\n /// @dev list of allowed tokens at Liquidity. tokens that are once configured can never be completely removed. so this\\n /// array is append-only.\\n address[] internal _listedTokens;\\n\\n // ----- storage slot 11 ------\\n\\n /// @dev expanded token configs per token: token -> config data slot 2.\\n /// Use of this is signaled by `_exchangePricesAndConfig` bit 249.\\n /// First 14 bits => 0- 13 => max allowed utilization (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383). configurable.\\n /// Last 242 bits => 14-255 => empty for future use\\n mapping(address => uint256) internal _configs2;\\n}\\n\",\"keccak256\":\"0x0fdae459355d882ccb2b9b350d0abe17604078a8df887e5d7c774f69e83529dd\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/error.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Error {\\n error FluidLiquidityError(uint256 errorId_);\\n}\\n\",\"keccak256\":\"0x6013ceb756cb1301b2a5ebac8aa0dfc39dc610012670462a70c13d99a2708302\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary ErrorTypes {\\n /***********************************|\\n | Admin Module | \\n |__________________________________*/\\n\\n /// @notice thrown when an input address is zero\\n uint256 internal constant AdminModule__AddressZero = 10001;\\n\\n /// @notice thrown when msg.sender is not governance\\n uint256 internal constant AdminModule__OnlyGovernance = 10002;\\n\\n /// @notice thrown when msg.sender is not auth\\n uint256 internal constant AdminModule__OnlyAuths = 10003;\\n\\n /// @notice thrown when msg.sender is not guardian\\n uint256 internal constant AdminModule__OnlyGuardians = 10004;\\n\\n /// @notice thrown when base withdrawal limit, base debt limit or max withdrawal limit is sent as 0\\n uint256 internal constant AdminModule__LimitZero = 10005;\\n\\n /// @notice thrown whenever an invalid input param is given\\n uint256 internal constant AdminModule__InvalidParams = 10006;\\n\\n /// @notice thrown if user class 1 is paused (can not be paused)\\n uint256 internal constant AdminModule__UserNotPausable = 10007;\\n\\n /// @notice thrown if user is tried to be unpaused but is not paused in the first place\\n uint256 internal constant AdminModule__UserNotPaused = 10008;\\n\\n /// @notice thrown if user is not defined yet: Governance didn't yet set any config for this user on a particular token\\n uint256 internal constant AdminModule__UserNotDefined = 10009;\\n\\n /// @notice thrown if a token is configured in an invalid order: 1. Set rate config for token 2. Set token config 3. allow any user.\\n uint256 internal constant AdminModule__InvalidConfigOrder = 10010;\\n\\n /// @notice thrown if revenue is collected when revenue collector address is not set\\n uint256 internal constant AdminModule__RevenueCollectorNotSet = 10011;\\n\\n /// @notice all ValueOverflow errors below are thrown if a certain input param overflows the allowed storage size\\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_ZERO = 10012;\\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_KINK = 10013;\\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_MAX = 10014;\\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_KINK1 = 10015;\\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_KINK2 = 10016;\\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_MAX_V2 = 10017;\\n uint256 internal constant AdminModule__ValueOverflow__FEE = 10018;\\n uint256 internal constant AdminModule__ValueOverflow__THRESHOLD = 10019;\\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_PERCENT = 10020;\\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_DURATION = 10021;\\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_PERCENT_BORROW = 10022;\\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_DURATION_BORROW = 10023;\\n uint256 internal constant AdminModule__ValueOverflow__EXCHANGE_PRICES = 10024;\\n uint256 internal constant AdminModule__ValueOverflow__UTILIZATION = 10025;\\n\\n /// @notice thrown when an address is not a contract\\n uint256 internal constant AdminModule__AddressNotAContract = 10026;\\n\\n uint256 internal constant AdminModule__ValueOverflow__MAX_UTILIZATION = 10027;\\n\\n /// @notice thrown if a token that is being listed has not between 6 and 18 decimals\\n uint256 internal constant AdminModule__TokenInvalidDecimalsRange = 10028;\\n\\n /***********************************|\\n | User Module | \\n |__________________________________*/\\n\\n /// @notice thrown when user operations are paused for an interacted token\\n uint256 internal constant UserModule__UserNotDefined = 11001;\\n\\n /// @notice thrown when user operations are paused for an interacted token\\n uint256 internal constant UserModule__UserPaused = 11002;\\n\\n /// @notice thrown when user's try to withdraw below withdrawal limit\\n uint256 internal constant UserModule__WithdrawalLimitReached = 11003;\\n\\n /// @notice thrown when user's try to borrow above borrow limit\\n uint256 internal constant UserModule__BorrowLimitReached = 11004;\\n\\n /// @notice thrown when user sent supply/withdraw and borrow/payback both as 0\\n uint256 internal constant UserModule__OperateAmountsZero = 11005;\\n\\n /// @notice thrown when user sent supply/withdraw or borrow/payback both as bigger than 2**128\\n uint256 internal constant UserModule__OperateAmountOutOfBounds = 11006;\\n\\n /// @notice thrown when the operate amount for supply / withdraw / borrow / payback is below the minimum amount\\n /// that would cause a storage difference after BigMath & rounding imprecision. Extremely unlikely to ever happen\\n /// for all normal use-cases.\\n uint256 internal constant UserModule__OperateAmountInsufficient = 11007;\\n\\n /// @notice thrown when withdraw or borrow is executed but withdrawTo or borrowTo is the zero address\\n uint256 internal constant UserModule__ReceiverNotDefined = 11008;\\n\\n /// @notice thrown when user did send excess or insufficient amount (beyond rounding issues)\\n uint256 internal constant UserModule__TransferAmountOutOfBounds = 11009;\\n\\n /// @notice thrown when user sent msg.value along for an operation not for the native token\\n uint256 internal constant UserModule__MsgValueForNonNativeToken = 11010;\\n\\n /// @notice thrown when a borrow operation is done when utilization is above 100%\\n uint256 internal constant UserModule__MaxUtilizationReached = 11011;\\n\\n /// @notice all ValueOverflow errors below are thrown if a certain input param or calc result overflows the allowed storage size\\n uint256 internal constant UserModule__ValueOverflow__EXCHANGE_PRICES = 11012;\\n uint256 internal constant UserModule__ValueOverflow__UTILIZATION = 11013;\\n uint256 internal constant UserModule__ValueOverflow__TOTAL_SUPPLY = 11014;\\n uint256 internal constant UserModule__ValueOverflow__TOTAL_BORROW = 11015;\\n\\n /***********************************|\\n | LiquidityHelpers | \\n |__________________________________*/\\n\\n /// @notice thrown when a reentrancy happens\\n uint256 internal constant LiquidityHelpers__Reentrancy = 12001;\\n}\\n\",\"keccak256\":\"0x915417f764bf86c48a3d1623bce934a9c859e6f302e42818a30d91ca107e931f\",\"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\"},\"solmate/src/utils/FixedPointMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Arithmetic library with operations for fixed-point numbers.\\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\\n/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\\nlibrary FixedPointMathLib {\\n /*//////////////////////////////////////////////////////////////\\n SIMPLIFIED FIXED POINT OPERATIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal constant MAX_UINT256 = 2**256 - 1;\\n\\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\\n\\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\\n }\\n\\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\\n }\\n\\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\\n }\\n\\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n LOW LEVEL FIXED POINT OPERATIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function mulDivDown(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 z) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\\n if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\\n revert(0, 0)\\n }\\n\\n // Divide x * y by the denominator.\\n z := div(mul(x, y), denominator)\\n }\\n }\\n\\n function mulDivUp(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 z) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\\n if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\\n revert(0, 0)\\n }\\n\\n // If x * y modulo the denominator is strictly greater than 0,\\n // 1 is added to round up the division of x * y by the denominator.\\n z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))\\n }\\n }\\n\\n function rpow(\\n uint256 x,\\n uint256 n,\\n uint256 scalar\\n ) internal pure returns (uint256 z) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n switch x\\n case 0 {\\n switch n\\n case 0 {\\n // 0 ** 0 = 1\\n z := scalar\\n }\\n default {\\n // 0 ** n = 0\\n z := 0\\n }\\n }\\n default {\\n switch mod(n, 2)\\n case 0 {\\n // If n is even, store scalar in z for now.\\n z := scalar\\n }\\n default {\\n // If n is odd, store x in z for now.\\n z := x\\n }\\n\\n // Shifting right by 1 is like dividing by 2.\\n let half := shr(1, scalar)\\n\\n for {\\n // Shift n right by 1 before looping to halve it.\\n n := shr(1, n)\\n } n {\\n // Shift n right by 1 each iteration to halve it.\\n n := shr(1, n)\\n } {\\n // Revert immediately if x ** 2 would overflow.\\n // Equivalent to iszero(eq(div(xx, x), x)) here.\\n if shr(128, x) {\\n revert(0, 0)\\n }\\n\\n // Store x squared.\\n let xx := mul(x, x)\\n\\n // Round to the nearest number.\\n let xxRound := add(xx, half)\\n\\n // Revert if xx + half overflowed.\\n if lt(xxRound, xx) {\\n revert(0, 0)\\n }\\n\\n // Set x to scaled xxRound.\\n x := div(xxRound, scalar)\\n\\n // If n is even:\\n if mod(n, 2) {\\n // Compute z * x.\\n let zx := mul(z, x)\\n\\n // If z * x overflowed:\\n if iszero(eq(div(zx, x), z)) {\\n // Revert if x is non-zero.\\n if iszero(iszero(x)) {\\n revert(0, 0)\\n }\\n }\\n\\n // Round to the nearest number.\\n let zxRound := add(zx, half)\\n\\n // Revert if zx + half overflowed.\\n if lt(zxRound, zx) {\\n revert(0, 0)\\n }\\n\\n // Return properly scaled zxRound.\\n z := div(zxRound, scalar)\\n }\\n }\\n }\\n }\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n GENERAL NUMBER UTILITIES\\n //////////////////////////////////////////////////////////////*/\\n\\n function sqrt(uint256 x) internal pure returns (uint256 z) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let y := x // We start y at x, which will help us make our initial estimate.\\n\\n z := 181 // The \\\"correct\\\" value is 1, but this saves a multiplication later.\\n\\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\\n\\n // We check y >= 2^(k + 8) but shift right by k bits\\n // each branch to ensure that if x >= 256, then y >= 256.\\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\\n y := shr(128, y)\\n z := shl(64, z)\\n }\\n if iszero(lt(y, 0x1000000000000000000)) {\\n y := shr(64, y)\\n z := shl(32, z)\\n }\\n if iszero(lt(y, 0x10000000000)) {\\n y := shr(32, y)\\n z := shl(16, z)\\n }\\n if iszero(lt(y, 0x1000000)) {\\n y := shr(16, y)\\n z := shl(8, z)\\n }\\n\\n // Goal was to get z*z*y within a small factor of x. More iterations could\\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\\n\\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\\n\\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\\n\\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\\n\\n // There is no overflow risk here since y < 2^136 after the first branch above.\\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\\n\\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n\\n // If x+1 is a perfect square, the Babylonian method cycles between\\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\\n z := sub(z, lt(div(x, z), z))\\n }\\n }\\n\\n function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Mod x by y. Note this will return\\n // 0 instead of reverting if y is zero.\\n z := mod(x, y)\\n }\\n }\\n\\n function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Divide x by y. Note this will return\\n // 0 instead of reverting if y is zero.\\n r := div(x, y)\\n }\\n }\\n\\n function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Add 1 to x * y if x % y > 0. Note this will\\n // return 0 instead of reverting if y is zero.\\n z := add(gt(mod(x, y), 0), div(x, y))\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1b62af9baf5b8e991ed7531bc87f45550ba9d61e8dbff5caf237ccaf3a3fd843\",\"license\":\"AGPL-3.0-only\"}},\"version\":1}",
"bytecode": "0x60a06040523480156200001157600080fd5b5060405162005cc938038062005cc983398101604081905262000034916200006f565b60026001558060008190036200006557604051636e55c17160e11b8152612716600482015260240160405180910390fd5b6080525062000089565b6000602082840312156200008257600080fd5b5051919050565b608051615c1d620000ac600039600081816101e501526105820152615c1d6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063a5eb43ef11610097578063e8025d7711610066578063e8025d77146101cd578063eae2c8f1146101e0578063ec0484011461021a578063f4bfa0001461022d57600080fd5b8063a5eb43ef14610181578063ac862bfa14610194578063c2da75f0146101a7578063dd4cbf6b146101ba57600080fd5b80633fad77fc116100d35780633fad77fc1461013557806354bb0c1d146101485780637f7b60021461015b5780639dde59771461016e57600080fd5b806301b88f86146100fa57806302c6bb6a1461010f5780633f66feff14610122575b600080fd5b61010d610108366004614faf565b61024e565b005b61010d61011d3660046150b1565b610f5f565b61010d6101303660046151e4565b6119e1565b61010d610143366004615226565b611b6c565b61010d61015636600461529b565b611e06565b61010d6101693660046152bd565b611ef6565b61010d61017c366004615320565b612573565b61010d61018f3660046151e4565b6127eb565b61010d6101a23660046153c8565b61294e565b61010d6101b53660046151e4565b612d2b565b61010d6101c83660046153fe565b612f00565b61010d6101db36600461547f565b613372565b6102077f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61010d6102283660046153fe565b613488565b61024061023b3660046153c8565b613866565b6040516102119291906154d3565b336000908152600260205260409020546001908116148015906102ae5750336102957fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b156102ee576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024015b60405180910390fd5b6000806000806000806000805b8851811015610f1d5761032a89828151811061031957610319615501565b602002602001015160000151613989565b61035089828151811061033f5761033f615501565b602002602001015160200151613989565b600560008a838151811061036657610366615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546000036103ea576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271a60048201526024016102e5565b60018982815181106103fe576103fe615501565b60200260200101516040015160ff161180610452575088818151811061042657610426615501565b602002602001015160c0015189828151811061044457610444615501565b602002602001015160a00151115b8061047a575088818151811061046a5761046a615501565b6020026020010151608001516000145b806105c2575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168982815181106104bd576104bd615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1614610580578881815181106104f6576104f6615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561054c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105709190615530565b61057b90600a615578565b6105a2565b7f00000000000000000000000000000000000000000000000000000000000000005b8982815181106105b4576105b4615501565b602002602001015160c00151115b156105fd576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b613fff89828151811061061257610612615501565b602002602001015160600151111561065a576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272660048201526024016102e5565b62ffffff89828151811061067057610670615501565b60200260200101516080015111156106b8576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272760048201526024016102e5565b8881815181106106ca576106ca615501565b602002602001015160a001516000148061070157508881815181106106f1576106f1615501565b602002602001015160c001516000145b1561073c576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271560048201526024016102e5565b600960008a838151811061075257610752615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a83815181106107ac576107ac615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205497508760001480610830575060018816158015610830575088818151811061081d5761081d615501565b60200260200101516040015160ff166000145b806108695750876001166001148015610869575088818151811061085657610856615501565b60200260200101516040015160ff166001145b15610a305760da6108a7600a600860008d868151811061088b5761088b615501565b602002602001015160c00151613a16909392919063ffffffff16565b901b60c86108e2600a600860008e87815181106108c6576108c6615501565b602002602001015160a00151613a16909392919063ffffffff16565b901b60b08b84815181106108f8576108f8615501565b602002602001015160800151901b60a28c858151811061091a5761091a615501565b602002602001015160600151901b8c858151811061093a5761093a615501565b60200260200101516040015160ff168c7ffffff0000000000000000003fffffffffffffffffffffffffffffffffffffffe161717171717600960008b848151811061098757610987615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b84815181106109e1576109e1615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f15565b610a56898281518110610a4557610a45615501565b602002602001015160200151613b3f565b5050610abd600560008b8481518110610a7157610a71615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613c81565b905080925050600760008a8381518110610ad957610ad9615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549650610b4267ffffffffffffffff608089901c16600860ff9082901c91161b90565b955060c887901c60ff60c089901c161b945067ffffffffffffffff600189901c16935060ff8416600885901c901b935067ffffffffffffffff604189901c16925060ff8316600884901c901b9250876001166000148015610bc35750888181518110610bb057610bb0615501565b60200260200101516040015160ff166001145b15610c2157838511610bd6576000610be0565b610be08486615595565b9450610bf28464e8d4a5100084613e8f565b935081610c0464e8d4a5100085615578565b610c0e91906155d7565b9250610c1a8487615612565b9550610cae565b876001166001148015610c545750888181518110610c4157610c41615501565b60200260200101516040015160ff166000145b15610cae57838611610c67576000610c71565b610c718487615595565b9550610c83848364e8d4a51000613e8f565b935064e8d4a51000610c958385615578565b610c9f91906155d7565b9250610cab8486615612565b94505b610cbd84603860086001613a16565b9350610cce83603860086000613a16565b925060da610ced600a600860008d868151811061088b5761088b615501565b901b60c8610d0c600a600860008e87815181106108c6576108c6615501565b901b60b08b8481518110610d2257610d22615501565b602002602001015160800151901b60a28c8581518110610d4457610d44615501565b602002602001015160600151901b604187901b600189901b8e8781518110610d6e57610d6e615501565b60200260200101516040015160ff168e7ffffff0000000000000000003fffffffe000000000000000000000000000000001617171717171717600960008b8481518110610dbd57610dbd615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b8481518110610e1757610e17615501565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002055610e5a86603860086001613a16565b9550610e6b85603860086001613a16565b945060c085901b608087901b886fffffffffffffffffffffffffffffffff161717600760008b8481518110610ea257610ea2615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f12898281518110610f0157610f01615501565b602002602001015160200151613ed3565b50505b6001016102fb565b507f4a3d512075def8d38b63e79dacfdab217654f641be2b2f7d638b67b2515df7c088604051610f4d9190615625565b60405180910390a15050505050505050565b33600090815260026020526040902054600190811614801590610fbf575033610fa67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610ffa576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b6000806000806000806000805b88518110156119b15761102589828151811061031957610319615501565b61103a89828151811061033f5761033f615501565b600560008a838151811061105057611050615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546000036110d4576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271a60048201526024016102e5565b60018982815181106110e8576110e8615501565b60200260200101516040015160ff161180611120575088818151811061111057611110615501565b6020026020010151608001516000145b1561115b576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b61271089828151811061117057611170615501565b60200260200101516060015111156111b8576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272460048201526024016102e5565b62ffffff8982815181106111ce576111ce615501565b6020026020010151608001511115611216576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272560048201526024016102e5565b88818151811061122857611228615501565b602002602001015160a00151600003611271576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271560048201526024016102e5565b600860008a838151811061128757611287615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a83815181106112e1576112e1615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205497508760001480611365575060018816158015611365575088818151811061135257611352615501565b60200260200101516040015160ff166000145b8061139e575087600116600114801561139e575088818151811061138b5761138b615501565b60200260200101516040015160ff166001145b1561150d5760c86113c0600a600860008d86815181106108c6576108c6615501565b901b60b08a83815181106113d6576113d6615501565b602002602001015160800151901b60a28b84815181106113f8576113f8615501565b602002602001015160600151901b8b848151811061141857611418615501565b60200260200101516040015160ff168b7ffffffffffc00000000000003fffffffffffffffffffffffffffffffffffffffe1617171717600860008b848151811061146457611464615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b84815181106114be576114be615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506119a9565b611522898281518110610a4557610a45615501565b505061153d600560008b8481518110610a7157610a71615501565b5080925050600760008a838151811061155857611558615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205496506115bd67ffffffffffffffff8816600860ff9082901c91161b90565b955066ffffffffffffff604888901c1660ff604089901c161b945067ffffffffffffffff600189901c16935060ff8416600885901c901b935067ffffffffffffffff604189901c16925060ff8316600884901c901b9250876001166000148015611647575088818151811061163457611634615501565b60200260200101516040015160ff166001145b156116af5783851161165a576000611664565b6116648486615595565b94508161167664e8d4a5100086615578565b61168091906155d7565b93508161169264e8d4a5100085615578565b61169c91906155d7565b92506116a88487615612565b9550611746565b8760011660011480156116e257508881815181106116cf576116cf615501565b60200260200101516040015160ff166000145b15611746578386116116f55760006116ff565b6116ff8487615595565b955064e8d4a510006117118386615578565b61171b91906155d7565b935064e8d4a5100061172d8385615578565b61173791906155d7565b92506117438486615612565b94505b61175584603860086000613a16565b935061176683603860086000613a16565b925060c8611785600a600860008d86815181106108c6576108c6615501565b901b60b08a838151811061179b5761179b615501565b602002602001015160800151901b60a28b84815181106117bd576117bd615501565b602002602001015160600151901b604186901b600188901b8d86815181106117e7576117e7615501565b60200260200101516040015160ff168d7ffffffffffc00000000000003fffffffe0000000000000000000000000000000016171717171717600860008b848151811061183557611835615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b848151811061188f5761188f615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506118f360386008600089613a16909392919063ffffffff16565b955061190485603860086000613a16565b9450604085901b86887fffffffffffffffffffffffffffffffff00000000000000000000000000000000161717600760008b848151811061194757611947615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506119a6898281518110610f0157610f01615501565b50505b600101611007565b507f614e3525ec8c152da9319cd9038950346a4a042d3c6810a7f3ffddc34347bdb088604051610f4d91906156c3565b33611a0a7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614611a5b576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271260048201526024016102e5565b8060005b81811015611b2d57611a97848483818110611a7c57611a7c615501565b611a92926020604090920201908101915061529b565b614267565b838382818110611aa957611aa9615501565b9050604002016020016020810190611ac19190615758565b611acc576000611acf565b60015b60ff1660026000868685818110611ae857611ae8615501565b611afe926020604090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101611a5f565b507fb694cde8b4bf47e7f5845bb4374f98c5b29bbbaa5208ea679121cecb5d8fd3e08383604051611b5f929190615775565b60405180910390a1505050565b33600090815260026020526040902054600190811614801590611bcc575033611bb37fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611c07576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b806000805b82811015611dc657611c44858583818110611c2957611c29615501565b611c3f92602060a090920201908101915061529b565b613989565b611c74858583818110611c5957611c59615501565b611c6f92602060a090920201908101915061529b565b6142b8565b60066000868684818110611c8a57611c8a615501565b611ca092602060a090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205491508115611d0257611cff858583818110611ce457611ce4615501565b611cfa92602060a090920201908101915061529b565b613b3f565b50505b611d32858583818110611d1757611d17615501565b905060a00201803603810190611d2d91906157e4565b6143b8565b60066000878785818110611d4857611d48615501565b611d5e92602060a090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020558115611dbe57611dbb858583818110611da057611da0615501565b611db692602060a090920201908101915061529b565b613ed3565b50505b600101611c0c565b507f1f953465aa7f3f2478d38b6c2a9cfcfbda846398254e278f614d586d527d902c8484604051611df8929190615859565b60405180910390a150505050565b33611e2f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614611e80576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271260048201526024016102e5565b611e8981614267565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917fde3dd47a9a762713b4a9813a037ab6f57e36569d8b0ec4ddb285d8a61878b5b491a250565b33600090815260026020526040902054600190811614801590611f56575033611f3d7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611f91576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b8060008080805b8481101561253157611fcb878783818110611fb557611fb5615501565b611c3f926020608090920201908101915061529b565b60066000888884818110611fe157611fe1615501565b611ff7926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460000361206f576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271a60048201526024016102e5565b61271087878381811061208457612084615501565b9050608002016020013511156120ca576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272260048201526024016102e5565b6127108787838181106120df576120df615501565b905060800201606001351115612125576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272b60048201526024016102e5565b6101f487878381811061213a5761213a615501565b905060800201604001351115612180576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272360048201526024016102e5565b6005600088888481811061219657612196615501565b6121ac926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054935067ffffffffffffffff605b85901c16925067ffffffffffffffff609b85901c16915060008311801561221b5750600082115b1561228b5761222984613c81565b909350915067ffffffffffffffff83118061224b575067ffffffffffffffff82115b15612286576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272860048201526024016102e5565b61231d565b64e8d4a51000925064e8d4a510009150600a8787838181106122af576122af615501565b6122c5926020608090920201908101915061529b565b81546001810183556000928352602090922090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790555b600061271088888481811061233457612334615501565b905060800201606001351415905060f981612350576000612353565b60015b60ff16901b609b84901b605b86901b42603a1b602c8c8c8881811061237a5761237a615501565b90506080020160400135901b60108d8d8981811061239a5761239a615501565b90506080020160200135901b8a7ffdfffffff80000000000000000000000000000000000000000000fffc000ffff16171717171717600560008a8a868181106123e5576123e5615501565b6123fb926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020558061242e57600061244b565b87878381811061244057612440615501565b905060800201606001355b600b60008a8a8681811061246157612461615501565b612477926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0001617600b60008a8a868181106124eb576124eb615501565b612501926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205550600101611f98565b507fa9d5be7e168dc43b637b924e6cc22c262478dffd9d475fa170b6d4e4ba57646086866040516125639291906158ce565b60405180910390a1505050505050565b336000908152600260205260409020546001908116148015906125d35750336125ba7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b1561260e576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b806000805b828110156127b95761264685858381811061263057612630615501565b611c3f92602060e090920201908101915061529b565b61267185858381811061265b5761265b615501565b611c6f92602060e090920201908101915061529b565b6006600086868481811061268757612687615501565b61269d92602060e090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054915081156126fa576126f78585838181106126e1576126e1615501565b611cfa92602060e090920201908101915061529b565b50505b61272a85858381811061270f5761270f615501565b905060e002018036038101906127259190615939565b61451b565b6006600087878581811061274057612740615501565b61275692602060e090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205581156127b1576127ae85858381811061279857612798615501565b611db692602060e090920201908101915061529b565b50505b600101612613565b507ff96f9120f802331b6220bac68c2ab90cce6c8a8f9fed548d72dd092ad1899bf98484604051611df89291906159a4565b336128147fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614612865576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271260048201526024016102e5565b8060005b8181101561291c57612886848483818110611a7c57611a7c615501565b83838281811061289857612898615501565b90506040020160200160208101906128b09190615758565b6128bb5760006128be565b60015b60ff16600360008686858181106128d7576128d7615501565b6128ed926020604090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101612869565b507f530db3bf9b4b0c4f296fe1d9e21620b91db0a8bdcaca4cf1e6dc9844739405c18383604051611b5f929190615775565b336000908152600260205260409020546001908116148015906129ae5750336129957fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b156129e9576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b60005473ffffffffffffffffffffffffffffffffffffffff1680612a3d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271b60048201526024016102e5565b8160005b81811015612d2457612a73858583818110612a5e57612a5e615501565b9050602002016020810190611c3f919061529b565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee868684818110612a9c57612a9c615501565b9050602002016020810190612ab1919061529b565b73ffffffffffffffffffffffffffffffffffffffff161490506000612c6260076000898987818110612ae557612ae5615501565b9050602002016020810190612afa919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600560008a8a88818110612b4b57612b4b615501565b9050602002016020810190612b60919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205484612c5c57898987818110612bb257612bb2615501565b9050602002016020810190612bc7919061529b565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015612c33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c579190615530565b6146fa565b476146fa565b90508015612cb0578115612c7f57612c7a8582614763565b612cb0565b612cb0878785818110612c9457612c94615501565b9050602002016020810190612ca9919061529b565b86836148c2565b80878785818110612cc357612cc3615501565b9050602002016020810190612cd8919061529b565b73ffffffffffffffffffffffffffffffffffffffff167f7ded56fbc1e1a41c85fd5fb3d0ce91eafc72414b7f06ed356c1d921823d4c37c60405160405180910390a35050600101612a41565b5050505050565b33600090815260026020526040902054600190811614801590612d8b575033612d727fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15612dc6576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b8060005b81811015612ece576001848483818110612de657612de6615501565b905060400201602001351115612e2c576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b612e57848483818110612e4157612e41615501565b611c3f926020604090920201908101915061529b565b838382818110612e6957612e69615501565b9050604002016020013560046000868685818110612e8957612e89615501565b612e9f926020604090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101612dca565b507f9ccbc3483d75ae36da94213ac30ac0a047e1226ef3435d004cd501608e5b388b8383604051611b5f929190615a2d565b33600090815260036020526040902054600190811614801590612f60575033612f477fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15612f9b576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271460048201526024016102e5565b612fa485613989565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260046020526040902054600103613007576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271760048201526024016102e5565b60008380156131995760005b8181101561319757613030878783818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081209088888481811061306857613068615501565b905060200201602081019061307d919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250826000036130f8576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271960048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081207f800000000000000000000000000000000000000000000000000000000000000085179189898581811061315357613153615501565b9050602002016020810190613168919061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101613013565b505b5081801561332a5760005b81811015613328576131c1858583818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600960205260408120908686848181106131f9576131f9615501565b905060200201602081019061320e919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925082600003613289576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271960048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526009602052604081207f80000000000000000000000000000000000000000000000000000000000000008517918787858181106132e4576132e4615501565b90506020020160208101906132f9919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020556001016131a4565b505b7f6686e5bb0cc56cbc9aa2b434eb18009891bf411d6d3f961fdfe70be336ca45288787878787604051613361959493929190615acd565b60405180910390a150505050505050565b336000908152600260205260409020546001908116148015906133d25750336133b97fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b1561340d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b80158061341a5750600281115b15613455576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b600181905560405181907fb33384c8a450936b9fba178db857f03fb9865a40d166aa2f9d439a9fdddfbe2290600090a250565b336000908152600360205260409020546001908116148015906134e85750336134cf7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613523576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271460048201526024016102e5565b61352c85613989565b60008380156136ae5760005b818110156136ac57613555878783818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081209088888481811061358d5761358d615501565b90506020020160208101906135a2919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020549250600160ff84901c1461360d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271860048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85169189898581811061366857613668615501565b905060200201602081019061367d919061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101613538565b505b5081801561382f5760005b8181101561382d576136d6858583818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff881660009081526009602052604081209086868481811061370e5761370e615501565b9050602002016020810190613723919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020549250600160ff84901c1461378e576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271860048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526009602052604081207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8516918787858181106137e9576137e9615501565b90506020020160208101906137fe919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020556001016136b9565b505b7facd30ef49b8fd1b51bbefff95071c5b0257180a7778c9c0fa4eb77a8842e290d8787878787604051613361959493929190615acd565b606080828067ffffffffffffffff81111561388357613883614e89565b6040519080825280602002602001820160405280156138ac578160200160208202803683370190505b5092508067ffffffffffffffff8111156138c8576138c8614e89565b6040519080825280602002602001820160405280156138f1578160200160208202803683370190505b50915060005b8181101561398057613914868683818110612a5e57612a5e615501565b61393e86868381811061392957613929615501565b9050602002016020810190611db6919061529b565b85838151811061395057613950615501565b6020026020010185848151811061396957613969615501565b6020908102919091010191909152526001016138f7565b50509250929050565b73ffffffffffffffffffffffffffffffffffffffff81163b1580156139d8575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b15613a13576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272a60048201526024016102e5565b50565b600080856fffffffffffffffffffffffffffffffff811115613a395760809150811c5b67ffffffffffffffff811115613a51576040918201911c5b63ffffffff811115613a65576020918201911c5b61ffff811115613a77576010918201911c5b60ff811115613a88576008918201911c5b600f811115613a99576004918201911c5b6003811115613aaa576002918201911c5b6001811115613aba576001820191505b8015613ac7576001820191505b5084811015613ad35750835b848103905085811c60008211841615613b2257600181019050806001871b03613b2257506001908101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86011b5b6001851b8210613b3157600080fd5b90931b909201949350505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408120548190613b7081613c81565b909350915067ffffffffffffffff831180613b92575067ffffffffffffffff82115b15613bcd576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272860048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff8416600081815260056020526040908190207ffffffffff80000000000000000000000000000000000000003ffffffffffffff841642603a1b17605b87901b17609b86901b17905551839185917f96c40bed7fc8d0ac41633a3bd47f254f0b0076e5df70975c51d23514bc49d3b890613c739061ffff871690601e88901c613fff1690918252602082015260400190565b60405180910390a450915091565b67ffffffffffffffff605b82901c811690609b83901c16811580613ca3575080155b15613cdf576040517fd50d75120000000000000000000000000000000000000000000000000000000081526201117160048201526024016102e5565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480613d09575082155b80613d145750806001145b15613d2157505050915091565b64496cebb80084840283020484019350617fff60db87901c16925082600103613d4c57505050915091565b82600116600103613da15760019290921c91826c7e37be2022c0914b268000000081613d7a57613d7a6155a8565b049250612710601e87901c613fff166b033b2e3c9fd0803ce8000000850102049250613dce565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b80600116600103613e055760011c61271081016b033b2e3c9fd0803ce8000000820281613dfd57613dfd6155a8565b049050613e3b565b60011c61271081016b033b2e3c9fd0803ce8000000820281613e2957613e296155a8565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b6000827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0484118302158202613ec457600080fd5b50910281810615159190040190565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408120548190613f0481613c81565b73ffffffffffffffffffffffffffffffffffffffff861660009081526007602052604081205492955090935064e8d4a51000613f5286600885901c66ffffffffffffff1660ff86161b615578565b613f5c91906155d7565b9050600064e8d4a51000613f8686608886901c66ffffffffffffff16608087901c60ff161b615578565b613f9091906155d7565b9050600066ffffffffffffff604885901c1660ff604086901c161b9050600060c885901c60ff60c087901c161b9050600080851180613fcf5750600083115b1561400257613fde8386615612565b612710613feb8487615612565b613ff59190615578565b613fff91906155d7565b90505b8285111561402c5760018561401961271086615578565b61402391906155d7565b901b945061406e565b828510156140595760018361404361271088615578565b61404d91906155d7565b901b600117945061406e565b841561406957614e20945061406e565b600094505b818411156140985760018461408561271085615578565b61408f91906155d7565b901b93506140da565b818410156140c5576001826140af61271087615578565b6140b991906155d7565b901b60011793506140da565b83156140d557614e2093506140da565b600093505b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526006602052604081205461410a908361494f565b905067ffffffffffffffff8a1180614129575067ffffffffffffffff89115b15614164576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272860048201526024016102e5565b613fff8211156141a4576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272960048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260056020526040908190207ffe000000000000000000000000000000000000000000000003fff0003fff00008b168417601e86901b1742603a1b17605b8e901b17609b8d901b1760db8a901b1760ea89901b179055518a918c917f96c40bed7fc8d0ac41633a3bd47f254f0b0076e5df70975c51d23514bc49d3b8906142529086908890918252602082015260400190565b60405180910390a45050505050505050915091565b73ffffffffffffffffffffffffffffffffffffffff8116613a13576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271160048201526024016102e5565b600073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461435f578173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061435a9190615b1c565b614362565b60125b9050600660ff821610806143795750601260ff8216115b156143b4576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272c60048201526024016102e5565b5050565b600061ffff826040015111156143fe576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271c60048201526024016102e5565b61ffff82606001511115614442576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271d60048201526024016102e5565b61ffff82608001511115614486576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271e60048201526024016102e5565b6020820151158061449d5750612710826020015110155b806144af575081608001518260600151115b156144ea576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b60348260800151901b60248360600151901b60148460200151901b60048560400151901b6001171717179050919050565b600061ffff82606001511115614561576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271c60048201526024016102e5565b61ffff826080015111156145a5576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271f60048201526024016102e5565b61ffff8260a0015111156145e9576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272060048201526024016102e5565b61ffff8260c00151111561462d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272160048201526024016102e5565b602082015115806146445750612710826020015110155b8061465757508160400151826020015110155b806146685750612710826040015110155b8061467a57508160c001518260a00151115b156146b5576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b60548260c00151901b60448360a00151901b60348460400151901b60248560800151901b60148660200151901b60048760600151901b60021717171717179050919050565b600080600061470885613c81565b91509150600061471887846149f8565b905080156147555761472a8783614a4b565b6147349086615612565b935080841161474457600061474e565b61474e8185615595565b9350614759565b8493505b5050509392505050565b804710156147cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016102e5565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114614827576040519150601f19603f3d011682016040523d82523d6000602084013e61482c565b606091505b50509050806148bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016102e5565b505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526148bd908490614a85565b6000600f8316600181900361496f576149688484614b91565b91506149b8565b80600203614981576149688484614c70565b6040517fd50d75120000000000000000000000000000000000000000000000000000000081526201117260048201526024016102e5565b61ffff8211156149f15760405161ffff92507fe41708b2641eb1f7442f6a1e760ae5098fd7ba9f85e0c101513add0fbb27bcd790600090a15b5092915050565b66ffffffffffffff604883901c811660ff604085901c81169190911b91600885901c169084161b64e8d4a51000614a2f8483615578565b614a3991906155d7565b614a439083615612565b949350505050565b60c882901c60ff60c084901c81169190911b9066ffffffffffffff608885901c16608085901c9091161b64e8d4a51000614a2f8483615578565b6000614ae7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614d189092919063ffffffff16565b8051909150156148bd5780806020019051810190614b059190615b39565b6148bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e5565b600080808080601487901c61ffff1680871015614bca5761ffff600489901c16945061ffff602489901c16935060009250809150614be9565b61ffff602489901c16945061ffff603489901c16935080925061271091505b60008084840364e8d4a510008888030281614c0657614c066155a8565b0585810264e8d4a5100089020392508902820190506000811215614c5b576040517fd50d75120000000000000000000000000000000000000000000000000000000081526201117360048201526024016102e5565b64e8d4a5100090049998505050505050505050565b600080808080601487901c61ffff1680871015614ca95761ffff600489901c16945061ffff602489901c16935060009250809150614be9565b603488901c61ffff1680881015614cdb5761ffff60248a901c16955061ffff60448a901c169450819350809250614cfa565b61ffff60448a901c16955061ffff60548a901c16945080935061271092505b5060008084840364e8d4a510008888030281614c0657614c066155a8565b6060614a438484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051614d4c9190615b7a565b60006040518083038185875af1925050503d8060008114614d89576040519150601f19603f3d011682016040523d82523d6000602084013e614d8e565b606091505b5091509150614d9f87838387614daa565b979650505050505050565b60608315614e40578251600003614e395773ffffffffffffffffffffffffffffffffffffffff85163b614e39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e5565b5081614a43565b614a438383815115614e555781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e59190615b96565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614edb57614edb614e89565b60405290565b60405160c0810167ffffffffffffffff81118282101715614edb57614edb614e89565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f4b57614f4b614e89565b604052919050565b600067ffffffffffffffff821115614f6d57614f6d614e89565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114614f9b57600080fd5b919050565b60ff81168114613a1357600080fd5b60006020808385031215614fc257600080fd5b823567ffffffffffffffff811115614fd957600080fd5b8301601f81018513614fea57600080fd5b8035614ffd614ff882614f53565b614f04565b81815260e0918202830184019184820191908884111561501c57600080fd5b938501935b838510156150a55780858a0312156150395760008081fd5b615041614eb8565b61504a86614f77565b8152615057878701614f77565b8782015260408087013561506a81614fa0565b90820152606086810135908201526080808701359082015260a0808701359082015260c0808701359082015283529384019391850191615021565b50979650505050505050565b600060208083850312156150c457600080fd5b823567ffffffffffffffff8111156150db57600080fd5b8301601f810185136150ec57600080fd5b80356150fa614ff882614f53565b81815260c0918202830184019184820191908884111561511957600080fd5b938501935b838510156150a55780858a0312156151365760008081fd5b61513e614ee1565b61514786614f77565b8152615154878701614f77565b8782015260408087013561516781614fa0565b90820152606086810135908201526080808701359082015260a080870135908201528352938401939185019161511e565b60008083601f8401126151aa57600080fd5b50813567ffffffffffffffff8111156151c257600080fd5b6020830191508360208260061b85010111156151dd57600080fd5b9250929050565b600080602083850312156151f757600080fd5b823567ffffffffffffffff81111561520e57600080fd5b61521a85828601615198565b90969095509350505050565b6000806020838503121561523957600080fd5b823567ffffffffffffffff8082111561525157600080fd5b818501915085601f83011261526557600080fd5b81358181111561527457600080fd5b86602060a08302850101111561528957600080fd5b60209290920196919550909350505050565b6000602082840312156152ad57600080fd5b6152b682614f77565b9392505050565b600080602083850312156152d057600080fd5b823567ffffffffffffffff808211156152e857600080fd5b818501915085601f8301126152fc57600080fd5b81358181111561530b57600080fd5b8660208260071b850101111561528957600080fd5b6000806020838503121561533357600080fd5b823567ffffffffffffffff8082111561534b57600080fd5b818501915085601f83011261535f57600080fd5b81358181111561536e57600080fd5b86602060e08302850101111561528957600080fd5b60008083601f84011261539557600080fd5b50813567ffffffffffffffff8111156153ad57600080fd5b6020830191508360208260051b85010111156151dd57600080fd5b600080602083850312156153db57600080fd5b823567ffffffffffffffff8111156153f257600080fd5b61521a85828601615383565b60008060008060006060868803121561541657600080fd5b61541f86614f77565b9450602086013567ffffffffffffffff8082111561543c57600080fd5b61544889838a01615383565b9096509450604088013591508082111561546157600080fd5b5061546e88828901615383565b969995985093965092949392505050565b60006020828403121561549157600080fd5b5035919050565b600081518084526020808501945080840160005b838110156154c8578151875295820195908201906001016154ac565b509495945050505050565b6040815260006154e66040830185615498565b82810360208401526154f88185615498565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561554257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761558f5761558f615549565b92915050565b8181038181111561558f5761558f615549565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261560d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082018082111561558f5761558f615549565b602080825282518282018190526000919060409081850190868401855b828110156156b6578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101615642565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156156b6578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016156e0565b8015158114613a1357600080fd5b60006020828403121561576a57600080fd5b81356152b68161574a565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff6157b183614f77565b168352848201356157c18161574a565b151583860152918301919083019060010161578b565b5090979650505050505050565b600060a082840312156157f657600080fd5b60405160a0810181811067ffffffffffffffff8211171561581957615819614e89565b60405261582583614f77565b8152602083013560208201526040830135604082015260608301356060820152608083013560808201528091505092915050565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff61589583614f77565b16835281850135858401528382013584840152606080830135908401526080808301359084015260a0928301929091019060010161586f565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff61590a83614f77565b1683528185013585840152838201358484015260608083013590840152608092830192909101906001016158e4565b600060e0828403121561594b57600080fd5b615953614eb8565b61595c83614f77565b81526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c08201528091505092915050565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff6159e083614f77565b16835281850135858401528382013584840152606080830135908401526080808301359084015260a0808301359084015260c0808301359084015260e092830192909101906001016159ba565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff615a6983614f77565b16835281850135858401529183019190830190600101615a43565b8183526000602080850194508260005b858110156154c85773ffffffffffffffffffffffffffffffffffffffff615aba83614f77565b1687529582019590820190600101615a94565b73ffffffffffffffffffffffffffffffffffffffff86168152606060208201526000615afd606083018688615a84565b8281036040840152615b10818587615a84565b98975050505050505050565b600060208284031215615b2e57600080fd5b81516152b681614fa0565b600060208284031215615b4b57600080fd5b81516152b68161574a565b60005b83811015615b71578181015183820152602001615b59565b50506000910152565b60008251615b8c818460208701615b56565b9190910192915050565b6020815260008251806020840152615bb5816040850160208701615b56565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f8aec2d23d17b78ecb88e10b6f3873fe8d210a6dde4b38e422699906510a614264736f6c63430008150033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063a5eb43ef11610097578063e8025d7711610066578063e8025d77146101cd578063eae2c8f1146101e0578063ec0484011461021a578063f4bfa0001461022d57600080fd5b8063a5eb43ef14610181578063ac862bfa14610194578063c2da75f0146101a7578063dd4cbf6b146101ba57600080fd5b80633fad77fc116100d35780633fad77fc1461013557806354bb0c1d146101485780637f7b60021461015b5780639dde59771461016e57600080fd5b806301b88f86146100fa57806302c6bb6a1461010f5780633f66feff14610122575b600080fd5b61010d610108366004614faf565b61024e565b005b61010d61011d3660046150b1565b610f5f565b61010d6101303660046151e4565b6119e1565b61010d610143366004615226565b611b6c565b61010d61015636600461529b565b611e06565b61010d6101693660046152bd565b611ef6565b61010d61017c366004615320565b612573565b61010d61018f3660046151e4565b6127eb565b61010d6101a23660046153c8565b61294e565b61010d6101b53660046151e4565b612d2b565b61010d6101c83660046153fe565b612f00565b61010d6101db36600461547f565b613372565b6102077f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61010d6102283660046153fe565b613488565b61024061023b3660046153c8565b613866565b6040516102119291906154d3565b336000908152600260205260409020546001908116148015906102ae5750336102957fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b156102ee576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024015b60405180910390fd5b6000806000806000806000805b8851811015610f1d5761032a89828151811061031957610319615501565b602002602001015160000151613989565b61035089828151811061033f5761033f615501565b602002602001015160200151613989565b600560008a838151811061036657610366615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546000036103ea576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271a60048201526024016102e5565b60018982815181106103fe576103fe615501565b60200260200101516040015160ff161180610452575088818151811061042657610426615501565b602002602001015160c0015189828151811061044457610444615501565b602002602001015160a00151115b8061047a575088818151811061046a5761046a615501565b6020026020010151608001516000145b806105c2575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168982815181106104bd576104bd615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1614610580578881815181106104f6576104f6615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561054c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105709190615530565b61057b90600a615578565b6105a2565b7f00000000000000000000000000000000000000000000000000000000000000005b8982815181106105b4576105b4615501565b602002602001015160c00151115b156105fd576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b613fff89828151811061061257610612615501565b602002602001015160600151111561065a576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272660048201526024016102e5565b62ffffff89828151811061067057610670615501565b60200260200101516080015111156106b8576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272760048201526024016102e5565b8881815181106106ca576106ca615501565b602002602001015160a001516000148061070157508881815181106106f1576106f1615501565b602002602001015160c001516000145b1561073c576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271560048201526024016102e5565b600960008a838151811061075257610752615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a83815181106107ac576107ac615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205497508760001480610830575060018816158015610830575088818151811061081d5761081d615501565b60200260200101516040015160ff166000145b806108695750876001166001148015610869575088818151811061085657610856615501565b60200260200101516040015160ff166001145b15610a305760da6108a7600a600860008d868151811061088b5761088b615501565b602002602001015160c00151613a16909392919063ffffffff16565b901b60c86108e2600a600860008e87815181106108c6576108c6615501565b602002602001015160a00151613a16909392919063ffffffff16565b901b60b08b84815181106108f8576108f8615501565b602002602001015160800151901b60a28c858151811061091a5761091a615501565b602002602001015160600151901b8c858151811061093a5761093a615501565b60200260200101516040015160ff168c7ffffff0000000000000000003fffffffffffffffffffffffffffffffffffffffe161717171717600960008b848151811061098757610987615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b84815181106109e1576109e1615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f15565b610a56898281518110610a4557610a45615501565b602002602001015160200151613b3f565b5050610abd600560008b8481518110610a7157610a71615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613c81565b905080925050600760008a8381518110610ad957610ad9615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549650610b4267ffffffffffffffff608089901c16600860ff9082901c91161b90565b955060c887901c60ff60c089901c161b945067ffffffffffffffff600189901c16935060ff8416600885901c901b935067ffffffffffffffff604189901c16925060ff8316600884901c901b9250876001166000148015610bc35750888181518110610bb057610bb0615501565b60200260200101516040015160ff166001145b15610c2157838511610bd6576000610be0565b610be08486615595565b9450610bf28464e8d4a5100084613e8f565b935081610c0464e8d4a5100085615578565b610c0e91906155d7565b9250610c1a8487615612565b9550610cae565b876001166001148015610c545750888181518110610c4157610c41615501565b60200260200101516040015160ff166000145b15610cae57838611610c67576000610c71565b610c718487615595565b9550610c83848364e8d4a51000613e8f565b935064e8d4a51000610c958385615578565b610c9f91906155d7565b9250610cab8486615612565b94505b610cbd84603860086001613a16565b9350610cce83603860086000613a16565b925060da610ced600a600860008d868151811061088b5761088b615501565b901b60c8610d0c600a600860008e87815181106108c6576108c6615501565b901b60b08b8481518110610d2257610d22615501565b602002602001015160800151901b60a28c8581518110610d4457610d44615501565b602002602001015160600151901b604187901b600189901b8e8781518110610d6e57610d6e615501565b60200260200101516040015160ff168e7ffffff0000000000000000003fffffffe000000000000000000000000000000001617171717171717600960008b8481518110610dbd57610dbd615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b8481518110610e1757610e17615501565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002055610e5a86603860086001613a16565b9550610e6b85603860086001613a16565b945060c085901b608087901b886fffffffffffffffffffffffffffffffff161717600760008b8481518110610ea257610ea2615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f12898281518110610f0157610f01615501565b602002602001015160200151613ed3565b50505b6001016102fb565b507f4a3d512075def8d38b63e79dacfdab217654f641be2b2f7d638b67b2515df7c088604051610f4d9190615625565b60405180910390a15050505050505050565b33600090815260026020526040902054600190811614801590610fbf575033610fa67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610ffa576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b6000806000806000806000805b88518110156119b15761102589828151811061031957610319615501565b61103a89828151811061033f5761033f615501565b600560008a838151811061105057611050615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546000036110d4576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271a60048201526024016102e5565b60018982815181106110e8576110e8615501565b60200260200101516040015160ff161180611120575088818151811061111057611110615501565b6020026020010151608001516000145b1561115b576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b61271089828151811061117057611170615501565b60200260200101516060015111156111b8576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272460048201526024016102e5565b62ffffff8982815181106111ce576111ce615501565b6020026020010151608001511115611216576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272560048201526024016102e5565b88818151811061122857611228615501565b602002602001015160a00151600003611271576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271560048201526024016102e5565b600860008a838151811061128757611287615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a83815181106112e1576112e1615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205497508760001480611365575060018816158015611365575088818151811061135257611352615501565b60200260200101516040015160ff166000145b8061139e575087600116600114801561139e575088818151811061138b5761138b615501565b60200260200101516040015160ff166001145b1561150d5760c86113c0600a600860008d86815181106108c6576108c6615501565b901b60b08a83815181106113d6576113d6615501565b602002602001015160800151901b60a28b84815181106113f8576113f8615501565b602002602001015160600151901b8b848151811061141857611418615501565b60200260200101516040015160ff168b7ffffffffffc00000000000003fffffffffffffffffffffffffffffffffffffffe1617171717600860008b848151811061146457611464615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b84815181106114be576114be615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506119a9565b611522898281518110610a4557610a45615501565b505061153d600560008b8481518110610a7157610a71615501565b5080925050600760008a838151811061155857611558615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205496506115bd67ffffffffffffffff8816600860ff9082901c91161b90565b955066ffffffffffffff604888901c1660ff604089901c161b945067ffffffffffffffff600189901c16935060ff8416600885901c901b935067ffffffffffffffff604189901c16925060ff8316600884901c901b9250876001166000148015611647575088818151811061163457611634615501565b60200260200101516040015160ff166001145b156116af5783851161165a576000611664565b6116648486615595565b94508161167664e8d4a5100086615578565b61168091906155d7565b93508161169264e8d4a5100085615578565b61169c91906155d7565b92506116a88487615612565b9550611746565b8760011660011480156116e257508881815181106116cf576116cf615501565b60200260200101516040015160ff166000145b15611746578386116116f55760006116ff565b6116ff8487615595565b955064e8d4a510006117118386615578565b61171b91906155d7565b935064e8d4a5100061172d8385615578565b61173791906155d7565b92506117438486615612565b94505b61175584603860086000613a16565b935061176683603860086000613a16565b925060c8611785600a600860008d86815181106108c6576108c6615501565b901b60b08a838151811061179b5761179b615501565b602002602001015160800151901b60a28b84815181106117bd576117bd615501565b602002602001015160600151901b604186901b600188901b8d86815181106117e7576117e7615501565b60200260200101516040015160ff168d7ffffffffffc00000000000003fffffffe0000000000000000000000000000000016171717171717600860008b848151811061183557611835615501565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b848151811061188f5761188f615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506118f360386008600089613a16909392919063ffffffff16565b955061190485603860086000613a16565b9450604085901b86887fffffffffffffffffffffffffffffffff00000000000000000000000000000000161717600760008b848151811061194757611947615501565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506119a6898281518110610f0157610f01615501565b50505b600101611007565b507f614e3525ec8c152da9319cd9038950346a4a042d3c6810a7f3ffddc34347bdb088604051610f4d91906156c3565b33611a0a7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614611a5b576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271260048201526024016102e5565b8060005b81811015611b2d57611a97848483818110611a7c57611a7c615501565b611a92926020604090920201908101915061529b565b614267565b838382818110611aa957611aa9615501565b9050604002016020016020810190611ac19190615758565b611acc576000611acf565b60015b60ff1660026000868685818110611ae857611ae8615501565b611afe926020604090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101611a5f565b507fb694cde8b4bf47e7f5845bb4374f98c5b29bbbaa5208ea679121cecb5d8fd3e08383604051611b5f929190615775565b60405180910390a1505050565b33600090815260026020526040902054600190811614801590611bcc575033611bb37fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611c07576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b806000805b82811015611dc657611c44858583818110611c2957611c29615501565b611c3f92602060a090920201908101915061529b565b613989565b611c74858583818110611c5957611c59615501565b611c6f92602060a090920201908101915061529b565b6142b8565b60066000868684818110611c8a57611c8a615501565b611ca092602060a090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205491508115611d0257611cff858583818110611ce457611ce4615501565b611cfa92602060a090920201908101915061529b565b613b3f565b50505b611d32858583818110611d1757611d17615501565b905060a00201803603810190611d2d91906157e4565b6143b8565b60066000878785818110611d4857611d48615501565b611d5e92602060a090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020558115611dbe57611dbb858583818110611da057611da0615501565b611db692602060a090920201908101915061529b565b613ed3565b50505b600101611c0c565b507f1f953465aa7f3f2478d38b6c2a9cfcfbda846398254e278f614d586d527d902c8484604051611df8929190615859565b60405180910390a150505050565b33611e2f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614611e80576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271260048201526024016102e5565b611e8981614267565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917fde3dd47a9a762713b4a9813a037ab6f57e36569d8b0ec4ddb285d8a61878b5b491a250565b33600090815260026020526040902054600190811614801590611f56575033611f3d7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611f91576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b8060008080805b8481101561253157611fcb878783818110611fb557611fb5615501565b611c3f926020608090920201908101915061529b565b60066000888884818110611fe157611fe1615501565b611ff7926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460000361206f576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271a60048201526024016102e5565b61271087878381811061208457612084615501565b9050608002016020013511156120ca576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272260048201526024016102e5565b6127108787838181106120df576120df615501565b905060800201606001351115612125576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272b60048201526024016102e5565b6101f487878381811061213a5761213a615501565b905060800201604001351115612180576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272360048201526024016102e5565b6005600088888481811061219657612196615501565b6121ac926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054935067ffffffffffffffff605b85901c16925067ffffffffffffffff609b85901c16915060008311801561221b5750600082115b1561228b5761222984613c81565b909350915067ffffffffffffffff83118061224b575067ffffffffffffffff82115b15612286576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272860048201526024016102e5565b61231d565b64e8d4a51000925064e8d4a510009150600a8787838181106122af576122af615501565b6122c5926020608090920201908101915061529b565b81546001810183556000928352602090922090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790555b600061271088888481811061233457612334615501565b905060800201606001351415905060f981612350576000612353565b60015b60ff16901b609b84901b605b86901b42603a1b602c8c8c8881811061237a5761237a615501565b90506080020160400135901b60108d8d8981811061239a5761239a615501565b90506080020160200135901b8a7ffdfffffff80000000000000000000000000000000000000000000fffc000ffff16171717171717600560008a8a868181106123e5576123e5615501565b6123fb926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020558061242e57600061244b565b87878381811061244057612440615501565b905060800201606001355b600b60008a8a8681811061246157612461615501565b612477926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0001617600b60008a8a868181106124eb576124eb615501565b612501926020608090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205550600101611f98565b507fa9d5be7e168dc43b637b924e6cc22c262478dffd9d475fa170b6d4e4ba57646086866040516125639291906158ce565b60405180910390a1505050505050565b336000908152600260205260409020546001908116148015906125d35750336125ba7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b1561260e576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b806000805b828110156127b95761264685858381811061263057612630615501565b611c3f92602060e090920201908101915061529b565b61267185858381811061265b5761265b615501565b611c6f92602060e090920201908101915061529b565b6006600086868481811061268757612687615501565b61269d92602060e090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054915081156126fa576126f78585838181106126e1576126e1615501565b611cfa92602060e090920201908101915061529b565b50505b61272a85858381811061270f5761270f615501565b905060e002018036038101906127259190615939565b61451b565b6006600087878581811061274057612740615501565b61275692602060e090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205581156127b1576127ae85858381811061279857612798615501565b611db692602060e090920201908101915061529b565b50505b600101612613565b507ff96f9120f802331b6220bac68c2ab90cce6c8a8f9fed548d72dd092ad1899bf98484604051611df89291906159a4565b336128147fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614612865576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271260048201526024016102e5565b8060005b8181101561291c57612886848483818110611a7c57611a7c615501565b83838281811061289857612898615501565b90506040020160200160208101906128b09190615758565b6128bb5760006128be565b60015b60ff16600360008686858181106128d7576128d7615501565b6128ed926020604090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101612869565b507f530db3bf9b4b0c4f296fe1d9e21620b91db0a8bdcaca4cf1e6dc9844739405c18383604051611b5f929190615775565b336000908152600260205260409020546001908116148015906129ae5750336129957fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b156129e9576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b60005473ffffffffffffffffffffffffffffffffffffffff1680612a3d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271b60048201526024016102e5565b8160005b81811015612d2457612a73858583818110612a5e57612a5e615501565b9050602002016020810190611c3f919061529b565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee868684818110612a9c57612a9c615501565b9050602002016020810190612ab1919061529b565b73ffffffffffffffffffffffffffffffffffffffff161490506000612c6260076000898987818110612ae557612ae5615501565b9050602002016020810190612afa919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600560008a8a88818110612b4b57612b4b615501565b9050602002016020810190612b60919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205484612c5c57898987818110612bb257612bb2615501565b9050602002016020810190612bc7919061529b565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015612c33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c579190615530565b6146fa565b476146fa565b90508015612cb0578115612c7f57612c7a8582614763565b612cb0565b612cb0878785818110612c9457612c94615501565b9050602002016020810190612ca9919061529b565b86836148c2565b80878785818110612cc357612cc3615501565b9050602002016020810190612cd8919061529b565b73ffffffffffffffffffffffffffffffffffffffff167f7ded56fbc1e1a41c85fd5fb3d0ce91eafc72414b7f06ed356c1d921823d4c37c60405160405180910390a35050600101612a41565b5050505050565b33600090815260026020526040902054600190811614801590612d8b575033612d727fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15612dc6576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b8060005b81811015612ece576001848483818110612de657612de6615501565b905060400201602001351115612e2c576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b612e57848483818110612e4157612e41615501565b611c3f926020604090920201908101915061529b565b838382818110612e6957612e69615501565b9050604002016020013560046000868685818110612e8957612e89615501565b612e9f926020604090920201908101915061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101612dca565b507f9ccbc3483d75ae36da94213ac30ac0a047e1226ef3435d004cd501608e5b388b8383604051611b5f929190615a2d565b33600090815260036020526040902054600190811614801590612f60575033612f477fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15612f9b576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271460048201526024016102e5565b612fa485613989565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260046020526040902054600103613007576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271760048201526024016102e5565b60008380156131995760005b8181101561319757613030878783818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081209088888481811061306857613068615501565b905060200201602081019061307d919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250826000036130f8576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271960048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081207f800000000000000000000000000000000000000000000000000000000000000085179189898581811061315357613153615501565b9050602002016020810190613168919061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101613013565b505b5081801561332a5760005b81811015613328576131c1858583818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600960205260408120908686848181106131f9576131f9615501565b905060200201602081019061320e919061529b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925082600003613289576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271960048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526009602052604081207f80000000000000000000000000000000000000000000000000000000000000008517918787858181106132e4576132e4615501565b90506020020160208101906132f9919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020556001016131a4565b505b7f6686e5bb0cc56cbc9aa2b434eb18009891bf411d6d3f961fdfe70be336ca45288787878787604051613361959493929190615acd565b60405180910390a150505050505050565b336000908152600260205260409020546001908116148015906133d25750336133b97fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b1561340d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271360048201526024016102e5565b80158061341a5750600281115b15613455576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b600181905560405181907fb33384c8a450936b9fba178db857f03fb9865a40d166aa2f9d439a9fdddfbe2290600090a250565b336000908152600360205260409020546001908116148015906134e85750336134cf7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613523576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271460048201526024016102e5565b61352c85613989565b60008380156136ae5760005b818110156136ac57613555878783818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081209088888481811061358d5761358d615501565b90506020020160208101906135a2919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020549250600160ff84901c1461360d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271860048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526008602052604081207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85169189898581811061366857613668615501565b905060200201602081019061367d919061529b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002055600101613538565b505b5081801561382f5760005b8181101561382d576136d6858583818110612a5e57612a5e615501565b73ffffffffffffffffffffffffffffffffffffffff881660009081526009602052604081209086868481811061370e5761370e615501565b9050602002016020810190613723919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020549250600160ff84901c1461378e576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271860048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff881660009081526009602052604081207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8516918787858181106137e9576137e9615501565b90506020020160208101906137fe919061529b565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020556001016136b9565b505b7facd30ef49b8fd1b51bbefff95071c5b0257180a7778c9c0fa4eb77a8842e290d8787878787604051613361959493929190615acd565b606080828067ffffffffffffffff81111561388357613883614e89565b6040519080825280602002602001820160405280156138ac578160200160208202803683370190505b5092508067ffffffffffffffff8111156138c8576138c8614e89565b6040519080825280602002602001820160405280156138f1578160200160208202803683370190505b50915060005b8181101561398057613914868683818110612a5e57612a5e615501565b61393e86868381811061392957613929615501565b9050602002016020810190611db6919061529b565b85838151811061395057613950615501565b6020026020010185848151811061396957613969615501565b6020908102919091010191909152526001016138f7565b50509250929050565b73ffffffffffffffffffffffffffffffffffffffff81163b1580156139d8575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b15613a13576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272a60048201526024016102e5565b50565b600080856fffffffffffffffffffffffffffffffff811115613a395760809150811c5b67ffffffffffffffff811115613a51576040918201911c5b63ffffffff811115613a65576020918201911c5b61ffff811115613a77576010918201911c5b60ff811115613a88576008918201911c5b600f811115613a99576004918201911c5b6003811115613aaa576002918201911c5b6001811115613aba576001820191505b8015613ac7576001820191505b5084811015613ad35750835b848103905085811c60008211841615613b2257600181019050806001871b03613b2257506001908101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86011b5b6001851b8210613b3157600080fd5b90931b909201949350505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408120548190613b7081613c81565b909350915067ffffffffffffffff831180613b92575067ffffffffffffffff82115b15613bcd576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272860048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff8416600081815260056020526040908190207ffffffffff80000000000000000000000000000000000000003ffffffffffffff841642603a1b17605b87901b17609b86901b17905551839185917f96c40bed7fc8d0ac41633a3bd47f254f0b0076e5df70975c51d23514bc49d3b890613c739061ffff871690601e88901c613fff1690918252602082015260400190565b60405180910390a450915091565b67ffffffffffffffff605b82901c811690609b83901c16811580613ca3575080155b15613cdf576040517fd50d75120000000000000000000000000000000000000000000000000000000081526201117160048201526024016102e5565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480613d09575082155b80613d145750806001145b15613d2157505050915091565b64496cebb80084840283020484019350617fff60db87901c16925082600103613d4c57505050915091565b82600116600103613da15760019290921c91826c7e37be2022c0914b268000000081613d7a57613d7a6155a8565b049250612710601e87901c613fff166b033b2e3c9fd0803ce8000000850102049250613dce565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b80600116600103613e055760011c61271081016b033b2e3c9fd0803ce8000000820281613dfd57613dfd6155a8565b049050613e3b565b60011c61271081016b033b2e3c9fd0803ce8000000820281613e2957613e296155a8565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b6000827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0484118302158202613ec457600080fd5b50910281810615159190040190565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408120548190613f0481613c81565b73ffffffffffffffffffffffffffffffffffffffff861660009081526007602052604081205492955090935064e8d4a51000613f5286600885901c66ffffffffffffff1660ff86161b615578565b613f5c91906155d7565b9050600064e8d4a51000613f8686608886901c66ffffffffffffff16608087901c60ff161b615578565b613f9091906155d7565b9050600066ffffffffffffff604885901c1660ff604086901c161b9050600060c885901c60ff60c087901c161b9050600080851180613fcf5750600083115b1561400257613fde8386615612565b612710613feb8487615612565b613ff59190615578565b613fff91906155d7565b90505b8285111561402c5760018561401961271086615578565b61402391906155d7565b901b945061406e565b828510156140595760018361404361271088615578565b61404d91906155d7565b901b600117945061406e565b841561406957614e20945061406e565b600094505b818411156140985760018461408561271085615578565b61408f91906155d7565b901b93506140da565b818410156140c5576001826140af61271087615578565b6140b991906155d7565b901b60011793506140da565b83156140d557614e2093506140da565b600093505b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526006602052604081205461410a908361494f565b905067ffffffffffffffff8a1180614129575067ffffffffffffffff89115b15614164576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272860048201526024016102e5565b613fff8211156141a4576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272960048201526024016102e5565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260056020526040908190207ffe000000000000000000000000000000000000000000000003fff0003fff00008b168417601e86901b1742603a1b17605b8e901b17609b8d901b1760db8a901b1760ea89901b179055518a918c917f96c40bed7fc8d0ac41633a3bd47f254f0b0076e5df70975c51d23514bc49d3b8906142529086908890918252602082015260400190565b60405180910390a45050505050505050915091565b73ffffffffffffffffffffffffffffffffffffffff8116613a13576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271160048201526024016102e5565b600073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461435f578173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061435a9190615b1c565b614362565b60125b9050600660ff821610806143795750601260ff8216115b156143b4576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272c60048201526024016102e5565b5050565b600061ffff826040015111156143fe576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271c60048201526024016102e5565b61ffff82606001511115614442576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271d60048201526024016102e5565b61ffff82608001511115614486576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271e60048201526024016102e5565b6020820151158061449d5750612710826020015110155b806144af575081608001518260600151115b156144ea576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b60348260800151901b60248360600151901b60148460200151901b60048560400151901b6001171717179050919050565b600061ffff82606001511115614561576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271c60048201526024016102e5565b61ffff826080015111156145a5576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271f60048201526024016102e5565b61ffff8260a0015111156145e9576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272060048201526024016102e5565b61ffff8260c00151111561462d576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261272160048201526024016102e5565b602082015115806146445750612710826020015110155b8061465757508160400151826020015110155b806146685750612710826040015110155b8061467a57508160c001518260a00151115b156146b5576040517fdcab82e200000000000000000000000000000000000000000000000000000000815261271660048201526024016102e5565b60548260c00151901b60448360a00151901b60348460400151901b60248560800151901b60148660200151901b60048760600151901b60021717171717179050919050565b600080600061470885613c81565b91509150600061471887846149f8565b905080156147555761472a8783614a4b565b6147349086615612565b935080841161474457600061474e565b61474e8185615595565b9350614759565b8493505b5050509392505050565b804710156147cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016102e5565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114614827576040519150601f19603f3d011682016040523d82523d6000602084013e61482c565b606091505b50509050806148bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016102e5565b505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526148bd908490614a85565b6000600f8316600181900361496f576149688484614b91565b91506149b8565b80600203614981576149688484614c70565b6040517fd50d75120000000000000000000000000000000000000000000000000000000081526201117260048201526024016102e5565b61ffff8211156149f15760405161ffff92507fe41708b2641eb1f7442f6a1e760ae5098fd7ba9f85e0c101513add0fbb27bcd790600090a15b5092915050565b66ffffffffffffff604883901c811660ff604085901c81169190911b91600885901c169084161b64e8d4a51000614a2f8483615578565b614a3991906155d7565b614a439083615612565b949350505050565b60c882901c60ff60c084901c81169190911b9066ffffffffffffff608885901c16608085901c9091161b64e8d4a51000614a2f8483615578565b6000614ae7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614d189092919063ffffffff16565b8051909150156148bd5780806020019051810190614b059190615b39565b6148bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e5565b600080808080601487901c61ffff1680871015614bca5761ffff600489901c16945061ffff602489901c16935060009250809150614be9565b61ffff602489901c16945061ffff603489901c16935080925061271091505b60008084840364e8d4a510008888030281614c0657614c066155a8565b0585810264e8d4a5100089020392508902820190506000811215614c5b576040517fd50d75120000000000000000000000000000000000000000000000000000000081526201117360048201526024016102e5565b64e8d4a5100090049998505050505050505050565b600080808080601487901c61ffff1680871015614ca95761ffff600489901c16945061ffff602489901c16935060009250809150614be9565b603488901c61ffff1680881015614cdb5761ffff60248a901c16955061ffff60448a901c169450819350809250614cfa565b61ffff60448a901c16955061ffff60548a901c16945080935061271092505b5060008084840364e8d4a510008888030281614c0657614c066155a8565b6060614a438484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051614d4c9190615b7a565b60006040518083038185875af1925050503d8060008114614d89576040519150601f19603f3d011682016040523d82523d6000602084013e614d8e565b606091505b5091509150614d9f87838387614daa565b979650505050505050565b60608315614e40578251600003614e395773ffffffffffffffffffffffffffffffffffffffff85163b614e39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e5565b5081614a43565b614a438383815115614e555781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e59190615b96565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614edb57614edb614e89565b60405290565b60405160c0810167ffffffffffffffff81118282101715614edb57614edb614e89565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f4b57614f4b614e89565b604052919050565b600067ffffffffffffffff821115614f6d57614f6d614e89565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114614f9b57600080fd5b919050565b60ff81168114613a1357600080fd5b60006020808385031215614fc257600080fd5b823567ffffffffffffffff811115614fd957600080fd5b8301601f81018513614fea57600080fd5b8035614ffd614ff882614f53565b614f04565b81815260e0918202830184019184820191908884111561501c57600080fd5b938501935b838510156150a55780858a0312156150395760008081fd5b615041614eb8565b61504a86614f77565b8152615057878701614f77565b8782015260408087013561506a81614fa0565b90820152606086810135908201526080808701359082015260a0808701359082015260c0808701359082015283529384019391850191615021565b50979650505050505050565b600060208083850312156150c457600080fd5b823567ffffffffffffffff8111156150db57600080fd5b8301601f810185136150ec57600080fd5b80356150fa614ff882614f53565b81815260c0918202830184019184820191908884111561511957600080fd5b938501935b838510156150a55780858a0312156151365760008081fd5b61513e614ee1565b61514786614f77565b8152615154878701614f77565b8782015260408087013561516781614fa0565b90820152606086810135908201526080808701359082015260a080870135908201528352938401939185019161511e565b60008083601f8401126151aa57600080fd5b50813567ffffffffffffffff8111156151c257600080fd5b6020830191508360208260061b85010111156151dd57600080fd5b9250929050565b600080602083850312156151f757600080fd5b823567ffffffffffffffff81111561520e57600080fd5b61521a85828601615198565b90969095509350505050565b6000806020838503121561523957600080fd5b823567ffffffffffffffff8082111561525157600080fd5b818501915085601f83011261526557600080fd5b81358181111561527457600080fd5b86602060a08302850101111561528957600080fd5b60209290920196919550909350505050565b6000602082840312156152ad57600080fd5b6152b682614f77565b9392505050565b600080602083850312156152d057600080fd5b823567ffffffffffffffff808211156152e857600080fd5b818501915085601f8301126152fc57600080fd5b81358181111561530b57600080fd5b8660208260071b850101111561528957600080fd5b6000806020838503121561533357600080fd5b823567ffffffffffffffff8082111561534b57600080fd5b818501915085601f83011261535f57600080fd5b81358181111561536e57600080fd5b86602060e08302850101111561528957600080fd5b60008083601f84011261539557600080fd5b50813567ffffffffffffffff8111156153ad57600080fd5b6020830191508360208260051b85010111156151dd57600080fd5b600080602083850312156153db57600080fd5b823567ffffffffffffffff8111156153f257600080fd5b61521a85828601615383565b60008060008060006060868803121561541657600080fd5b61541f86614f77565b9450602086013567ffffffffffffffff8082111561543c57600080fd5b61544889838a01615383565b9096509450604088013591508082111561546157600080fd5b5061546e88828901615383565b969995985093965092949392505050565b60006020828403121561549157600080fd5b5035919050565b600081518084526020808501945080840160005b838110156154c8578151875295820195908201906001016154ac565b509495945050505050565b6040815260006154e66040830185615498565b82810360208401526154f88185615498565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561554257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761558f5761558f615549565b92915050565b8181038181111561558f5761558f615549565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261560d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082018082111561558f5761558f615549565b602080825282518282018190526000919060409081850190868401855b828110156156b6578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101615642565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156156b6578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016156e0565b8015158114613a1357600080fd5b60006020828403121561576a57600080fd5b81356152b68161574a565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff6157b183614f77565b168352848201356157c18161574a565b151583860152918301919083019060010161578b565b5090979650505050505050565b600060a082840312156157f657600080fd5b60405160a0810181811067ffffffffffffffff8211171561581957615819614e89565b60405261582583614f77565b8152602083013560208201526040830135604082015260608301356060820152608083013560808201528091505092915050565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff61589583614f77565b16835281850135858401528382013584840152606080830135908401526080808301359084015260a0928301929091019060010161586f565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff61590a83614f77565b1683528185013585840152838201358484015260608083013590840152608092830192909101906001016158e4565b600060e0828403121561594b57600080fd5b615953614eb8565b61595c83614f77565b81526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c08201528091505092915050565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff6159e083614f77565b16835281850135858401528382013584840152606080830135908401526080808301359084015260a0808301359084015260c0808301359084015260e092830192909101906001016159ba565b6020808252818101839052600090604080840186845b878110156157d75773ffffffffffffffffffffffffffffffffffffffff615a6983614f77565b16835281850135858401529183019190830190600101615a43565b8183526000602080850194508260005b858110156154c85773ffffffffffffffffffffffffffffffffffffffff615aba83614f77565b1687529582019590820190600101615a94565b73ffffffffffffffffffffffffffffffffffffffff86168152606060208201526000615afd606083018688615a84565b8281036040840152615b10818587615a84565b98975050505050505050565b600060208284031215615b2e57600080fd5b81516152b681614fa0565b600060208284031215615b4b57600080fd5b81516152b68161574a565b60005b83811015615b71578181015183820152602001615b59565b50506000910152565b60008251615b8c818460208701615b56565b9190910192915050565b6020815260008251806020840152615bb5816040850160208701615b56565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f8aec2d23d17b78ecb88e10b6f3873fe8d210a6dde4b38e422699906510a614264736f6c63430008150033",
"devdoc": {
"kind": "dev",
"methods": {
"changeStatus(uint256)": {
"params": {
"newStatus_": "new status status = 2 -> pause, status = 1 -> resume."
}
},
"collectRevenue(address[])": {
"details": "Note that this can revert if token balance is < revenueAmount (utilization > 100%)",
"params": {
"tokens_": "array of tokens to collect revenue for"
}
},
"pauseUser(address,address[],address[])": {
"params": {
"borrowTokens_": "token addresses to pause borrowings for",
"supplyTokens_": "token addresses to pause withdrawals for",
"user_": "address of user to pause operations for"
}
},
"unpauseUser(address,address[],address[])": {
"params": {
"borrowTokens_": "token addresses to unpause borrowings for",
"supplyTokens_": "token addresses to unpause withdrawals for",
"user_": "address of user to unpause operations for"
}
},
"updateAuths((address,bool)[])": {
"params": {
"authsStatus_": "array of structs setting allowed status for an address. status true => add auth, false => remove auth"
}
},
"updateExchangePrices(address[])": {
"params": {
"tokens_": "tokens to update exchange prices for"
},
"returns": {
"borrowExchangePrices_": "new borrow rates of overall system for each token",
"supplyExchangePrices_": "new supply rates of overall system for each token"
}
},
"updateGuardians((address,bool)[])": {
"params": {
"guardiansStatus_": "array of structs setting allowed status for an address. status true => add guardian, false => remove guardian"
}
},
"updateRateDataV1s((address,uint256,uint256,uint256,uint256)[])": {
"params": {
"tokensRateData_": "array of RateDataV1Params with rate data to set for each token"
}
},
"updateRateDataV2s((address,uint256,uint256,uint256,uint256,uint256,uint256)[])": {
"params": {
"tokensRateData_": "array of RateDataV2Params with rate data to set for each token"
}
},
"updateRevenueCollector(address)": {
"params": {
"revenueCollector_": "new revenue collector address"
}
},
"updateTokenConfigs((address,uint256,uint256,uint256)[])": {
"params": {
"tokenConfigs_": "contains token address, fee & utilization threshold"
}
},
"updateUserBorrowConfigs((address,address,uint8,uint256,uint256,uint256,uint256)[])": {
"params": {
"userBorrowConfigs_": "struct array containing user borrow config, see `UserBorrowConfig` struct for more info"
}
},
"updateUserClasses((address,uint256)[])": {
"params": {
"userClasses_": "struct array of uint256 value to assign for each user address"
}
},
"updateUserSupplyConfigs((address,address,uint8,uint256,uint256,uint256)[])": {
"params": {
"userSupplyConfigs_": "struct array containing user supply config, see `UserSupplyConfig` struct for more info"
}
}
},
"title": "Fluid Liquidity AdminModule",
"version": 1
},
"userdoc": {
"events": {
"BorrowRateMaxCap()": {
"notice": "emitted if the calculated borrow rate surpassed max borrow rate (16 bits) and was capped at maximum value 65535"
},
"LogChangeStatus(uint256)": {
"notice": "emitted when status is changed (paused / unpaused)"
},
"LogCollectRevenue(address,uint256)": {
"notice": "emitted when revenue is collected"
},
"LogPauseUser(address,address[],address[])": {
"notice": "emitted when a user gets certain tokens paused"
},
"LogUnpauseUser(address,address[],address[])": {
"notice": "emitted when a user gets certain tokens unpaused"
},
"LogUpdateAuths((address,bool)[])": {
"notice": "emitted when allowed auths are updated"
},
"LogUpdateExchangePrices(address,uint256,uint256,uint256,uint256)": {
"notice": "emitted when exchange prices and borrow rate are updated"
},
"LogUpdateGuardians((address,bool)[])": {
"notice": "emitted when allowed guardians are updated"
},
"LogUpdateRateDataV1s((address,uint256,uint256,uint256,uint256)[])": {
"notice": "emitted when token rate data is updated with rate data v1"
},
"LogUpdateRateDataV2s((address,uint256,uint256,uint256,uint256,uint256,uint256)[])": {
"notice": "emitted when token rate data is updated with rate data v2"
},
"LogUpdateRevenueCollector(address)": {
"notice": "emitted when revenue collector address is updated"
},
"LogUpdateTokenConfigs((address,uint256,uint256,uint256)[])": {
"notice": "emitted when token configs are updated"
},
"LogUpdateUserBorrowConfigs((address,address,uint8,uint256,uint256,uint256,uint256)[])": {
"notice": "emitted when user borrow configs are updated"
},
"LogUpdateUserClasses((address,uint256)[])": {
"notice": "emitted when user classes are updated"
},
"LogUpdateUserSupplyConfigs((address,address,uint8,uint256,uint256,uint256)[])": {
"notice": "emitted when user supply configs are updated"
}
},
"kind": "user",
"methods": {
"changeStatus(uint256)": {
"notice": "changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths."
},
"collectRevenue(address[])": {
"notice": "collects revenue for tokens to configured revenueCollector address."
},
"pauseUser(address,address[],address[])": {
"notice": "pause operations for a particular user in class 0 (class 1 users can't be paused by guardians). Only callable by Guardians."
},
"unpauseUser(address,address[],address[])": {
"notice": "unpause operations for a particular user in class 0 (class 1 users can't be paused by guardians). Only callable by Guardians."
},
"updateAuths((address,bool)[])": {
"notice": "adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract. auths can be helpful in reducing governance overhead where it's not needed."
},
"updateExchangePrices(address[])": {
"notice": "gets the current updated exchange prices for n tokens and updates all prices, rates related data in storage."
},
"updateGuardians((address,bool)[])": {
"notice": "adds/removes guardians. Only callable by Governance."
},
"updateRateDataV1s((address,uint256,uint256,uint256,uint256)[])": {
"notice": "update tokens rate data version 1. Only callable by Auths."
},
"updateRateDataV2s((address,uint256,uint256,uint256,uint256,uint256,uint256)[])": {
"notice": "update tokens rate data version 2. Only callable by Auths."
},
"updateRevenueCollector(address)": {
"notice": "changes the revenue collector address (contract that is sent revenue). Only callable by Governance."
},
"updateTokenConfigs((address,uint256,uint256,uint256)[])": {
"notice": "updates token configs: fee charge on borrowers interest & storage update utilization threshold. Only callable by Auths."
},
"updateUserBorrowConfigs((address,address,uint8,uint256,uint256,uint256,uint256)[])": {
"notice": "setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits. Only callable by Auths."
},
"updateUserClasses((address,uint256)[])": {
"notice": "updates user classes: 0 is for new protocols, 1 is for established protocols. Only callable by Auths."
},
"updateUserSupplyConfigs((address,address,uint8,uint256,uint256,uint256)[])": {
"notice": "sets user supply configs per token basis. Eg: with interest or interest-free and automated limits. Only callable by Auths."
}
},
"notice": "Fluid Liquidity auth protected methods to configure things such as: guardians, auths, governance, revenue, token configs, allowances etc. Accessibility of methods is restricted to Governance, Auths or Guardians. Governance is Auth & Governance by default",
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 16694,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_revenueCollector",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 16697,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_status",
"offset": 0,
"slot": "1",
"type": "t_uint256"
},
{
"astId": 16702,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_isAuth",
"offset": 0,
"slot": "2",
"type": "t_mapping(t_address,t_uint256)"
},
{
"astId": 16707,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_isGuardian",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_address,t_uint256)"
},
{
"astId": 16712,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_userClass",
"offset": 0,
"slot": "4",
"type": "t_mapping(t_address,t_uint256)"
},
{
"astId": 16717,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_exchangePricesAndConfig",
"offset": 0,
"slot": "5",
"type": "t_mapping(t_address,t_uint256)"
},
{
"astId": 16722,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_rateData",
"offset": 0,
"slot": "6",
"type": "t_mapping(t_address,t_uint256)"
},
{
"astId": 16727,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_totalAmounts",
"offset": 0,
"slot": "7",
"type": "t_mapping(t_address,t_uint256)"
},
{
"astId": 16734,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_userSupplyData",
"offset": 0,
"slot": "8",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
},
{
"astId": 16741,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_userBorrowData",
"offset": 0,
"slot": "9",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
},
{
"astId": 16745,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_listedTokens",
"offset": 0,
"slot": "10",
"type": "t_array(t_address)dyn_storage"
},
{
"astId": 16750,
"contract": "contracts/liquidity/adminModule/main.sol:FluidLiquidityAdminModule",
"label": "_configs2",
"offset": 0,
"slot": "11",
"type": "t_mapping(t_address,t_uint256)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_address)dyn_storage": {
"base": "t_address",
"encoding": "dynamic_array",
"label": "address[]",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_mapping(t_address,t_uint256))": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => mapping(address => uint256))",
"numberOfBytes": "32",
"value": "t_mapping(t_address,t_uint256)"
},
"t_mapping(t_address,t_uint256)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => uint256)",
"numberOfBytes": "32",
"value": "t_uint256"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}