From 5770fa89d998c9e54b71f714e50834bd407767ea Mon Sep 17 00:00:00 2001 From: danilo neves cruz Date: Tue, 21 Nov 2023 15:29:32 -0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20ethereum:=20deploy=20new=20`WBTC?= =?UTF-8?q?`=20irm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/nasty-pumpkins-bathe.md | 5 +++ .../ethereum/InterestRateModelWBTC.json | 45 ++++++++++--------- 2 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 .changeset/nasty-pumpkins-bathe.md diff --git a/.changeset/nasty-pumpkins-bathe.md b/.changeset/nasty-pumpkins-bathe.md new file mode 100644 index 000000000..a6662302b --- /dev/null +++ b/.changeset/nasty-pumpkins-bathe.md @@ -0,0 +1,5 @@ +--- +"@exactly/protocol": patch +--- + +🚀 ethereum: deploy new `WBTC` irm diff --git a/deployments/ethereum/InterestRateModelWBTC.json b/deployments/ethereum/InterestRateModelWBTC.json index a0163ed34..29725014a 100644 --- a/deployments/ethereum/InterestRateModelWBTC.json +++ b/deployments/ethereum/InterestRateModelWBTC.json @@ -1,5 +1,5 @@ { - "address": "0x3cEcEa7Ef91b6F6d3760f6b5845c3332dC00a420", + "address": "0xf05385BC0b38E941f65D3031e1695bfBF8d60c90", "abi": [ { "inputs": [ @@ -218,35 +218,35 @@ "type": "function" } ], - "transactionHash": "0x8c438a603417063b20924d50a3aadb36b3ddc3d4d56413e9b845a30c79e9f2d0", + "transactionHash": "0x458b64601ae16577ea39cd52ce91db6b327c98722f152cadf67c40e1a9ed6198", "receipt": { "to": null, "from": "0xe61Bdef3FFF4C3CF7A07996DCB8802b5C85B665a", - "contractAddress": "0x3cEcEa7Ef91b6F6d3760f6b5845c3332dC00a420", - "transactionIndex": 45, - "gasUsed": "595125", + "contractAddress": "0xf05385BC0b38E941f65D3031e1695bfBF8d60c90", + "transactionIndex": 87, + "gasUsed": "595827", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc9ba660409f66a7e8273a6ecd3435b4cefa207af65d8bd156fb3664dba84e34d", - "transactionHash": "0x8c438a603417063b20924d50a3aadb36b3ddc3d4d56413e9b845a30c79e9f2d0", + "blockHash": "0x6872742e5a82e4e9660d5e32c23efbec932d57636af2a036b28a75419635e449", + "transactionHash": "0x458b64601ae16577ea39cd52ce91db6b327c98722f152cadf67c40e1a9ed6198", "logs": [], - "blockNumber": 16887593, - "cumulativeGasUsed": "5545634", + "blockNumber": 18621814, + "cumulativeGasUsed": "6416908", "status": 1, "byzantium": true }, "args": [ - "369700000000000000", - "-349700000000000000", - "1000007768000000000", - "36184000000000000", - "-15925000000000000", - "1007213882000000000" + "465860000000000000", + "-413450000000000000", + "1050553997000000000", + "27194000000000000", + "3016000000000000", + "1007776377000000000" ], - "numDeployments": 4, - "solcInputHash": "67403aa452dca047d7345f8ccca0ca14", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fixedCurveA_\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fixedCurveB_\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"fixedMaxUtilization_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"floatingCurveA_\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"floatingCurveB_\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"floatingMaxUtilization_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyMatured\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UtilizationExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maturity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplied\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"backupAssets\",\"type\":\"uint256\"}],\"name\":\"fixedBorrowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fixedCurveA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fixedCurveB\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fixedMaxUtilization\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"floatingCurveA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"floatingCurveB\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"floatingMaxUtilization\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"utilization\",\"type\":\"uint256\"}],\"name\":\"floatingRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"borrowed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplied\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"backupAssets\",\"type\":\"uint256\"}],\"name\":\"minFixedRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"utilization\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"fixedBorrowRate(uint256,uint256,uint256,uint256,uint256)\":{\"params\":{\"amount\":\"the current borrow's amount.\",\"backupAssets\":\"backup supplier assets.\",\"borrowed\":\"ex-ante amount borrowed from this fixed rate pool.\",\"maturity\":\"maturity date for calculating days left to maturity.\",\"supplied\":\"deposits in the fixed rate pool.\"},\"returns\":{\"_0\":\"rate of the fee that the borrower will have to pay (represented with 18 decimals).\"}},\"floatingRate(uint256)\":{\"details\":\"Uses the floating rate curve parameters.\",\"params\":{\"utilization\":\"utilization rate, with 18 decimals precision.\"},\"returns\":{\"_0\":\"the interest rate, with 18 decimals precision.\"}},\"minFixedRate(uint256,uint256,uint256)\":{\"params\":{\"backupAssets\":\"backup supplier assets.\",\"borrowed\":\"amount borrowed from the fixed rate pool.\",\"supplied\":\"deposits in the fixed rate pool.\"},\"returns\":{\"rate\":\"of the fee that the borrower will have to pay and current utilization.\"}}},\"stateVariables\":{\"PRECISION_THRESHOLD\":{\"details\":\"When `eta` (`delta / alpha`) is lower than this value, use simpson's rule for approximation.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"fixedBorrowRate(uint256,uint256,uint256,uint256,uint256)\":{\"notice\":\"Gets the rate to borrow a certain amount at a certain maturity with supply/demand values in the fixed rate pool and assets from the backup supplier.\"},\"fixedCurveA()\":{\"notice\":\"Scale factor of the fixed curve.\"},\"fixedCurveB()\":{\"notice\":\"Origin intercept of the fixed curve.\"},\"fixedMaxUtilization()\":{\"notice\":\"Asymptote of the fixed curve.\"},\"floatingCurveA()\":{\"notice\":\"Scale factor of the floating curve.\"},\"floatingCurveB()\":{\"notice\":\"Origin intercept of the floating curve.\"},\"floatingMaxUtilization()\":{\"notice\":\"Asymptote of the floating curve.\"},\"floatingRate(uint256)\":{\"notice\":\"Returns the interest rate for an utilization rate.\"},\"minFixedRate(uint256,uint256,uint256)\":{\"notice\":\"Gets the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and assets from the backup supplier.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/InterestRateModel.sol\":\"InterestRateModel\"},\"debug\":{\"revertStrings\":\"strip\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.17;\\n\\nimport { Math } from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport { FixedPointMathLib } from \\\"solmate/src/utils/FixedPointMathLib.sol\\\";\\n\\ncontract InterestRateModel {\\n using FixedPointMathLib for uint256;\\n using FixedPointMathLib for int256;\\n\\n /// @notice Threshold to define which method should be used to calculate the interest rates.\\n /// @dev When `eta` (`delta / alpha`) is lower than this value, use simpson's rule for approximation.\\n uint256 internal constant PRECISION_THRESHOLD = 7.5e14;\\n\\n /// @notice Scale factor of the fixed curve.\\n uint256 public immutable fixedCurveA;\\n /// @notice Origin intercept of the fixed curve.\\n int256 public immutable fixedCurveB;\\n /// @notice Asymptote of the fixed curve.\\n uint256 public immutable fixedMaxUtilization;\\n\\n /// @notice Scale factor of the floating curve.\\n uint256 public immutable floatingCurveA;\\n /// @notice Origin intercept of the floating curve.\\n int256 public immutable floatingCurveB;\\n /// @notice Asymptote of the floating curve.\\n uint256 public immutable floatingMaxUtilization;\\n\\n constructor(\\n uint256 fixedCurveA_,\\n int256 fixedCurveB_,\\n uint256 fixedMaxUtilization_,\\n uint256 floatingCurveA_,\\n int256 floatingCurveB_,\\n uint256 floatingMaxUtilization_\\n ) {\\n fixedCurveA = fixedCurveA_;\\n fixedCurveB = fixedCurveB_;\\n fixedMaxUtilization = fixedMaxUtilization_;\\n\\n floatingCurveA = floatingCurveA_;\\n floatingCurveB = floatingCurveB_;\\n floatingMaxUtilization = floatingMaxUtilization_;\\n\\n // reverts if it's an invalid curve (such as one yielding a negative interest rate).\\n fixedRate(0, 0);\\n floatingRate(0);\\n }\\n\\n /// @notice Gets the rate to borrow a certain amount at a certain maturity with supply/demand values in the fixed rate\\n /// pool and assets from the backup supplier.\\n /// @param maturity maturity date for calculating days left to maturity.\\n /// @param amount the current borrow's amount.\\n /// @param borrowed ex-ante amount borrowed from this fixed rate pool.\\n /// @param supplied deposits in the fixed rate pool.\\n /// @param backupAssets backup supplier assets.\\n /// @return rate of the fee that the borrower will have to pay (represented with 18 decimals).\\n function fixedBorrowRate(\\n uint256 maturity,\\n uint256 amount,\\n uint256 borrowed,\\n uint256 supplied,\\n uint256 backupAssets\\n ) external view returns (uint256) {\\n if (block.timestamp >= maturity) revert AlreadyMatured();\\n\\n uint256 potentialAssets = supplied + backupAssets;\\n uint256 utilizationAfter = (borrowed + amount).divWadUp(potentialAssets);\\n\\n if (utilizationAfter > 1e18) revert UtilizationExceeded();\\n\\n uint256 utilizationBefore = borrowed.divWadDown(potentialAssets);\\n\\n return fixedRate(utilizationBefore, utilizationAfter).mulDivDown(maturity - block.timestamp, 365 days);\\n }\\n\\n /// @notice Gets the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and\\n /// assets from the backup supplier.\\n /// @param borrowed amount borrowed from the fixed rate pool.\\n /// @param supplied deposits in the fixed rate pool.\\n /// @param backupAssets backup supplier assets.\\n /// @return rate of the fee that the borrower will have to pay and current utilization.\\n function minFixedRate(\\n uint256 borrowed,\\n uint256 supplied,\\n uint256 backupAssets\\n ) external view returns (uint256 rate, uint256 utilization) {\\n utilization = borrowed.divWadUp(supplied + backupAssets);\\n rate = fixedRate(utilization, utilization);\\n }\\n\\n /// @notice Returns the interest rate integral from `u0` to `u1`, using the analytical solution (ln).\\n /// @dev Uses the fixed rate curve parameters.\\n /// Handles special case where delta utilization tends to zero, using simpson's rule.\\n /// @param utilizationBefore ex-ante utilization rate, with 18 decimals precision.\\n /// @param utilizationAfter ex-post utilization rate, with 18 decimals precision.\\n /// @return the interest rate, with 18 decimals precision.\\n function fixedRate(uint256 utilizationBefore, uint256 utilizationAfter) internal view returns (uint256) {\\n uint256 alpha = fixedMaxUtilization - utilizationBefore;\\n uint256 delta = utilizationAfter - utilizationBefore;\\n int256 r = int256(\\n delta.divWadDown(alpha) < PRECISION_THRESHOLD\\n ? (fixedCurveA.divWadDown(alpha) +\\n fixedCurveA.mulDivDown(4e18, fixedMaxUtilization - ((utilizationAfter + utilizationBefore) / 2)) +\\n fixedCurveA.divWadDown(fixedMaxUtilization - utilizationAfter)) / 6\\n : fixedCurveA.mulDivDown(\\n uint256(int256(alpha.divWadDown(fixedMaxUtilization - utilizationAfter)).lnWad()),\\n delta\\n )\\n ) + fixedCurveB;\\n assert(r >= 0);\\n return uint256(r);\\n }\\n\\n /// @notice Returns the interest rate for an utilization rate.\\n /// @dev Uses the floating rate curve parameters.\\n /// @param utilization utilization rate, with 18 decimals precision.\\n /// @return the interest rate, with 18 decimals precision.\\n function floatingRate(uint256 utilization) public view returns (uint256) {\\n int256 r = int256(floatingCurveA.divWadDown(floatingMaxUtilization - utilization)) + floatingCurveB;\\n assert(r >= 0);\\n return uint256(r);\\n }\\n}\\n\\nerror AlreadyMatured();\\nerror UtilizationExceeded();\\n\",\"keccak256\":\"0xc530cffad07d14a24f969d67c7d02f420b8ce6db2959153ca5a5169be00a06fa\",\"license\":\"BUSL-1.1\"},\"solmate/src/utils/FixedPointMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0;\\n\\n/// @notice Arithmetic library with operations for fixed-point numbers.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\\nlibrary FixedPointMathLib {\\n /*//////////////////////////////////////////////////////////////\\n SIMPLIFIED FIXED POINT OPERATIONS\\n //////////////////////////////////////////////////////////////*/\\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 function powWad(int256 x, int256 y) internal pure returns (int256) {\\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\\n }\\n\\n function expWad(int256 x) internal pure returns (int256 r) {\\n unchecked {\\n // When the result is < 0.5 we return zero. This happens when\\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\\n if (x <= -42139678854452767551) return 0;\\n\\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\\n if (x >= 135305999368893231589) revert(\\\"EXP_OVERFLOW\\\");\\n\\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\\n // for more intermediate precision and a binary basis. This base conversion\\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\\n x = (x << 78) / 5**18;\\n\\n // Reduce range of x to (-\\u00bd ln 2, \\u00bd ln 2) * 2**96 by factoring out powers\\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\\n x = x - k * 54916777467707473351141471128;\\n\\n // k is in the range [-61, 195].\\n\\n // Evaluate using a (6, 7)-term rational approximation.\\n // p is made monic, we'll multiply by a scale factor later.\\n int256 y = x + 1346386616545796478920950773328;\\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\\n int256 p = y + x - 94201549194550492254356042504812;\\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\\n p = p * x + (4385272521454847904659076985693276 << 96);\\n\\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\\n int256 q = x - 2855989394907223263936484059900;\\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\\n\\n assembly {\\n // Div in assembly because solidity adds a zero check despite the unchecked.\\n // The q polynomial won't have zeros in the domain as all its roots are complex.\\n // No scaling is necessary because p is already 2**96 too large.\\n r := sdiv(p, q)\\n }\\n\\n // r should be in the range (0.09, 0.25) * 2**96.\\n\\n // We now need to multiply r by:\\n // * the scale factor s = ~6.031367120.\\n // * the 2**k factor from the range reduction.\\n // * the 1e18 / 2**96 factor for base conversion.\\n // We do this all at once, with an intermediate result in 2**213\\n // basis, so the final right shift is always by a positive amount.\\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\\n }\\n }\\n\\n function lnWad(int256 x) internal pure returns (int256 r) {\\n unchecked {\\n require(x > 0, \\\"UNDEFINED\\\");\\n\\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\\n // We do this by multiplying by 2**96 / 10**18. But since\\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\\n // and add ln(2**96 / 10**18) at the end.\\n\\n // Reduce range of x to (1, 2) * 2**96\\n // ln(2^k * x) = k * ln(2) + ln(x)\\n int256 k = int256(log2(uint256(x))) - 96;\\n x <<= uint256(159 - k);\\n x = int256(uint256(x) >> 159);\\n\\n // Evaluate using a (8, 8)-term rational approximation.\\n // p is made monic, we will multiply by a scale factor later.\\n int256 p = x + 3273285459638523848632254066296;\\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\\n p = p * x - (795164235651350426258249787498 << 96);\\n\\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\\n // q is monic by convention.\\n int256 q = x + 5573035233440673466300451813936;\\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\\n q = ((q * x) >> 96) + 909429971244387300277376558375;\\n assembly {\\n // Div in assembly because solidity adds a zero check despite the unchecked.\\n // The q polynomial is known not to have zeros in the domain.\\n // No scaling required because p is already 2**96 too large.\\n r := sdiv(p, q)\\n }\\n\\n // r is in the range (0, 0.125) * 2**96\\n\\n // Finalization, we need to:\\n // * multiply by the scale factor s = 5.549\\u2026\\n // * add ln(2**96 / 10**18)\\n // * add k * ln(2)\\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\\n\\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\\n r *= 1677202110996718588342820967067443963516166;\\n // add ln(2) * k * 5e18 * 2**192\\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\\n // add ln(2**96 / 10**18) * 5e18 * 2**192\\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\\n // base conversion: mul 2**18 / 2**192\\n r >>= 174;\\n }\\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 assembly {\\n // Store x * y in z for now.\\n z := mul(x, y)\\n\\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\\n revert(0, 0)\\n }\\n\\n // Divide z by the denominator.\\n z := div(z, denominator)\\n }\\n }\\n\\n function mulDivUp(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 z) {\\n assembly {\\n // Store x * y in z for now.\\n z := mul(x, y)\\n\\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\\n revert(0, 0)\\n }\\n\\n // First, divide z - 1 by the denominator and add 1.\\n // We allow z - 1 to underflow if z is 0, because we multiply the\\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\\n }\\n }\\n\\n function rpow(\\n uint256 x,\\n uint256 n,\\n uint256 scalar\\n ) internal pure returns (uint256 z) {\\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 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 log2(uint256 x) internal pure returns (uint256 r) {\\n require(x > 0, \\\"UNDEFINED\\\");\\n\\n assembly {\\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n r := or(r, shl(3, lt(0xff, shr(r, x))))\\n r := or(r, shl(2, lt(0xf, shr(r, x))))\\n r := or(r, shl(1, lt(0x3, shr(r, x))))\\n r := or(r, lt(0x1, shr(r, x)))\\n }\\n }\\n\\n function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n assembly {\\n // z will equal 0 if y is 0, unlike in Solidity where it will revert.\\n z := mod(x, y)\\n }\\n }\\n\\n function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n assembly {\\n // z will equal 0 if y is 0, unlike in Solidity where it will revert.\\n z := div(x, y)\\n }\\n }\\n\\n /// @dev Will return 0 instead of reverting if y is zero.\\n function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n assembly {\\n // Add 1 to x * y if x % y > 0.\\n z := add(gt(mod(x, y), 0), div(x, y))\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0bf1d4f3999a4471e0fded0a2f67e7fe328e2a27385348571b1fc0a8d9c9f62e\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101406040523480156200001257600080fd5b5060405162000fbf38038062000fbf8339810160408190526200003591620004c3565b608086905260a085905260c084905260e0839052610100829052610120819052620000626000806200007c565b506200006f600062000217565b50505050505050620005b4565b6000808360c0516200008f919062000524565b905060006200009f858562000524565b9050600060a0516602aa1efb94e000620000c885856200026c60201b6200035a1790919060201c565b106200012f576200012962000110620000ff8860c051620000ea919062000524565b876200026c60201b6200035a1790919060201c565b6200028a60201b620003761760201c565b846080516200043360201b62000522179092919060201c565b620001ea565b60066200015c8760c05162000145919062000524565b6080516200026c60201b6200035a1790919060201c565b620001aa673782dace9d9000006002620001778c8c6200053a565b62000183919062000550565b60c05162000192919062000524565b6080516200043360201b62000522179092919060201c565b620001c6876080516200026c60201b6200035a1790919060201c565b620001d291906200053a565b620001de91906200053a565b620001ea919062000550565b620001f6919062000573565b905060008112156200020c576200020c6200059e565b925050505b92915050565b600080610100516200024a846101205162000233919062000524565b60e0516200026c60201b6200035a1790919060201c565b62000256919062000573565b905060008112156200021157620002116200059e565b60006200028383670de0b6b3a76400008462000433565b9392505050565b60008082136200029957600080fd5b60006060620002a88462000453565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd190190910260016c0504a838426634cdd8738f543560611b03190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b8282028115158415858304851417166200044c57600080fd5b0492915050565b60008082116200046257600080fd5b5060016001600160801b03821160071b82811c6001600160401b031060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60008060008060008060c08789031215620004dd57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b634e487b7160e01b600052601160045260246000fd5b818103818111156200021157620002116200050e565b808201808211156200021157620002116200050e565b6000826200056e57634e487b7160e01b600052601260045260246000fd5b500490565b80820182811260008312801582168215821617156200059657620005966200050e565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60805160a05160c05160e051610100516101205161096a6200065560003960008181610187015261023d01526000818160d701526102150152600081816101600152610263015260008181609d0152818161055f015281816105dc0152818161064401526106b70152600081816101c1015261059701526000818160fe0152818161060e0152818161066a015281816106dd0152610708015261096a6000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c806384a874661161006657806384a8746614610148578063b99699341461015b578063d837268514610182578063df635f3d146101a9578063dfb08e10146101bc57600080fd5b80630481520b1461009857806326980121146100d25780634d6fc522146100f957806362caa04914610120575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b61013361012e366004610818565b6101e3565b604080519283526020830191909152016100c9565b6100bf610156366004610844565b610210565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf6101b736600461085d565b6102ab565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6000806101fa6101f384866108ae565b8690610541565b90506102068182610556565b9150935093915050565b6000807f0000000000000000000000000000000000000000000000000000000000000000610288610261857f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b61029291906108d4565b905060008112156102a5576102a56108fc565b92915050565b60008542106102cd576040516305a29e1160e51b815260040160405180910390fd5b60006102d983856108ae565b905060006102f1826102eb89896108ae565b90610541565b9050670de0b6b3a764000081111561031c576040516386a8c2bd60e01b815260040160405180910390fd5b6000610328878461035a565b905061034d610337428b6108c1565b6301e133806103468486610556565b9190610522565b9998505050505050505050565b600061036f83670de0b6b3a764000084610522565b9392505050565b600080821361038457600080fd5b6000606061039184610771565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b82820281151584158583048514171661053a57600080fd5b0492915050565b600061036f83670de0b6b3a7640000846107ea565b600080610583847f00000000000000000000000000000000000000000000000000000000000000006108c1565b9050600061059185856108c1565b905060007f00000000000000000000000000000000000000000000000000000000000000006602aa1efb94e0006105c8848661035a565b106106395761063461060c610607610600897f00000000000000000000000000000000000000000000000000000000000000006108c1565b879061035a565b610376565b7f00000000000000000000000000000000000000000000000000000000000000009085610522565b61074b565b600661068f610668887f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b610703673782dace9d90000060026106a78c8c6108ae565b6106b19190610912565b6106db907f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009190610522565b61072d7f00000000000000000000000000000000000000000000000000000000000000008861035a565b61073791906108ae565b61074191906108ae565b61074b9190610912565b61075591906108d4565b90506000811215610768576107686108fc565b95945050505050565b600080821161077f57600080fd5b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b82820281151584158583048514171661080257600080fd5b6001826001830304018115150290509392505050565b60008060006060848603121561082d57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561085657600080fd5b5035919050565b600080600080600060a0868803121561087557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156102a5576102a5610898565b818103818111156102a5576102a5610898565b80820182811260008312801582168215821617156108f4576108f4610898565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60008261092f57634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122030753b87d5eaed4b89794a01df3d3f399176f5c3294b4f561d462bca90d6cbee64736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c806384a874661161006657806384a8746614610148578063b99699341461015b578063d837268514610182578063df635f3d146101a9578063dfb08e10146101bc57600080fd5b80630481520b1461009857806326980121146100d25780634d6fc522146100f957806362caa04914610120575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b61013361012e366004610818565b6101e3565b604080519283526020830191909152016100c9565b6100bf610156366004610844565b610210565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf6101b736600461085d565b6102ab565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6000806101fa6101f384866108ae565b8690610541565b90506102068182610556565b9150935093915050565b6000807f0000000000000000000000000000000000000000000000000000000000000000610288610261857f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b61029291906108d4565b905060008112156102a5576102a56108fc565b92915050565b60008542106102cd576040516305a29e1160e51b815260040160405180910390fd5b60006102d983856108ae565b905060006102f1826102eb89896108ae565b90610541565b9050670de0b6b3a764000081111561031c576040516386a8c2bd60e01b815260040160405180910390fd5b6000610328878461035a565b905061034d610337428b6108c1565b6301e133806103468486610556565b9190610522565b9998505050505050505050565b600061036f83670de0b6b3a764000084610522565b9392505050565b600080821361038457600080fd5b6000606061039184610771565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b82820281151584158583048514171661053a57600080fd5b0492915050565b600061036f83670de0b6b3a7640000846107ea565b600080610583847f00000000000000000000000000000000000000000000000000000000000000006108c1565b9050600061059185856108c1565b905060007f00000000000000000000000000000000000000000000000000000000000000006602aa1efb94e0006105c8848661035a565b106106395761063461060c610607610600897f00000000000000000000000000000000000000000000000000000000000000006108c1565b879061035a565b610376565b7f00000000000000000000000000000000000000000000000000000000000000009085610522565b61074b565b600661068f610668887f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b610703673782dace9d90000060026106a78c8c6108ae565b6106b19190610912565b6106db907f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009190610522565b61072d7f00000000000000000000000000000000000000000000000000000000000000008861035a565b61073791906108ae565b61074191906108ae565b61074b9190610912565b61075591906108d4565b90506000811215610768576107686108fc565b95945050505050565b600080821161077f57600080fd5b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b82820281151584158583048514171661080257600080fd5b6001826001830304018115150290509392505050565b60008060006060848603121561082d57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561085657600080fd5b5035919050565b600080600080600060a0868803121561087557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156102a5576102a5610898565b818103818111156102a5576102a5610898565b80820182811260008312801582168215821617156108f4576108f4610898565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60008261092f57634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122030753b87d5eaed4b89794a01df3d3f399176f5c3294b4f561d462bca90d6cbee64736f6c63430008110033", + "numDeployments": 5, + "solcInputHash": "222d5883a9f2fda67cf6f52bad6a10a1", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fixedCurveA_\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fixedCurveB_\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"fixedMaxUtilization_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"floatingCurveA_\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"floatingCurveB_\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"floatingMaxUtilization_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyMatured\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UtilizationExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maturity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplied\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"backupAssets\",\"type\":\"uint256\"}],\"name\":\"fixedBorrowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fixedCurveA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fixedCurveB\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fixedMaxUtilization\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"floatingCurveA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"floatingCurveB\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"floatingMaxUtilization\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"utilization\",\"type\":\"uint256\"}],\"name\":\"floatingRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"borrowed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplied\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"backupAssets\",\"type\":\"uint256\"}],\"name\":\"minFixedRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"utilization\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"fixedBorrowRate(uint256,uint256,uint256,uint256,uint256)\":{\"params\":{\"amount\":\"the current borrow's amount.\",\"backupAssets\":\"backup supplier assets.\",\"borrowed\":\"ex-ante amount borrowed from this fixed rate pool.\",\"maturity\":\"maturity date for calculating days left to maturity.\",\"supplied\":\"deposits in the fixed rate pool.\"},\"returns\":{\"_0\":\"rate of the fee that the borrower will have to pay (represented with 18 decimals).\"}},\"floatingRate(uint256)\":{\"details\":\"Uses the floating rate curve parameters.\",\"params\":{\"utilization\":\"utilization rate, with 18 decimals precision.\"},\"returns\":{\"_0\":\"the interest rate, with 18 decimals precision.\"}},\"minFixedRate(uint256,uint256,uint256)\":{\"params\":{\"backupAssets\":\"backup supplier assets.\",\"borrowed\":\"amount borrowed from the fixed rate pool.\",\"supplied\":\"deposits in the fixed rate pool.\"},\"returns\":{\"rate\":\"of the fee that the borrower will have to pay, with 18 decimals precision.\",\"utilization\":\"current utilization rate, with 18 decimals precision.\"}}},\"stateVariables\":{\"PRECISION_THRESHOLD\":{\"details\":\"When `eta` (`delta / alpha`) is lower than this value, use simpson's rule for approximation.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"fixedBorrowRate(uint256,uint256,uint256,uint256,uint256)\":{\"notice\":\"Gets the rate to borrow a certain amount at a certain maturity with supply/demand values in the fixed rate pool and assets from the backup supplier.\"},\"fixedCurveA()\":{\"notice\":\"Scale factor of the fixed curve.\"},\"fixedCurveB()\":{\"notice\":\"Origin intercept of the fixed curve.\"},\"fixedMaxUtilization()\":{\"notice\":\"Asymptote of the fixed curve.\"},\"floatingCurveA()\":{\"notice\":\"Scale factor of the floating curve.\"},\"floatingCurveB()\":{\"notice\":\"Origin intercept of the floating curve.\"},\"floatingMaxUtilization()\":{\"notice\":\"Asymptote of the floating curve.\"},\"floatingRate(uint256)\":{\"notice\":\"Returns the interest rate for an utilization rate.\"},\"minFixedRate(uint256,uint256,uint256)\":{\"notice\":\"Returns the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and assets from the backup supplier.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/InterestRateModel.sol\":\"InterestRateModel\"},\"debug\":{\"revertStrings\":\"strip\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.17;\\n\\nimport { Math } from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport { FixedPointMathLib } from \\\"solmate/src/utils/FixedPointMathLib.sol\\\";\\n\\ncontract InterestRateModel {\\n using FixedPointMathLib for uint256;\\n using FixedPointMathLib for int256;\\n\\n /// @notice Threshold to define which method should be used to calculate the interest rates.\\n /// @dev When `eta` (`delta / alpha`) is lower than this value, use simpson's rule for approximation.\\n uint256 internal constant PRECISION_THRESHOLD = 7.5e14;\\n\\n /// @notice Scale factor of the fixed curve.\\n uint256 public immutable fixedCurveA;\\n /// @notice Origin intercept of the fixed curve.\\n int256 public immutable fixedCurveB;\\n /// @notice Asymptote of the fixed curve.\\n uint256 public immutable fixedMaxUtilization;\\n\\n /// @notice Scale factor of the floating curve.\\n uint256 public immutable floatingCurveA;\\n /// @notice Origin intercept of the floating curve.\\n int256 public immutable floatingCurveB;\\n /// @notice Asymptote of the floating curve.\\n uint256 public immutable floatingMaxUtilization;\\n\\n constructor(\\n uint256 fixedCurveA_,\\n int256 fixedCurveB_,\\n uint256 fixedMaxUtilization_,\\n uint256 floatingCurveA_,\\n int256 floatingCurveB_,\\n uint256 floatingMaxUtilization_\\n ) {\\n assert(fixedMaxUtilization_ > 1e18);\\n assert(floatingMaxUtilization_ > 1e18);\\n\\n fixedCurveA = fixedCurveA_;\\n fixedCurveB = fixedCurveB_;\\n fixedMaxUtilization = fixedMaxUtilization_;\\n\\n floatingCurveA = floatingCurveA_;\\n floatingCurveB = floatingCurveB_;\\n floatingMaxUtilization = floatingMaxUtilization_;\\n\\n // reverts if it's an invalid curve (such as one yielding a negative interest rate).\\n fixedRate(0, 0);\\n floatingRate(0);\\n }\\n\\n /// @notice Gets the rate to borrow a certain amount at a certain maturity with supply/demand values in the fixed rate\\n /// pool and assets from the backup supplier.\\n /// @param maturity maturity date for calculating days left to maturity.\\n /// @param amount the current borrow's amount.\\n /// @param borrowed ex-ante amount borrowed from this fixed rate pool.\\n /// @param supplied deposits in the fixed rate pool.\\n /// @param backupAssets backup supplier assets.\\n /// @return rate of the fee that the borrower will have to pay (represented with 18 decimals).\\n function fixedBorrowRate(\\n uint256 maturity,\\n uint256 amount,\\n uint256 borrowed,\\n uint256 supplied,\\n uint256 backupAssets\\n ) external view returns (uint256) {\\n if (block.timestamp >= maturity) revert AlreadyMatured();\\n\\n uint256 potentialAssets = supplied + backupAssets;\\n uint256 utilizationAfter = (borrowed + amount).divWadUp(potentialAssets);\\n\\n if (utilizationAfter > 1e18) revert UtilizationExceeded();\\n\\n uint256 utilizationBefore = borrowed.divWadDown(potentialAssets);\\n\\n return fixedRate(utilizationBefore, utilizationAfter).mulDivDown(maturity - block.timestamp, 365 days);\\n }\\n\\n /// @notice Returns the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and\\n /// assets from the backup supplier.\\n /// @param borrowed amount borrowed from the fixed rate pool.\\n /// @param supplied deposits in the fixed rate pool.\\n /// @param backupAssets backup supplier assets.\\n /// @return rate of the fee that the borrower will have to pay, with 18 decimals precision.\\n /// @return utilization current utilization rate, with 18 decimals precision.\\n function minFixedRate(\\n uint256 borrowed,\\n uint256 supplied,\\n uint256 backupAssets\\n ) external view returns (uint256 rate, uint256 utilization) {\\n utilization = borrowed.divWadUp(supplied + backupAssets);\\n rate = fixedRate(utilization, utilization);\\n }\\n\\n /// @notice Returns the interest rate integral from `u0` to `u1`, using the analytical solution (ln).\\n /// @dev Uses the fixed rate curve parameters.\\n /// Handles special case where delta utilization tends to zero, using simpson's rule.\\n /// @param utilizationBefore ex-ante utilization rate, with 18 decimals precision.\\n /// @param utilizationAfter ex-post utilization rate, with 18 decimals precision.\\n /// @return the interest rate, with 18 decimals precision.\\n function fixedRate(uint256 utilizationBefore, uint256 utilizationAfter) internal view returns (uint256) {\\n uint256 alpha = fixedMaxUtilization - utilizationBefore;\\n uint256 delta = utilizationAfter - utilizationBefore;\\n int256 r = int256(\\n delta.divWadDown(alpha) < PRECISION_THRESHOLD\\n ? (fixedCurveA.divWadDown(alpha) +\\n fixedCurveA.mulDivDown(4e18, fixedMaxUtilization - ((utilizationAfter + utilizationBefore) / 2)) +\\n fixedCurveA.divWadDown(fixedMaxUtilization - utilizationAfter)) / 6\\n : fixedCurveA.mulDivDown(\\n uint256(int256(alpha.divWadDown(fixedMaxUtilization - utilizationAfter)).lnWad()),\\n delta\\n )\\n ) + fixedCurveB;\\n assert(r >= 0);\\n return uint256(r);\\n }\\n\\n /// @notice Returns the interest rate for an utilization rate.\\n /// @dev Uses the floating rate curve parameters.\\n /// @param utilization utilization rate, with 18 decimals precision.\\n /// @return the interest rate, with 18 decimals precision.\\n function floatingRate(uint256 utilization) public view returns (uint256) {\\n int256 r = int256(floatingCurveA.divWadDown(floatingMaxUtilization - utilization)) + floatingCurveB;\\n assert(r >= 0);\\n return uint256(r);\\n }\\n}\\n\\nerror AlreadyMatured();\\nerror UtilizationExceeded();\\n\",\"keccak256\":\"0xfb1d32f03bb869906ce577bb0e4cbc3e141006c7087f4e826ce513a9c4582f57\",\"license\":\"BUSL-1.1\"},\"solmate/src/utils/FixedPointMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0;\\n\\n/// @notice Arithmetic library with operations for fixed-point numbers.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\\nlibrary FixedPointMathLib {\\n /*//////////////////////////////////////////////////////////////\\n SIMPLIFIED FIXED POINT OPERATIONS\\n //////////////////////////////////////////////////////////////*/\\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 function powWad(int256 x, int256 y) internal pure returns (int256) {\\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\\n }\\n\\n function expWad(int256 x) internal pure returns (int256 r) {\\n unchecked {\\n // When the result is < 0.5 we return zero. This happens when\\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\\n if (x <= -42139678854452767551) return 0;\\n\\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\\n if (x >= 135305999368893231589) revert(\\\"EXP_OVERFLOW\\\");\\n\\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\\n // for more intermediate precision and a binary basis. This base conversion\\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\\n x = (x << 78) / 5**18;\\n\\n // Reduce range of x to (-\\u00bd ln 2, \\u00bd ln 2) * 2**96 by factoring out powers\\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\\n x = x - k * 54916777467707473351141471128;\\n\\n // k is in the range [-61, 195].\\n\\n // Evaluate using a (6, 7)-term rational approximation.\\n // p is made monic, we'll multiply by a scale factor later.\\n int256 y = x + 1346386616545796478920950773328;\\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\\n int256 p = y + x - 94201549194550492254356042504812;\\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\\n p = p * x + (4385272521454847904659076985693276 << 96);\\n\\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\\n int256 q = x - 2855989394907223263936484059900;\\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\\n\\n assembly {\\n // Div in assembly because solidity adds a zero check despite the unchecked.\\n // The q polynomial won't have zeros in the domain as all its roots are complex.\\n // No scaling is necessary because p is already 2**96 too large.\\n r := sdiv(p, q)\\n }\\n\\n // r should be in the range (0.09, 0.25) * 2**96.\\n\\n // We now need to multiply r by:\\n // * the scale factor s = ~6.031367120.\\n // * the 2**k factor from the range reduction.\\n // * the 1e18 / 2**96 factor for base conversion.\\n // We do this all at once, with an intermediate result in 2**213\\n // basis, so the final right shift is always by a positive amount.\\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\\n }\\n }\\n\\n function lnWad(int256 x) internal pure returns (int256 r) {\\n unchecked {\\n require(x > 0, \\\"UNDEFINED\\\");\\n\\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\\n // We do this by multiplying by 2**96 / 10**18. But since\\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\\n // and add ln(2**96 / 10**18) at the end.\\n\\n // Reduce range of x to (1, 2) * 2**96\\n // ln(2^k * x) = k * ln(2) + ln(x)\\n int256 k = int256(log2(uint256(x))) - 96;\\n x <<= uint256(159 - k);\\n x = int256(uint256(x) >> 159);\\n\\n // Evaluate using a (8, 8)-term rational approximation.\\n // p is made monic, we will multiply by a scale factor later.\\n int256 p = x + 3273285459638523848632254066296;\\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\\n p = p * x - (795164235651350426258249787498 << 96);\\n\\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\\n // q is monic by convention.\\n int256 q = x + 5573035233440673466300451813936;\\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\\n q = ((q * x) >> 96) + 909429971244387300277376558375;\\n assembly {\\n // Div in assembly because solidity adds a zero check despite the unchecked.\\n // The q polynomial is known not to have zeros in the domain.\\n // No scaling required because p is already 2**96 too large.\\n r := sdiv(p, q)\\n }\\n\\n // r is in the range (0, 0.125) * 2**96\\n\\n // Finalization, we need to:\\n // * multiply by the scale factor s = 5.549\\u2026\\n // * add ln(2**96 / 10**18)\\n // * add k * ln(2)\\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\\n\\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\\n r *= 1677202110996718588342820967067443963516166;\\n // add ln(2) * k * 5e18 * 2**192\\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\\n // add ln(2**96 / 10**18) * 5e18 * 2**192\\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\\n // base conversion: mul 2**18 / 2**192\\n r >>= 174;\\n }\\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 assembly {\\n // Store x * y in z for now.\\n z := mul(x, y)\\n\\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\\n revert(0, 0)\\n }\\n\\n // Divide z by the denominator.\\n z := div(z, denominator)\\n }\\n }\\n\\n function mulDivUp(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 z) {\\n assembly {\\n // Store x * y in z for now.\\n z := mul(x, y)\\n\\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\\n revert(0, 0)\\n }\\n\\n // First, divide z - 1 by the denominator and add 1.\\n // We allow z - 1 to underflow if z is 0, because we multiply the\\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\\n }\\n }\\n\\n function rpow(\\n uint256 x,\\n uint256 n,\\n uint256 scalar\\n ) internal pure returns (uint256 z) {\\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 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 log2(uint256 x) internal pure returns (uint256 r) {\\n require(x > 0, \\\"UNDEFINED\\\");\\n\\n assembly {\\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n r := or(r, shl(3, lt(0xff, shr(r, x))))\\n r := or(r, shl(2, lt(0xf, shr(r, x))))\\n r := or(r, shl(1, lt(0x3, shr(r, x))))\\n r := or(r, lt(0x1, shr(r, x)))\\n }\\n }\\n\\n function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n assembly {\\n // z will equal 0 if y is 0, unlike in Solidity where it will revert.\\n z := mod(x, y)\\n }\\n }\\n\\n function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n assembly {\\n // z will equal 0 if y is 0, unlike in Solidity where it will revert.\\n z := div(x, y)\\n }\\n }\\n\\n /// @dev Will return 0 instead of reverting if y is zero.\\n function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n assembly {\\n // Add 1 to x * y if x % y > 0.\\n z := add(gt(mod(x, y), 0), div(x, y))\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0bf1d4f3999a4471e0fded0a2f67e7fe328e2a27385348571b1fc0a8d9c9f62e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6101406040523480156200001257600080fd5b5060405162000ff338038062000ff38339810160408190526200003591620004f7565b670de0b6b3a764000084116200004f576200004f62000542565b670de0b6b3a7640000811162000069576200006962000542565b608086905260a085905260c084905260e083905261010082905261012081905262000096600080620000b0565b50620000a360006200024b565b50505050505050620005e8565b6000808360c051620000c391906200056e565b90506000620000d385856200056e565b9050600060a0516602aa1efb94e000620000fc8585620002a060201b6200035a1790919060201c565b1062000163576200015d62000144620001338860c0516200011e91906200056e565b87620002a060201b6200035a1790919060201c565b620002be60201b620003761760201c565b846080516200046760201b62000522179092919060201c565b6200021e565b6006620001908760c0516200017991906200056e565b608051620002a060201b6200035a1790919060201c565b620001de673782dace9d9000006002620001ab8c8c62000584565b620001b791906200059a565b60c051620001c691906200056e565b6080516200046760201b62000522179092919060201c565b620001fa87608051620002a060201b6200035a1790919060201c565b62000206919062000584565b62000212919062000584565b6200021e91906200059a565b6200022a9190620005bd565b9050600081121562000240576200024062000542565b925050505b92915050565b600080610100516200027e84610120516200026791906200056e565b60e051620002a060201b6200035a1790919060201c565b6200028a9190620005bd565b9050600081121562000245576200024562000542565b6000620002b783670de0b6b3a76400008462000467565b9392505050565b6000808213620002cd57600080fd5b60006060620002dc8462000487565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd190190910260016c0504a838426634cdd8738f543560611b03190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b8282028115158415858304851417166200048057600080fd5b0492915050565b60008082116200049657600080fd5b5060016001600160801b03821160071b82811c6001600160401b031060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60008060008060008060c087890312156200051157600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111562000245576200024562000558565b8082018082111562000245576200024562000558565b600082620005b857634e487b7160e01b600052601260045260246000fd5b500490565b8082018281126000831280158216821582161715620005e057620005e062000558565b505092915050565b60805160a05160c05160e051610100516101205161096a6200068960003960008181610187015261023d01526000818160d701526102150152600081816101600152610263015260008181609d0152818161055f015281816105dc0152818161064401526106b70152600081816101c1015261059701526000818160fe0152818161060e0152818161066a015281816106dd0152610708015261096a6000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c806384a874661161006657806384a8746614610148578063b99699341461015b578063d837268514610182578063df635f3d146101a9578063dfb08e10146101bc57600080fd5b80630481520b1461009857806326980121146100d25780634d6fc522146100f957806362caa04914610120575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b61013361012e366004610818565b6101e3565b604080519283526020830191909152016100c9565b6100bf610156366004610844565b610210565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf6101b736600461085d565b6102ab565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6000806101fa6101f384866108ae565b8690610541565b90506102068182610556565b9150935093915050565b6000807f0000000000000000000000000000000000000000000000000000000000000000610288610261857f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b61029291906108d4565b905060008112156102a5576102a56108fc565b92915050565b60008542106102cd576040516305a29e1160e51b815260040160405180910390fd5b60006102d983856108ae565b905060006102f1826102eb89896108ae565b90610541565b9050670de0b6b3a764000081111561031c576040516386a8c2bd60e01b815260040160405180910390fd5b6000610328878461035a565b905061034d610337428b6108c1565b6301e133806103468486610556565b9190610522565b9998505050505050505050565b600061036f83670de0b6b3a764000084610522565b9392505050565b600080821361038457600080fd5b6000606061039184610771565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b82820281151584158583048514171661053a57600080fd5b0492915050565b600061036f83670de0b6b3a7640000846107ea565b600080610583847f00000000000000000000000000000000000000000000000000000000000000006108c1565b9050600061059185856108c1565b905060007f00000000000000000000000000000000000000000000000000000000000000006602aa1efb94e0006105c8848661035a565b106106395761063461060c610607610600897f00000000000000000000000000000000000000000000000000000000000000006108c1565b879061035a565b610376565b7f00000000000000000000000000000000000000000000000000000000000000009085610522565b61074b565b600661068f610668887f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b610703673782dace9d90000060026106a78c8c6108ae565b6106b19190610912565b6106db907f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009190610522565b61072d7f00000000000000000000000000000000000000000000000000000000000000008861035a565b61073791906108ae565b61074191906108ae565b61074b9190610912565b61075591906108d4565b90506000811215610768576107686108fc565b95945050505050565b600080821161077f57600080fd5b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b82820281151584158583048514171661080257600080fd5b6001826001830304018115150290509392505050565b60008060006060848603121561082d57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561085657600080fd5b5035919050565b600080600080600060a0868803121561087557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156102a5576102a5610898565b818103818111156102a5576102a5610898565b80820182811260008312801582168215821617156108f4576108f4610898565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60008261092f57634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220521e1b7f74e9ccd053b72c6e1e94aea0b237e099ed748044febdbfe6e05d6c4564736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c806384a874661161006657806384a8746614610148578063b99699341461015b578063d837268514610182578063df635f3d146101a9578063dfb08e10146101bc57600080fd5b80630481520b1461009857806326980121146100d25780634d6fc522146100f957806362caa04914610120575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b61013361012e366004610818565b6101e3565b604080519283526020830191909152016100c9565b6100bf610156366004610844565b610210565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf6101b736600461085d565b6102ab565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6000806101fa6101f384866108ae565b8690610541565b90506102068182610556565b9150935093915050565b6000807f0000000000000000000000000000000000000000000000000000000000000000610288610261857f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b61029291906108d4565b905060008112156102a5576102a56108fc565b92915050565b60008542106102cd576040516305a29e1160e51b815260040160405180910390fd5b60006102d983856108ae565b905060006102f1826102eb89896108ae565b90610541565b9050670de0b6b3a764000081111561031c576040516386a8c2bd60e01b815260040160405180910390fd5b6000610328878461035a565b905061034d610337428b6108c1565b6301e133806103468486610556565b9190610522565b9998505050505050505050565b600061036f83670de0b6b3a764000084610522565b9392505050565b600080821361038457600080fd5b6000606061039184610771565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b82820281151584158583048514171661053a57600080fd5b0492915050565b600061036f83670de0b6b3a7640000846107ea565b600080610583847f00000000000000000000000000000000000000000000000000000000000000006108c1565b9050600061059185856108c1565b905060007f00000000000000000000000000000000000000000000000000000000000000006602aa1efb94e0006105c8848661035a565b106106395761063461060c610607610600897f00000000000000000000000000000000000000000000000000000000000000006108c1565b879061035a565b610376565b7f00000000000000000000000000000000000000000000000000000000000000009085610522565b61074b565b600661068f610668887f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b610703673782dace9d90000060026106a78c8c6108ae565b6106b19190610912565b6106db907f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009190610522565b61072d7f00000000000000000000000000000000000000000000000000000000000000008861035a565b61073791906108ae565b61074191906108ae565b61074b9190610912565b61075591906108d4565b90506000811215610768576107686108fc565b95945050505050565b600080821161077f57600080fd5b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b82820281151584158583048514171661080257600080fd5b6001826001830304018115150290509392505050565b60008060006060848603121561082d57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561085657600080fd5b5035919050565b600080600080600060a0868803121561087557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156102a5576102a5610898565b818103818111156102a5576102a5610898565b80820182811260008312801582168215821617156108f4576108f4610898565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60008261092f57634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220521e1b7f74e9ccd053b72c6e1e94aea0b237e099ed748044febdbfe6e05d6c4564736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { @@ -278,7 +278,8 @@ "supplied": "deposits in the fixed rate pool." }, "returns": { - "rate": "of the fee that the borrower will have to pay and current utilization." + "rate": "of the fee that the borrower will have to pay, with 18 decimals precision.", + "utilization": "current utilization rate, with 18 decimals precision." } } }, @@ -317,7 +318,7 @@ "notice": "Returns the interest rate for an utilization rate." }, "minFixedRate(uint256,uint256,uint256)": { - "notice": "Gets the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and assets from the backup supplier." + "notice": "Returns the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and assets from the backup supplier." } }, "version": 1