Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 4 from a total of 4 transactions
Latest 4 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60a06040 | 20822373 | 532 days ago | Contract Creation | 0 ETH | |||
| 0x60a06040 | 20422344 | 588 days ago | Contract Creation | 0 ETH | |||
| 0x60a06040 | 20421822 | 588 days ago | Contract Creation | 0 ETH | |||
| 0x60a06040 | 20421784 | 588 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
CurveOracleFactory
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BlueOak-1.0.0
pragma solidity 0.8.19;
import { divuu } from "../../libraries/Fixed.sol";
// weird circular inheritance preventing us from using proper IRToken, not worth figuring out
interface IRToken {
function basketsNeeded() external view returns (uint192);
function totalSupply() external view returns (uint256);
}
contract CurveOracle {
IRToken public immutable rToken;
constructor(IRToken _rToken) {
rToken = _rToken;
}
function exchangeRate() external view returns (uint256) {
return divuu(uint256(rToken.basketsNeeded()), rToken.totalSupply());
}
}
/**
* @title CurveOracleFactory
* @notice An immutable factory for Curve oracles
*/
contract CurveOracleFactory {
error CurveOracleAlreadyDeployed();
event CurveOracleDeployed(address indexed rToken, address indexed curveOracle);
mapping(IRToken => CurveOracle) public curveOracles;
function deployCurveOracle(IRToken rToken) external returns (address) {
if (address(curveOracles[rToken]) != address(0)) revert CurveOracleAlreadyDeployed();
CurveOracle curveOracle = new CurveOracle(rToken);
curveOracle.exchangeRate(); // ensure it works
curveOracles[rToken] = curveOracle;
emit CurveOracleDeployed(address(rToken), address(curveOracle));
return address(curveOracle);
}
}// SPDX-License-Identifier: BlueOak-1.0.0
// solhint-disable func-name-mixedcase func-visibility
// slither-disable-start divide-before-multiply
pragma solidity ^0.8.19;
/// @title FixedPoint, a fixed-point arithmetic library defining the custom type uint192
/// @author Matt Elder <matt.elder@reserve.org> and the Reserve Team <https://reserve.org>
/** The logical type `uint192 ` is a 192 bit value, representing an 18-decimal Fixed-point
fractional value. This is what's described in the Solidity documentation as
"fixed192x18" -- a value represented by 192 bits, that makes 18 digits available to
the right of the decimal point.
The range of values that uint192 can represent is about [-1.7e20, 1.7e20].
Unless a function explicitly says otherwise, it will fail on overflow.
To be clear, the following should hold:
toFix(0) == 0
toFix(1) == 1e18
*/
// Analysis notes:
// Every function should revert iff its result is out of bounds.
// Unless otherwise noted, when a rounding mode is given, that mode is applied to
// a single division that may happen as the last step in the computation.
// Unless otherwise noted, when a rounding mode is *not* given but is needed, it's FLOOR.
// For each, we comment:
// - @return is the value expressed in "value space", where uint192(1e18) "is" 1.0
// - as-ints: is the value expressed in "implementation space", where uint192(1e18) "is" 1e18
// The "@return" expression is suitable for actually using the library
// The "as-ints" expression is suitable for testing
// A uint value passed to this library was out of bounds for uint192 operations
error UIntOutOfBounds();
bytes32 constant UIntOutofBoundsHash = keccak256(abi.encodeWithSignature("UIntOutOfBounds()"));
// Used by P1 implementation for easier casting
uint256 constant FIX_ONE_256 = 1e18;
uint8 constant FIX_DECIMALS = 18;
// If a particular uint192 is represented by the uint192 n, then the uint192 represents the
// value n/FIX_SCALE.
uint64 constant FIX_SCALE = 1e18;
// FIX_SCALE Squared:
uint128 constant FIX_SCALE_SQ = 1e36;
// The largest integer that can be converted to uint192 .
// This is a bit bigger than 3.1e39
uint192 constant FIX_MAX_INT = type(uint192).max / FIX_SCALE;
uint192 constant FIX_ZERO = 0; // The uint192 representation of zero.
uint192 constant FIX_ONE = FIX_SCALE; // The uint192 representation of one.
uint192 constant FIX_MAX = type(uint192).max; // The largest uint192. (Not an integer!)
uint192 constant FIX_MIN = 0; // The smallest uint192.
/// An enum that describes a rounding approach for converting to ints
enum RoundingMode {
FLOOR, // Round towards zero
ROUND, // Round to the nearest int
CEIL // Round away from zero
}
RoundingMode constant FLOOR = RoundingMode.FLOOR;
RoundingMode constant ROUND = RoundingMode.ROUND;
RoundingMode constant CEIL = RoundingMode.CEIL;
/* @dev Solidity 0.8.x only allows you to change one of type or size per type conversion.
Thus, all the tedious-looking double conversions like uint256(uint256 (foo))
See: https://docs.soliditylang.org/en/v0.8.17/080-breaking-changes.html#new-restrictions
*/
/// Explicitly convert a uint256 to a uint192. Revert if the input is out of bounds.
function _safeWrap(uint256 x) pure returns (uint192) {
if (FIX_MAX < x) revert UIntOutOfBounds();
return uint192(x);
}
/// Convert a uint to its Fix representation.
/// @return x
// as-ints: x * 1e18
function toFix(uint256 x) pure returns (uint192) {
return _safeWrap(x * FIX_SCALE);
}
/// Convert a uint to its fixed-point representation, and left-shift its value `shiftLeft`
/// decimal digits.
/// @return x * 10**shiftLeft
// as-ints: x * 10**(shiftLeft + 18)
function shiftl_toFix(uint256 x, int8 shiftLeft) pure returns (uint192) {
return shiftl_toFix(x, shiftLeft, FLOOR);
}
/// @return x * 10**shiftLeft
// as-ints: x * 10**(shiftLeft + 18)
function shiftl_toFix(
uint256 x,
int8 shiftLeft,
RoundingMode rounding
) pure returns (uint192) {
// conditions for avoiding overflow
if (x == 0) return 0;
if (shiftLeft <= -96) return (rounding == CEIL ? 1 : 0); // 0 < uint.max / 10**77 < 0.5
if (40 <= shiftLeft) revert UIntOutOfBounds(); // 10**56 < FIX_MAX < 10**57
shiftLeft += 18;
uint256 coeff = 10**abs(shiftLeft);
uint256 shifted = (shiftLeft >= 0) ? x * coeff : _divrnd(x, coeff, rounding);
return _safeWrap(shifted);
}
/// Divide a uint by a uint192, yielding a uint192
/// This may also fail if the result is MIN_uint192! not fixing this for optimization's sake.
/// @return x / y
// as-ints: x * 1e36 / y
function divFix(uint256 x, uint192 y) pure returns (uint192) {
// If we didn't have to worry about overflow, we'd just do `return x * 1e36 / _y`
// If it's safe to do this operation the easy way, do it:
if (x < uint256(type(uint256).max / FIX_SCALE_SQ)) {
return _safeWrap(uint256(x * FIX_SCALE_SQ) / y);
} else {
return _safeWrap(mulDiv256(x, FIX_SCALE_SQ, y));
}
}
/// Divide a uint by a uint, yielding a uint192
/// @return x / y
// as-ints: x * 1e18 / y
function divuu(uint256 x, uint256 y) pure returns (uint192) {
return _safeWrap(mulDiv256(FIX_SCALE, x, y));
}
/// @return min(x,y)
// as-ints: min(x,y)
function fixMin(uint192 x, uint192 y) pure returns (uint192) {
return x < y ? x : y;
}
/// @return max(x,y)
// as-ints: max(x,y)
function fixMax(uint192 x, uint192 y) pure returns (uint192) {
return x > y ? x : y;
}
/// @return absoluteValue(x,y)
// as-ints: absoluteValue(x,y)
function abs(int256 x) pure returns (uint256) {
return x < 0 ? uint256(-x) : uint256(x);
}
/// Divide two uints, returning a uint, using rounding mode `rounding`.
/// @return numerator / divisor
// as-ints: numerator / divisor
function _divrnd(
uint256 numerator,
uint256 divisor,
RoundingMode rounding
) pure returns (uint256) {
uint256 result = numerator / divisor;
if (rounding == FLOOR) return result;
if (rounding == ROUND) {
if (numerator % divisor > (divisor - 1) / 2) {
result++;
}
} else {
if (numerator % divisor != 0) {
result++;
}
}
return result;
}
library FixLib {
/// Again, all arithmetic functions fail if and only if the result is out of bounds.
/// Convert this fixed-point value to a uint. Round towards zero if needed.
/// @return x
// as-ints: x / 1e18
function toUint(uint192 x) internal pure returns (uint136) {
return toUint(x, FLOOR);
}
/// Convert this uint192 to a uint
/// @return x
// as-ints: x / 1e18 with rounding
function toUint(uint192 x, RoundingMode rounding) internal pure returns (uint136) {
return uint136(_divrnd(uint256(x), FIX_SCALE, rounding));
}
/// Return the uint192 shifted to the left by `decimal` digits
/// (Similar to a bitshift but in base 10)
/// @return x * 10**decimals
// as-ints: x * 10**decimals
function shiftl(uint192 x, int8 decimals) internal pure returns (uint192) {
return shiftl(x, decimals, FLOOR);
}
/// Return the uint192 shifted to the left by `decimal` digits
/// (Similar to a bitshift but in base 10)
/// @return x * 10**decimals
// as-ints: x * 10**decimals
function shiftl(
uint192 x,
int8 decimals,
RoundingMode rounding
) internal pure returns (uint192) {
// Handle overflow cases
if (x == 0) return 0;
if (decimals <= -59) return (rounding == CEIL ? 1 : 0); // 59, because 1e58 > 2**192
if (58 <= decimals) revert UIntOutOfBounds(); // 58, because x * 1e58 > 2 ** 192 if x != 0
uint256 coeff = uint256(10**abs(decimals));
return _safeWrap(decimals >= 0 ? x * coeff : _divrnd(x, coeff, rounding));
}
/// Add a uint192 to this uint192
/// @return x + y
// as-ints: x + y
function plus(uint192 x, uint192 y) internal pure returns (uint192) {
return x + y;
}
/// Add a uint to this uint192
/// @return x + y
// as-ints: x + y*1e18
function plusu(uint192 x, uint256 y) internal pure returns (uint192) {
return _safeWrap(x + y * FIX_SCALE);
}
/// Subtract a uint192 from this uint192
/// @return x - y
// as-ints: x - y
function minus(uint192 x, uint192 y) internal pure returns (uint192) {
return x - y;
}
/// Subtract a uint from this uint192
/// @return x - y
// as-ints: x - y*1e18
function minusu(uint192 x, uint256 y) internal pure returns (uint192) {
return _safeWrap(uint256(x) - uint256(y * FIX_SCALE));
}
/// Multiply this uint192 by a uint192
/// Round truncated values to the nearest available value. 5e-19 rounds away from zero.
/// @return x * y
// as-ints: x * y/1e18 [division using ROUND, not FLOOR]
function mul(uint192 x, uint192 y) internal pure returns (uint192) {
return mul(x, y, ROUND);
}
/// Multiply this uint192 by a uint192
/// @return x * y
// as-ints: x * y/1e18
function mul(
uint192 x,
uint192 y,
RoundingMode rounding
) internal pure returns (uint192) {
return _safeWrap(_divrnd(uint256(x) * uint256(y), FIX_SCALE, rounding));
}
/// Multiply this uint192 by a uint
/// @return x * y
// as-ints: x * y
function mulu(uint192 x, uint256 y) internal pure returns (uint192) {
return _safeWrap(x * y);
}
/// Divide this uint192 by a uint192
/// @return x / y
// as-ints: x * 1e18 / y
function div(uint192 x, uint192 y) internal pure returns (uint192) {
return div(x, y, FLOOR);
}
/// Divide this uint192 by a uint192
/// @return x / y
// as-ints: x * 1e18 / y
function div(
uint192 x,
uint192 y,
RoundingMode rounding
) internal pure returns (uint192) {
// Multiply-in FIX_SCALE before dividing by y to preserve precision.
return _safeWrap(_divrnd(uint256(x) * FIX_SCALE, y, rounding));
}
/// Divide this uint192 by a uint
/// @return x / y
// as-ints: x / y
function divu(uint192 x, uint256 y) internal pure returns (uint192) {
return divu(x, y, FLOOR);
}
/// Divide this uint192 by a uint
/// @return x / y
// as-ints: x / y
function divu(
uint192 x,
uint256 y,
RoundingMode rounding
) internal pure returns (uint192) {
return _safeWrap(_divrnd(x, y, rounding));
}
uint64 constant FIX_HALF = uint64(FIX_SCALE) / 2;
/// Raise this uint192 to a nonnegative integer power. Requires that x_ <= FIX_ONE
/// Gas cost is O(lg(y)), precision is +- 1e-18.
/// @return x_ ** y
// as-ints: x_ ** y / 1e18**(y-1) <- technically correct for y = 0. :D
function powu(uint192 x_, uint48 y) internal pure returns (uint192) {
require(x_ <= FIX_ONE);
if (y == 1) return x_;
if (x_ == FIX_ONE || y == 0) return FIX_ONE;
uint256 x = uint256(x_) * FIX_SCALE; // x is D36
uint256 result = FIX_SCALE_SQ; // result is D36
while (true) {
if (y & 1 == 1) result = (result * x + FIX_SCALE_SQ / 2) / FIX_SCALE_SQ;
if (y <= 1) break;
y = (y >> 1);
x = (x * x + FIX_SCALE_SQ / 2) / FIX_SCALE_SQ;
}
return _safeWrap(result / FIX_SCALE);
}
function sqrt(uint192 x) internal pure returns (uint192) {
return _safeWrap(sqrt256(x * FIX_ONE_256)); // FLOOR
}
/// Comparison operators...
function lt(uint192 x, uint192 y) internal pure returns (bool) {
return x < y;
}
function lte(uint192 x, uint192 y) internal pure returns (bool) {
return x <= y;
}
function gt(uint192 x, uint192 y) internal pure returns (bool) {
return x > y;
}
function gte(uint192 x, uint192 y) internal pure returns (bool) {
return x >= y;
}
function eq(uint192 x, uint192 y) internal pure returns (bool) {
return x == y;
}
function neq(uint192 x, uint192 y) internal pure returns (bool) {
return x != y;
}
/// Return whether or not this uint192 is less than epsilon away from y.
/// @return |x - y| < epsilon
// as-ints: |x - y| < epsilon
function near(
uint192 x,
uint192 y,
uint192 epsilon
) internal pure returns (bool) {
uint192 diff = x <= y ? y - x : x - y;
return diff < epsilon;
}
// ================ Chained Operations ================
// The operation foo_bar() always means:
// Do foo() followed by bar(), and overflow only if the _end_ result doesn't fit in an uint192
/// Shift this uint192 left by `decimals` digits, and convert to a uint
/// @return x * 10**decimals
// as-ints: x * 10**(decimals - 18)
function shiftl_toUint(uint192 x, int8 decimals) internal pure returns (uint256) {
return shiftl_toUint(x, decimals, FLOOR);
}
/// Shift this uint192 left by `decimals` digits, and convert to a uint.
/// @return x * 10**decimals
// as-ints: x * 10**(decimals - 18)
function shiftl_toUint(
uint192 x,
int8 decimals,
RoundingMode rounding
) internal pure returns (uint256) {
// Handle overflow cases
if (x == 0) return 0; // always computable, no matter what decimals is
if (decimals <= -42) return (rounding == CEIL ? 1 : 0);
if (96 <= decimals) revert UIntOutOfBounds();
decimals -= 18; // shift so that toUint happens at the same time.
uint256 coeff = uint256(10**abs(decimals));
return decimals >= 0 ? uint256(x * coeff) : uint256(_divrnd(x, coeff, rounding));
}
/// Multiply this uint192 by a uint, and output the result as a uint
/// @return x * y
// as-ints: x * y / 1e18
function mulu_toUint(uint192 x, uint256 y) internal pure returns (uint256) {
return mulDiv256(uint256(x), y, FIX_SCALE);
}
/// Multiply this uint192 by a uint, and output the result as a uint
/// @return x * y
// as-ints: x * y / 1e18
function mulu_toUint(
uint192 x,
uint256 y,
RoundingMode rounding
) internal pure returns (uint256) {
return mulDiv256(uint256(x), y, FIX_SCALE, rounding);
}
/// Multiply this uint192 by a uint192 and output the result as a uint
/// @return x * y
// as-ints: x * y / 1e36
function mul_toUint(uint192 x, uint192 y) internal pure returns (uint256) {
return mulDiv256(uint256(x), uint256(y), FIX_SCALE_SQ);
}
/// Multiply this uint192 by a uint192 and output the result as a uint
/// @return x * y
// as-ints: x * y / 1e36
function mul_toUint(
uint192 x,
uint192 y,
RoundingMode rounding
) internal pure returns (uint256) {
return mulDiv256(uint256(x), uint256(y), FIX_SCALE_SQ, rounding);
}
/// Compute x * y / z avoiding intermediate overflow
/// @dev Only use if you need to avoid overflow; costlier than x * y / z
/// @return x * y / z
// as-ints: x * y / z
function muluDivu(
uint192 x,
uint256 y,
uint256 z
) internal pure returns (uint192) {
return muluDivu(x, y, z, FLOOR);
}
/// Compute x * y / z, avoiding intermediate overflow
/// @dev Only use if you need to avoid overflow; costlier than x * y / z
/// @return x * y / z
// as-ints: x * y / z
function muluDivu(
uint192 x,
uint256 y,
uint256 z,
RoundingMode rounding
) internal pure returns (uint192) {
return _safeWrap(mulDiv256(x, y, z, rounding));
}
/// Compute x * y / z on Fixes, avoiding intermediate overflow
/// @dev Only use if you need to avoid overflow; costlier than x * y / z
/// @return x * y / z
// as-ints: x * y / z
function mulDiv(
uint192 x,
uint192 y,
uint192 z
) internal pure returns (uint192) {
return mulDiv(x, y, z, FLOOR);
}
/// Compute x * y / z on Fixes, avoiding intermediate overflow
/// @dev Only use if you need to avoid overflow; costlier than x * y / z
/// @return x * y / z
// as-ints: x * y / z
function mulDiv(
uint192 x,
uint192 y,
uint192 z,
RoundingMode rounding
) internal pure returns (uint192) {
return _safeWrap(mulDiv256(x, y, z, rounding));
}
// === safe*() ===
/// Multiply two fixes, rounding up to FIX_MAX and down to 0
/// @param a First param to multiply
/// @param b Second param to multiply
function safeMul(
uint192 a,
uint192 b,
RoundingMode rounding
) internal pure returns (uint192) {
// untestable:
// a will never = 0 here because of the check in _price()
if (a == 0 || b == 0) return 0;
// untestable:
// a = FIX_MAX iff b = 0
if (a == FIX_MAX || b == FIX_MAX) return FIX_MAX;
// return FIX_MAX instead of throwing overflow errors.
unchecked {
// p and mul *are* Fix values, so have 18 decimals (D18)
uint256 rawDelta = uint256(b) * a; // {D36} = {D18} * {D18}
// if we overflowed, then return FIX_MAX
if (rawDelta / b != a) return FIX_MAX;
uint256 shiftDelta = rawDelta;
// add in rounding
if (rounding == RoundingMode.ROUND) shiftDelta += (FIX_ONE / 2);
else if (rounding == RoundingMode.CEIL) shiftDelta += FIX_ONE - 1;
// untestable (here there be dragons):
// (below explanation is for the ROUND case, but it extends to the FLOOR/CEIL too)
// A) shiftDelta = rawDelta + (FIX_ONE / 2)
// shiftDelta overflows if:
// B) shiftDelta = MAX_UINT256 - FIX_ONE/2 + 1
// rawDelta + (FIX_ONE/2) = MAX_UINT256 - FIX_ONE/2 + 1
// b * a = MAX_UINT256 - FIX_ONE + 1
// therefore shiftDelta overflows if:
// C) b = (MAX_UINT256 - FIX_ONE + 1) / a
// MAX_UINT256 ~= 1e77 , FIX_MAX ~= 6e57 (6e20 difference in magnitude)
// a <= 1e21 (MAX_TARGET_AMT)
// a must be between 1e19 & 1e20 in order for b in (C) to be uint192,
// but a would have to be < 1e18 in order for (A) to overflow
if (shiftDelta < rawDelta) return FIX_MAX;
// return FIX_MAX if return result would truncate
if (shiftDelta / FIX_ONE > FIX_MAX) return FIX_MAX;
// return _div(rawDelta, FIX_ONE, rounding)
return uint192(shiftDelta / FIX_ONE); // {D18} = {D36} / {D18}
}
}
/// Divide two fixes, rounding up to FIX_MAX and down to 0
/// @param a Numerator
/// @param b Denominator
function safeDiv(
uint192 a,
uint192 b,
RoundingMode rounding
) internal pure returns (uint192) {
if (a == 0) return 0;
if (b == 0) return FIX_MAX;
uint256 raw = _divrnd(FIX_ONE_256 * a, uint256(b), rounding);
if (raw >= FIX_MAX) return FIX_MAX;
return uint192(raw); // don't need _safeWrap
}
/// Multiplies two fixes and divide by a third
/// @param a First to multiply
/// @param b Second to multiply
/// @param c Denominator
function safeMulDiv(
uint192 a,
uint192 b,
uint192 c,
RoundingMode rounding
) internal pure returns (uint192 result) {
if (a == 0 || b == 0) return 0;
if (a == FIX_MAX || b == FIX_MAX || c == 0) return FIX_MAX;
uint256 result_256;
unchecked {
(uint256 hi, uint256 lo) = fullMul(a, b);
if (hi >= c) return FIX_MAX;
uint256 mm = mulmod(a, b, c);
if (mm > lo) hi -= 1;
lo -= mm;
uint256 pow2 = c & (0 - c);
uint256 c_256 = uint256(c);
// Warning: Should not access c below this line
c_256 /= pow2;
lo /= pow2;
lo += hi * ((0 - pow2) / pow2 + 1);
uint256 r = 1;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
r *= 2 - c_256 * r;
result_256 = lo * r;
// Apply rounding
if (rounding == CEIL) {
if (mm != 0) result_256 += 1;
} else if (rounding == ROUND) {
if (mm > ((c_256 - 1) / 2)) result_256 += 1;
}
}
if (result_256 >= FIX_MAX) return FIX_MAX;
return uint192(result_256);
}
}
// ================ a couple pure-uint helpers================
// as-ints comments are omitted here, because they're the same as @return statements, because
// these are all pure uint functions
/// Return (x*y/z), avoiding intermediate overflow.
// Adapted from sources:
// https://medium.com/coinmonks/4db014e080b1, https://medium.com/wicketh/afa55870a65
// and quite a few of the other excellent "Mathemagic" posts from https://medium.com/wicketh
/// @dev Only use if you need to avoid overflow; costlier than x * y / z
/// @return result x * y / z
function mulDiv256(
uint256 x,
uint256 y,
uint256 z
) pure returns (uint256 result) {
unchecked {
(uint256 hi, uint256 lo) = fullMul(x, y);
if (hi >= z) revert UIntOutOfBounds();
uint256 mm = mulmod(x, y, z);
if (mm > lo) hi -= 1;
lo -= mm;
uint256 pow2 = z & (0 - z);
z /= pow2;
lo /= pow2;
lo += hi * ((0 - pow2) / pow2 + 1);
uint256 r = 1;
r *= 2 - z * r;
r *= 2 - z * r;
r *= 2 - z * r;
r *= 2 - z * r;
r *= 2 - z * r;
r *= 2 - z * r;
r *= 2 - z * r;
r *= 2 - z * r;
result = lo * r;
}
}
/// Return (x*y/z), avoiding intermediate overflow.
/// @dev Only use if you need to avoid overflow; costlier than x * y / z
/// @return x * y / z
function mulDiv256(
uint256 x,
uint256 y,
uint256 z,
RoundingMode rounding
) pure returns (uint256) {
uint256 result = mulDiv256(x, y, z);
if (rounding == FLOOR) return result;
uint256 mm = mulmod(x, y, z);
if (rounding == CEIL) {
if (mm != 0) result += 1;
} else {
if (mm > ((z - 1) / 2)) result += 1; // z should be z-1
}
return result;
}
/// Return (x*y) as a "virtual uint512" (lo, hi), representing (hi*2**256 + lo)
/// Adapted from sources:
/// https://medium.com/wicketh/27650fec525d, https://medium.com/coinmonks/4db014e080b1
/// @dev Intended to be internal to this library
/// @return hi (hi, lo) satisfies hi*(2**256) + lo == x * y
/// @return lo (paired with `hi`)
function fullMul(uint256 x, uint256 y) pure returns (uint256 hi, uint256 lo) {
unchecked {
uint256 mm = mulmod(x, y, uint256(0) - uint256(1));
lo = x * y;
hi = mm - lo;
if (mm < lo) hi -= 1;
}
}
// =============== from prbMath at commit 28055f6cd9a2367f9ad7ab6c8e01c9ac8e9acc61 ===============
/// @notice Calculates the square root of x using the Babylonian method.
///
/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
///
/// Notes:
/// - If x is not a perfect square, the result is rounded down.
/// - Credits to OpenZeppelin for the explanations in comments below.
///
/// @param x The uint256 number for which to calculate the square root.
/// @return result The result as a uint256.
function sqrt256(uint256 x) pure returns (uint256 result) {
if (x == 0) {
return 0;
}
// For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.
//
// We know that the "msb" (most significant bit) of x is a power of 2 such that we have:
//
// $$
// msb(x) <= x <= 2*msb(x)$
// $$
//
// We write $msb(x)$ as $2^k$, and we get:
//
// $$
// k = log_2(x)
// $$
//
// Thus, we can write the initial inequality as:
//
// $$
// 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\
// sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\
// 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}
// $$
//
// Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.
uint256 xAux = uint256(x);
result = 1;
if (xAux >= 2**128) {
xAux >>= 128;
result <<= 64;
}
if (xAux >= 2**64) {
xAux >>= 64;
result <<= 32;
}
if (xAux >= 2**32) {
xAux >>= 32;
result <<= 16;
}
if (xAux >= 2**16) {
xAux >>= 16;
result <<= 8;
}
if (xAux >= 2**8) {
xAux >>= 8;
result <<= 4;
}
if (xAux >= 2**4) {
xAux >>= 4;
result <<= 2;
}
if (xAux >= 2**2) {
result <<= 1;
}
// At this point, `result` is an estimation with at least one bit of precision. We know the true value has at
// most 128 bits, 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 + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
// If x is not a perfect square, round the result toward zero.
uint256 roundedResult = x / result;
if (result >= roundedResult) {
result = roundedResult;
}
}
}
// slither-disable-end divide-before-multiply{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"CurveOracleAlreadyDeployed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rToken","type":"address"},{"indexed":true,"internalType":"address","name":"curveOracle","type":"address"}],"name":"CurveOracleDeployed","type":"event"},{"inputs":[{"internalType":"contract IRToken","name":"","type":"address"}],"name":"curveOracles","outputs":[{"internalType":"contract CurveOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRToken","name":"rToken","type":"address"}],"name":"deployCurveOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50610690806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343bdb35f1461003b5780638c3017fa14610080575b600080fd5b6100646100493660046101d0565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b61006461008e3660046101d0565b6001600160a01b03818116600090815260208190526040812054909116156100c95760405163941e73fb60e01b815260040160405180910390fd5b6000826040516100d8906101c3565b6001600160a01b039091168152602001604051809103906000f080158015610104573d6000803e3d6000fd5b509050806001600160a01b0316633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101699190610200565b506001600160a01b0383811660008181526020819052604080822080546001600160a01b0319169486169485179055517ffede6abb16bf73e70ecf300d5820a9b6ec99ca6bd66c3980f2d089f0576b93a39190a392915050565b6104418061021a83390190565b6000602082840312156101e257600080fd5b81356001600160a01b03811681146101f957600080fd5b9392505050565b60006020828403121561021257600080fd5b505191905056fe60a060405234801561001057600080fd5b5060405161044138038061044183398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516103aa61009760003960008181605b01528181609c015261012701526103aa6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80633ba0b9a91461003b57806340c65f7214610056575b600080fd5b610043610095565b6040519081526020015b60405180910390f35b61007d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161004d565b60006101ac7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637121c2736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011c919061031c565b6001600160c01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a79190610345565b6101ba565b6001600160c01b0316905090565b60006101d76101d2670de0b6b3a764000085856101de565b6102c1565b9392505050565b60008060006101ed86866102ef565b915091508382106102115760405163f44398f560e01b815260040160405180910390fd5b600084806102215761022161035e565b868809905081811115610235576001830392505b9081900390600085900385168086816102505761025061035e565b0495508083816102625761026261035e565b0492508081600003816102775761027761035e565b046001019390930291909101600285810380870282030280870282030280870282030280870282030280870282030280870282030295860290039094029390930295945050505050565b60006001600160c01b038211156102eb5760405163f44398f560e01b815260040160405180910390fd5b5090565b6000808060001984860990508385029150818103925081811015610314576001830392505b509250929050565b60006020828403121561032e57600080fd5b81516001600160c01b03811681146101d757600080fd5b60006020828403121561035757600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fdfea264697066735822122077ebdec65a8a0aa21a2a9e048c81f3f02844d5c36ae5adf76469509f580a71cc64736f6c63430008130033a2646970667358221220c4ff9808bb07cf8844d087dae4d15bae2c78f6efcf27b55aea87ec589425510064736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100365760003560e01c806343bdb35f1461003b5780638c3017fa14610080575b600080fd5b6100646100493660046101d0565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b61006461008e3660046101d0565b6001600160a01b03818116600090815260208190526040812054909116156100c95760405163941e73fb60e01b815260040160405180910390fd5b6000826040516100d8906101c3565b6001600160a01b039091168152602001604051809103906000f080158015610104573d6000803e3d6000fd5b509050806001600160a01b0316633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101699190610200565b506001600160a01b0383811660008181526020819052604080822080546001600160a01b0319169486169485179055517ffede6abb16bf73e70ecf300d5820a9b6ec99ca6bd66c3980f2d089f0576b93a39190a392915050565b6104418061021a83390190565b6000602082840312156101e257600080fd5b81356001600160a01b03811681146101f957600080fd5b9392505050565b60006020828403121561021257600080fd5b505191905056fe60a060405234801561001057600080fd5b5060405161044138038061044183398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516103aa61009760003960008181605b01528181609c015261012701526103aa6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80633ba0b9a91461003b57806340c65f7214610056575b600080fd5b610043610095565b6040519081526020015b60405180910390f35b61007d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161004d565b60006101ac7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637121c2736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011c919061031c565b6001600160c01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a79190610345565b6101ba565b6001600160c01b0316905090565b60006101d76101d2670de0b6b3a764000085856101de565b6102c1565b9392505050565b60008060006101ed86866102ef565b915091508382106102115760405163f44398f560e01b815260040160405180910390fd5b600084806102215761022161035e565b868809905081811115610235576001830392505b9081900390600085900385168086816102505761025061035e565b0495508083816102625761026261035e565b0492508081600003816102775761027761035e565b046001019390930291909101600285810380870282030280870282030280870282030280870282030280870282030280870282030295860290039094029390930295945050505050565b60006001600160c01b038211156102eb5760405163f44398f560e01b815260040160405180910390fd5b5090565b6000808060001984860990508385029150818103925081811015610314576001830392505b509250929050565b60006020828403121561032e57600080fd5b81516001600160c01b03811681146101d757600080fd5b60006020828403121561035757600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fdfea264697066735822122077ebdec65a8a0aa21a2a9e048c81f3f02844d5c36ae5adf76469509f580a71cc64736f6c63430008130033a2646970667358221220c4ff9808bb07cf8844d087dae4d15bae2c78f6efcf27b55aea87ec589425510064736f6c63430008130033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.