ETH Price: $3,568.15 (+2.57%)

Contract

0x60D92e570D096f8E5C99A600bD130d71295AaF38
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
0x61014060995945622023-05-18 19:36:23398 days ago1684438583IN
 Create: InterestRateModel
0 ETH0.000000590.001

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
1060920992023-06-26 12:36:15359 days ago1687782975
0x60D92e57...1295AaF38
0 ETH
1060915972023-06-26 12:19:31359 days ago1687781971
0x60D92e57...1295AaF38
0 ETH
1060867932023-06-26 9:39:23359 days ago1687772363
0x60D92e57...1295AaF38
0 ETH
1060867932023-06-26 9:39:23359 days ago1687772363
0x60D92e57...1295AaF38
0 ETH
1060852902023-06-26 8:49:17359 days ago1687769357
0x60D92e57...1295AaF38
0 ETH
1060851972023-06-26 8:46:11359 days ago1687769171
0x60D92e57...1295AaF38
0 ETH
1060596182023-06-25 18:33:33360 days ago1687718013
0x60D92e57...1295AaF38
0 ETH
1060596182023-06-25 18:33:33360 days ago1687718013
0x60D92e57...1295AaF38
0 ETH
1060596182023-06-25 18:33:33360 days ago1687718013
0x60D92e57...1295AaF38
0 ETH
1060595592023-06-25 18:31:35360 days ago1687717895
0x60D92e57...1295AaF38
0 ETH
1060595592023-06-25 18:31:35360 days ago1687717895
0x60D92e57...1295AaF38
0 ETH
1060595592023-06-25 18:31:35360 days ago1687717895
0x60D92e57...1295AaF38
0 ETH
1060568982023-06-25 17:02:53360 days ago1687712573
0x60D92e57...1295AaF38
0 ETH
1060568162023-06-25 17:00:09360 days ago1687712409
0x60D92e57...1295AaF38
0 ETH
1060568162023-06-25 17:00:09360 days ago1687712409
0x60D92e57...1295AaF38
0 ETH
1060170252023-06-24 18:53:47361 days ago1687632827
0x60D92e57...1295AaF38
0 ETH
1060162962023-06-24 18:29:29361 days ago1687631369
0x60D92e57...1295AaF38
0 ETH
1060162962023-06-24 18:29:29361 days ago1687631369
0x60D92e57...1295AaF38
0 ETH
1059419292023-06-23 1:10:35362 days ago1687482635
0x60D92e57...1295AaF38
0 ETH
1059418722023-06-23 1:08:41362 days ago1687482521
0x60D92e57...1295AaF38
0 ETH
1059418722023-06-23 1:08:41362 days ago1687482521
0x60D92e57...1295AaF38
0 ETH
1058988392023-06-22 1:14:15363 days ago1687396455
0x60D92e57...1295AaF38
0 ETH
1058966932023-06-22 0:02:43363 days ago1687392163
0x60D92e57...1295AaF38
0 ETH
1058931562023-06-21 22:04:49364 days ago1687385089
0x60D92e57...1295AaF38
0 ETH
1058761922023-06-21 12:39:21364 days ago1687351161
0x60D92e57...1295AaF38
0 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
InterestRateModel

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 3 : InterestRateModel.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;

import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { FixedPointMathLib } from "solmate/src/utils/FixedPointMathLib.sol";

contract InterestRateModel {
  using FixedPointMathLib for uint256;
  using FixedPointMathLib for int256;

  /// @notice Threshold to define which method should be used to calculate the interest rates.
  /// @dev When `eta` (`delta / alpha`) is lower than this value, use simpson's rule for approximation.
  uint256 internal constant PRECISION_THRESHOLD = 7.5e14;

  /// @notice Scale factor of the fixed curve.
  uint256 public immutable fixedCurveA;
  /// @notice Origin intercept of the fixed curve.
  int256 public immutable fixedCurveB;
  /// @notice Asymptote of the fixed curve.
  uint256 public immutable fixedMaxUtilization;

  /// @notice Scale factor of the floating curve.
  uint256 public immutable floatingCurveA;
  /// @notice Origin intercept of the floating curve.
  int256 public immutable floatingCurveB;
  /// @notice Asymptote of the floating curve.
  uint256 public immutable floatingMaxUtilization;

  constructor(
    uint256 fixedCurveA_,
    int256 fixedCurveB_,
    uint256 fixedMaxUtilization_,
    uint256 floatingCurveA_,
    int256 floatingCurveB_,
    uint256 floatingMaxUtilization_
  ) {
    assert(fixedMaxUtilization_ > 1e18);
    assert(floatingMaxUtilization_ > 1e18);

    fixedCurveA = fixedCurveA_;
    fixedCurveB = fixedCurveB_;
    fixedMaxUtilization = fixedMaxUtilization_;

    floatingCurveA = floatingCurveA_;
    floatingCurveB = floatingCurveB_;
    floatingMaxUtilization = floatingMaxUtilization_;

    // reverts if it's an invalid curve (such as one yielding a negative interest rate).
    fixedRate(0, 0);
    floatingRate(0);
  }

  /// @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.
  /// @param maturity maturity date for calculating days left to maturity.
  /// @param amount the current borrow's amount.
  /// @param borrowed ex-ante amount borrowed from this fixed rate pool.
  /// @param supplied deposits in the fixed rate pool.
  /// @param backupAssets backup supplier assets.
  /// @return rate of the fee that the borrower will have to pay (represented with 18 decimals).
  function fixedBorrowRate(
    uint256 maturity,
    uint256 amount,
    uint256 borrowed,
    uint256 supplied,
    uint256 backupAssets
  ) external view returns (uint256) {
    if (block.timestamp >= maturity) revert AlreadyMatured();

    uint256 potentialAssets = supplied + backupAssets;
    uint256 utilizationAfter = (borrowed + amount).divWadUp(potentialAssets);

    if (utilizationAfter > 1e18) revert UtilizationExceeded();

    uint256 utilizationBefore = borrowed.divWadDown(potentialAssets);

    return fixedRate(utilizationBefore, utilizationAfter).mulDivDown(maturity - block.timestamp, 365 days);
  }

  /// @notice Returns the current annualized fixed rate to borrow with supply/demand values in the fixed rate pool and
  /// assets from the backup supplier.
  /// @param borrowed amount borrowed from the fixed rate pool.
  /// @param supplied deposits in the fixed rate pool.
  /// @param backupAssets backup supplier assets.
  /// @return rate of the fee that the borrower will have to pay, with 18 decimals precision.
  /// @return utilization current utilization rate, with 18 decimals precision.
  function minFixedRate(
    uint256 borrowed,
    uint256 supplied,
    uint256 backupAssets
  ) external view returns (uint256 rate, uint256 utilization) {
    utilization = borrowed.divWadUp(supplied + backupAssets);
    rate = fixedRate(utilization, utilization);
  }

  /// @notice Returns the interest rate integral from `u0` to `u1`, using the analytical solution (ln).
  /// @dev Uses the fixed rate curve parameters.
  /// Handles special case where delta utilization tends to zero, using simpson's rule.
  /// @param utilizationBefore ex-ante utilization rate, with 18 decimals precision.
  /// @param utilizationAfter ex-post utilization rate, with 18 decimals precision.
  /// @return the interest rate, with 18 decimals precision.
  function fixedRate(uint256 utilizationBefore, uint256 utilizationAfter) internal view returns (uint256) {
    uint256 alpha = fixedMaxUtilization - utilizationBefore;
    uint256 delta = utilizationAfter - utilizationBefore;
    int256 r = int256(
      delta.divWadDown(alpha) < PRECISION_THRESHOLD
        ? (fixedCurveA.divWadDown(alpha) +
          fixedCurveA.mulDivDown(4e18, fixedMaxUtilization - ((utilizationAfter + utilizationBefore) / 2)) +
          fixedCurveA.divWadDown(fixedMaxUtilization - utilizationAfter)) / 6
        : fixedCurveA.mulDivDown(
          uint256(int256(alpha.divWadDown(fixedMaxUtilization - utilizationAfter)).lnWad()),
          delta
        )
    ) + fixedCurveB;
    assert(r >= 0);
    return uint256(r);
  }

  /// @notice Returns the interest rate for an utilization rate.
  /// @dev Uses the floating rate curve parameters.
  /// @param utilization utilization rate, with 18 decimals precision.
  /// @return the interest rate, with 18 decimals precision.
  function floatingRate(uint256 utilization) public view returns (uint256) {
    int256 r = int256(floatingCurveA.divWadDown(floatingMaxUtilization - utilization)) + floatingCurveB;
    assert(r >= 0);
    return uint256(r);
  }
}

error AlreadyMatured();
error UtilizationExceeded();

File 2 of 3 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

File 3 of 3 : FixedPointMathLib.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    function powWad(int256 x, int256 y) internal pure returns (int256) {
        // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)
        return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.
    }

    function expWad(int256 x) internal pure returns (int256 r) {
        unchecked {
            // When the result is < 0.5 we return zero. This happens when
            // x <= floor(log(0.5e18) * 1e18) ~ -42e18
            if (x <= -42139678854452767551) return 0;

            // When the result is > (2**255 - 1) / 1e18 we can not represent it as an
            // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.
            if (x >= 135305999368893231589) revert("EXP_OVERFLOW");

            // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96
            // for more intermediate precision and a binary basis. This base conversion
            // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
            x = (x << 78) / 5**18;

            // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers
            // of two such that exp(x) = exp(x') * 2**k, where k is an integer.
            // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
            int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;
            x = x - k * 54916777467707473351141471128;

            // k is in the range [-61, 195].

            // Evaluate using a (6, 7)-term rational approximation.
            // p is made monic, we'll multiply by a scale factor later.
            int256 y = x + 1346386616545796478920950773328;
            y = ((y * x) >> 96) + 57155421227552351082224309758442;
            int256 p = y + x - 94201549194550492254356042504812;
            p = ((p * y) >> 96) + 28719021644029726153956944680412240;
            p = p * x + (4385272521454847904659076985693276 << 96);

            // We leave p in 2**192 basis so we don't need to scale it back up for the division.
            int256 q = x - 2855989394907223263936484059900;
            q = ((q * x) >> 96) + 50020603652535783019961831881945;
            q = ((q * x) >> 96) - 533845033583426703283633433725380;
            q = ((q * x) >> 96) + 3604857256930695427073651918091429;
            q = ((q * x) >> 96) - 14423608567350463180887372962807573;
            q = ((q * x) >> 96) + 26449188498355588339934803723976023;

            assembly {
                // Div in assembly because solidity adds a zero check despite the unchecked.
                // The q polynomial won't have zeros in the domain as all its roots are complex.
                // No scaling is necessary because p is already 2**96 too large.
                r := sdiv(p, q)
            }

            // r should be in the range (0.09, 0.25) * 2**96.

            // We now need to multiply r by:
            // * the scale factor s = ~6.031367120.
            // * the 2**k factor from the range reduction.
            // * the 1e18 / 2**96 factor for base conversion.
            // We do this all at once, with an intermediate result in 2**213
            // basis, so the final right shift is always by a positive amount.
            r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));
        }
    }

    function lnWad(int256 x) internal pure returns (int256 r) {
        unchecked {
            require(x > 0, "UNDEFINED");

            // We want to convert x from 10**18 fixed point to 2**96 fixed point.
            // We do this by multiplying by 2**96 / 10**18. But since
            // ln(x * C) = ln(x) + ln(C), we can simply do nothing here
            // and add ln(2**96 / 10**18) at the end.

            // Reduce range of x to (1, 2) * 2**96
            // ln(2^k * x) = k * ln(2) + ln(x)
            int256 k = int256(log2(uint256(x))) - 96;
            x <<= uint256(159 - k);
            x = int256(uint256(x) >> 159);

            // Evaluate using a (8, 8)-term rational approximation.
            // p is made monic, we will multiply by a scale factor later.
            int256 p = x + 3273285459638523848632254066296;
            p = ((p * x) >> 96) + 24828157081833163892658089445524;
            p = ((p * x) >> 96) + 43456485725739037958740375743393;
            p = ((p * x) >> 96) - 11111509109440967052023855526967;
            p = ((p * x) >> 96) - 45023709667254063763336534515857;
            p = ((p * x) >> 96) - 14706773417378608786704636184526;
            p = p * x - (795164235651350426258249787498 << 96);

            // We leave p in 2**192 basis so we don't need to scale it back up for the division.
            // q is monic by convention.
            int256 q = x + 5573035233440673466300451813936;
            q = ((q * x) >> 96) + 71694874799317883764090561454958;
            q = ((q * x) >> 96) + 283447036172924575727196451306956;
            q = ((q * x) >> 96) + 401686690394027663651624208769553;
            q = ((q * x) >> 96) + 204048457590392012362485061816622;
            q = ((q * x) >> 96) + 31853899698501571402653359427138;
            q = ((q * x) >> 96) + 909429971244387300277376558375;
            assembly {
                // Div in assembly because solidity adds a zero check despite the unchecked.
                // The q polynomial is known not to have zeros in the domain.
                // No scaling required because p is already 2**96 too large.
                r := sdiv(p, q)
            }

            // r is in the range (0, 0.125) * 2**96

            // Finalization, we need to:
            // * multiply by the scale factor s = 5.549…
            // * add ln(2**96 / 10**18)
            // * add k * ln(2)
            // * multiply by 10**18 / 2**96 = 5**18 >> 78

            // mul s * 5e18 * 2**96, base is now 5**18 * 2**192
            r *= 1677202110996718588342820967067443963516166;
            // add ln(2) * k * 5e18 * 2**192
            r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;
            // add ln(2**96 / 10**18) * 5e18 * 2**192
            r += 600920179829731861736702779321621459595472258049074101567377883020018308;
            // base conversion: mul 2**18 / 2**192
            r >>= 174;
        }
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        assembly {
            let y := x // We start y at x, which will help us make our initial estimate.

            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // We check y >= 2^(k + 8) but shift right by k bits
            // each branch to ensure that if x >= 256, then y >= 256.
            if iszero(lt(y, 0x10000000000000000000000000000000000)) {
                y := shr(128, y)
                z := shl(64, z)
            }
            if iszero(lt(y, 0x1000000000000000000)) {
                y := shr(64, y)
                z := shl(32, z)
            }
            if iszero(lt(y, 0x10000000000)) {
                y := shr(32, y)
                z := shl(16, z)
            }
            if iszero(lt(y, 0x1000000)) {
                y := shr(16, y)
                z := shl(8, z)
            }

            // Goal was to get z*z*y within a small factor of x. More iterations could
            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).
            // We ensured y >= 256 so that the relative difference between y and y+1 is small.
            // That's not possible if x < 256 but we can just verify those cases exhaustively.

            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.

            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.

            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.

            // There is no overflow risk here since y < 2^136 after the first branch above.
            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // If x+1 is a perfect square, the Babylonian method cycles between
            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.
            z := sub(z, lt(div(x, z), z))
        }
    }

    function log2(uint256 x) internal pure returns (uint256 r) {
        require(x > 0, "UNDEFINED");

        assembly {
            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            r := or(r, shl(2, lt(0xf, shr(r, x))))
            r := or(r, shl(1, lt(0x3, shr(r, x))))
            r := or(r, lt(0x1, shr(r, x)))
        }
    }

    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
        assembly {
            // z will equal 0 if y is 0, unlike in Solidity where it will revert.
            z := mod(x, y)
        }
    }

    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
        assembly {
            // z will equal 0 if y is 0, unlike in Solidity where it will revert.
            z := div(x, y)
        }
    }

    /// @dev Will return 0 instead of reverting if y is zero.
    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
        assembly {
            // Add 1 to x * y if x % y > 0.
            z := add(gt(mod(x, y), 0), div(x, y))
        }
    }
}

Settings
{
  "debug": {
    "revertStrings": "strip"
  },
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract 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"}]

6101406040523480156200001257600080fd5b5060405162000ff338038062000ff38339810160408190526200003591620004f7565b670de0b6b3a764000084116200004f576200004f62000542565b670de0b6b3a7640000811162000069576200006962000542565b608086905260a085905260c084905260e083905261010082905261012081905262000096600080620000b0565b50620000a360006200024b565b50505050505050620005e8565b6000808360c051620000c391906200056e565b90506000620000d385856200056e565b9050600060a0516602aa1efb94e000620000fc8585620002a060201b6200035a1790919060201c565b1062000163576200015d62000144620001338860c0516200011e91906200056e565b87620002a060201b6200035a1790919060201c565b620002be60201b620003761760201c565b846080516200046760201b62000522179092919060201c565b6200021e565b6006620001908760c0516200017991906200056e565b608051620002a060201b6200035a1790919060201c565b620001de673782dace9d9000006002620001ab8c8c62000584565b620001b791906200059a565b60c051620001c691906200056e565b6080516200046760201b62000522179092919060201c565b620001fa87608051620002a060201b6200035a1790919060201c565b62000206919062000584565b62000212919062000584565b6200021e91906200059a565b6200022a9190620005bd565b9050600081121562000240576200024062000542565b925050505b92915050565b600080610100516200027e84610120516200026791906200056e565b60e051620002a060201b6200035a1790919060201c565b6200028a9190620005bd565b9050600081121562000245576200024562000542565b6000620002b783670de0b6b3a76400008462000467565b9392505050565b6000808213620002cd57600080fd5b60006060620002dc8462000487565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd190190910260016c0504a838426634cdd8738f543560611b03190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b8282028115158415858304851417166200048057600080fd5b0492915050565b60008082116200049657600080fd5b5060016001600160801b03821160071b82811c6001600160401b031060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60008060008060008060c087890312156200051157600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111562000245576200024562000558565b8082018082111562000245576200024562000558565b600082620005b857634e487b7160e01b600052601260045260246000fd5b500490565b8082018281126000831280158216821582161715620005e057620005e062000558565b505092915050565b60805160a05160c05160e051610100516101205161096a6200068960003960008181610187015261023d01526000818160d701526102150152600081816101600152610263015260008181609d0152818161055f015281816105dc0152818161064401526106b70152600081816101c1015261059701526000818160fe0152818161060e0152818161066a015281816106dd0152610708015261096a6000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c806384a874661161006657806384a8746614610148578063b99699341461015b578063d837268514610182578063df635f3d146101a9578063dfb08e10146101bc57600080fd5b80630481520b1461009857806326980121146100d25780634d6fc522146100f957806362caa04914610120575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b61013361012e366004610818565b6101e3565b604080519283526020830191909152016100c9565b6100bf610156366004610844565b610210565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6100bf6101b736600461085d565b6102ab565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6000806101fa6101f384866108ae565b8690610541565b90506102068182610556565b9150935093915050565b6000807f0000000000000000000000000000000000000000000000000000000000000000610288610261857f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b61029291906108d4565b905060008112156102a5576102a56108fc565b92915050565b60008542106102cd576040516305a29e1160e51b815260040160405180910390fd5b60006102d983856108ae565b905060006102f1826102eb89896108ae565b90610541565b9050670de0b6b3a764000081111561031c576040516386a8c2bd60e01b815260040160405180910390fd5b6000610328878461035a565b905061034d610337428b6108c1565b6301e133806103468486610556565b9190610522565b9998505050505050505050565b600061036f83670de0b6b3a764000084610522565b9392505050565b600080821361038457600080fd5b6000606061039184610771565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b82820281151584158583048514171661053a57600080fd5b0492915050565b600061036f83670de0b6b3a7640000846107ea565b600080610583847f00000000000000000000000000000000000000000000000000000000000000006108c1565b9050600061059185856108c1565b905060007f00000000000000000000000000000000000000000000000000000000000000006602aa1efb94e0006105c8848661035a565b106106395761063461060c610607610600897f00000000000000000000000000000000000000000000000000000000000000006108c1565b879061035a565b610376565b7f00000000000000000000000000000000000000000000000000000000000000009085610522565b61074b565b600661068f610668887f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009061035a565b610703673782dace9d90000060026106a78c8c6108ae565b6106b19190610912565b6106db907f00000000000000000000000000000000000000000000000000000000000000006108c1565b7f00000000000000000000000000000000000000000000000000000000000000009190610522565b61072d7f00000000000000000000000000000000000000000000000000000000000000008861035a565b61073791906108ae565b61074191906108ae565b61074b9190610912565b61075591906108d4565b90506000811215610768576107686108fc565b95945050505050565b600080821161077f57600080fd5b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b82820281151584158583048514171661080257600080fd5b6001826001830304018115150290509392505050565b60008060006060848603121561082d57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561085657600080fd5b5035919050565b600080600080600060a0868803121561087557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156102a5576102a5610898565b818103818111156102a5576102a5610898565b80820182811260008312801582168215821617156108f4576108f4610898565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60008261092f57634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220c1b4fad199c346793d66c3995e10c3afc8853cdb8646e7deb595c71f73886de964736f6c63430008110033000000000000000000000000000000000000000000000000054a81f33310c000fffffffffffffffffffffffffffffffffffffffffffffffffaf3b34d5ef3a0000000000000000000000000000000000000000000000000000de0c06dc71106000000000000000000000000000000000000000000000000000044c9a2ec242000fffffffffffffffffffffffffffffffffffffffffffffffffff9a6bba3c950000000000000000000000000000000000000000000000000000dee774ebc451e00

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100935760003560e01c806384a874661161006657806384a8746614610148578063b99699341461015b578063d837268514610182578063df635f3d146101a9578063dfb08e10146101bc57600080fd5b80630481520b1461009857806326980121146100d25780634d6fc522146100f957806362caa04914610120575b600080fd5b6100bf7f0000000000000000000000000000000000000000000000000de0c06dc711060081565b6040519081526020015b60405180910390f35b6100bf7ffffffffffffffffffffffffffffffffffffffffffffffffffff9a6bba3c9500081565b6100bf7f000000000000000000000000000000000000000000000000054a81f33310c00081565b61013361012e366004610818565b6101e3565b604080519283526020830191909152016100c9565b6100bf610156366004610844565b610210565b6100bf7f0000000000000000000000000000000000000000000000000044c9a2ec24200081565b6100bf7f0000000000000000000000000000000000000000000000000dee774ebc451e0081565b6100bf6101b736600461085d565b6102ab565b6100bf7ffffffffffffffffffffffffffffffffffffffffffffffffffaf3b34d5ef3a00081565b6000806101fa6101f384866108ae565b8690610541565b90506102068182610556565b9150935093915050565b6000807ffffffffffffffffffffffffffffffffffffffffffffffffffff9a6bba3c95000610288610261857f0000000000000000000000000000000000000000000000000dee774ebc451e006108c1565b7f0000000000000000000000000000000000000000000000000044c9a2ec2420009061035a565b61029291906108d4565b905060008112156102a5576102a56108fc565b92915050565b60008542106102cd576040516305a29e1160e51b815260040160405180910390fd5b60006102d983856108ae565b905060006102f1826102eb89896108ae565b90610541565b9050670de0b6b3a764000081111561031c576040516386a8c2bd60e01b815260040160405180910390fd5b6000610328878461035a565b905061034d610337428b6108c1565b6301e133806103468486610556565b9190610522565b9998505050505050505050565b600061036f83670de0b6b3a764000084610522565b9392505050565b600080821361038457600080fd5b6000606061039184610771565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d6c8c3f38e95a6b1ff2ab1c3b343619018302821d6d02384773bdf1ac5676facced60901901830290911d6cb9a025d814b29c212b8b1a07cd1901909102780a09507084cc699bb0e71ea869ffffffffffffffffffffffff190105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b82820281151584158583048514171661053a57600080fd5b0492915050565b600061036f83670de0b6b3a7640000846107ea565b600080610583847f0000000000000000000000000000000000000000000000000de0c06dc71106006108c1565b9050600061059185856108c1565b905060007ffffffffffffffffffffffffffffffffffffffffffffffffffaf3b34d5ef3a0006602aa1efb94e0006105c8848661035a565b106106395761063461060c610607610600897f0000000000000000000000000000000000000000000000000de0c06dc71106006108c1565b879061035a565b610376565b7f000000000000000000000000000000000000000000000000054a81f33310c0009085610522565b61074b565b600661068f610668887f0000000000000000000000000000000000000000000000000de0c06dc71106006108c1565b7f000000000000000000000000000000000000000000000000054a81f33310c0009061035a565b610703673782dace9d90000060026106a78c8c6108ae565b6106b19190610912565b6106db907f0000000000000000000000000000000000000000000000000de0c06dc71106006108c1565b7f000000000000000000000000000000000000000000000000054a81f33310c0009190610522565b61072d7f000000000000000000000000000000000000000000000000054a81f33310c0008861035a565b61073791906108ae565b61074191906108ae565b61074b9190610912565b61075591906108d4565b90506000811215610768576107686108fc565b95945050505050565b600080821161077f57600080fd5b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b82820281151584158583048514171661080257600080fd5b6001826001830304018115150290509392505050565b60008060006060848603121561082d57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561085657600080fd5b5035919050565b600080600080600060a0868803121561087557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156102a5576102a5610898565b818103818111156102a5576102a5610898565b80820182811260008312801582168215821617156108f4576108f4610898565b505092915050565b634e487b7160e01b600052600160045260246000fd5b60008261092f57634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220c1b4fad199c346793d66c3995e10c3afc8853cdb8646e7deb595c71f73886de964736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000054a81f33310c000fffffffffffffffffffffffffffffffffffffffffffffffffaf3b34d5ef3a0000000000000000000000000000000000000000000000000000de0c06dc71106000000000000000000000000000000000000000000000000000044c9a2ec242000fffffffffffffffffffffffffffffffffffffffffffffffffff9a6bba3c950000000000000000000000000000000000000000000000000000dee774ebc451e00

-----Decoded View---------------
Arg [0] : fixedCurveA_ (uint256): 381260000000000000
Arg [1] : fixedCurveB_ (int256): -363750000000000000
Arg [2] : fixedMaxUtilization_ (uint256): 1000010695000000000
Arg [3] : floatingCurveA_ (uint256): 19362000000000000
Arg [4] : floatingCurveB_ (int256): -1787000000000000
Arg [5] : floatingMaxUtilization_ (uint256): 1003870947000000000

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000054a81f33310c000
Arg [1] : fffffffffffffffffffffffffffffffffffffffffffffffffaf3b34d5ef3a000
Arg [2] : 0000000000000000000000000000000000000000000000000de0c06dc7110600
Arg [3] : 0000000000000000000000000000000000000000000000000044c9a2ec242000
Arg [4] : fffffffffffffffffffffffffffffffffffffffffffffffffff9a6bba3c95000
Arg [5] : 0000000000000000000000000000000000000000000000000dee774ebc451e00


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.