Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Cache Decimals | 18032313 | 401 days ago | IN | 0 ETH | 0.00077635 | ||||
Cache Decimals | 18032310 | 401 days ago | IN | 0 ETH | 0.00083846 | ||||
Cache Decimals | 18032307 | 401 days ago | IN | 0 ETH | 0.00082042 | ||||
Cache Decimals | 18032304 | 401 days ago | IN | 0 ETH | 0.00081888 | ||||
Cache Decimals | 18032301 | 401 days ago | IN | 0 ETH | 0.00081952 | ||||
0x60806040 | 18032298 | 401 days ago | IN | 0 ETH | 0.01244277 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
OETHOracleRouter
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../interfaces/chainlink/AggregatorV3Interface.sol"; import { IOracle } from "../interfaces/IOracle.sol"; import { Helpers } from "../utils/Helpers.sol"; import { StableMath } from "../utils/StableMath.sol"; import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; // @notice Abstract functionality that is shared between various Oracle Routers abstract contract OracleRouterBase is IOracle { using StableMath for uint256; using SafeCast for int256; uint256 internal constant MIN_DRIFT = 0.7e18; uint256 internal constant MAX_DRIFT = 1.3e18; address internal constant FIXED_PRICE = 0x0000000000000000000000000000000000000001; // Maximum allowed staleness buffer above normal Oracle maximum staleness uint256 internal constant STALENESS_BUFFER = 1 days; mapping(address => uint8) internal decimalsCache; /** * @dev The price feed contract to use for a particular asset along with * maximum data staleness * @param asset address of the asset * @return feedAddress address of the price feed for the asset * @return maxStaleness maximum acceptable data staleness duration */ function feedMetadata(address asset) internal view virtual returns (address feedAddress, uint256 maxStaleness); /** * @notice Returns the total price in 18 digit unit for a given asset. * @param asset address of the asset * @return uint256 unit price for 1 asset unit, in 18 decimal fixed */ function price(address asset) external view virtual override returns (uint256) { (address _feed, uint256 maxStaleness) = feedMetadata(asset); require(_feed != address(0), "Asset not available"); require(_feed != FIXED_PRICE, "Fixed price feeds not supported"); (, int256 _iprice, , uint256 updatedAt, ) = AggregatorV3Interface(_feed) .latestRoundData(); require( updatedAt + maxStaleness >= block.timestamp, "Oracle price too old" ); uint8 decimals = getDecimals(_feed); uint256 _price = _iprice.toUint256().scaleBy(18, decimals); if (shouldBePegged(asset)) { require(_price <= MAX_DRIFT, "Oracle: Price exceeds max"); require(_price >= MIN_DRIFT, "Oracle: Price under min"); } return _price; } function getDecimals(address _feed) internal view virtual returns (uint8) { uint8 decimals = decimalsCache[_feed]; require(decimals > 0, "Oracle: Decimals not cached"); return decimals; } /** * @notice Before an asset/feed price is fetches for the first time the * decimals need to be cached. This is a gas optimization * @param asset address of the asset * @return uint8 corresponding asset decimals */ function cacheDecimals(address asset) external returns (uint8) { (address _feed, ) = feedMetadata(asset); require(_feed != address(0), "Asset not available"); require(_feed != FIXED_PRICE, "Fixed price feeds not supported"); uint8 decimals = AggregatorV3Interface(_feed).decimals(); decimalsCache[_feed] = decimals; return decimals; } function shouldBePegged(address _asset) internal view returns (bool) { string memory symbol = Helpers.getSymbol(_asset); bytes32 symbolHash = keccak256(abi.encodePacked(symbol)); return symbolHash == keccak256(abi.encodePacked("DAI")) || symbolHash == keccak256(abi.encodePacked("USDC")) || symbolHash == keccak256(abi.encodePacked("USDT")); } } // @notice Oracle Router that denominates all prices in USD contract OracleRouter is OracleRouterBase { /** * @dev The price feed contract to use for a particular asset along with * maximum data staleness * @param asset address of the asset * @return feedAddress address of the price feed for the asset * @return maxStaleness maximum acceptable data staleness duration */ function feedMetadata(address asset) internal pure virtual override returns (address feedAddress, uint256 maxStaleness) { /* + STALENESS_BUFFER is added in case Oracle for some reason doesn't * update on heartbeat and we add a generous buffer amount. */ if (asset == 0x6B175474E89094C44Da98b954EedeAC495271d0F) { // https://data.chain.link/ethereum/mainnet/stablecoins/dai-usd // Chainlink: DAI/USD feedAddress = 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9; maxStaleness = 1 hours + STALENESS_BUFFER; } else if (asset == 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) { // https://data.chain.link/ethereum/mainnet/stablecoins/usdc-usd // Chainlink: USDC/USD feedAddress = 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0xdAC17F958D2ee523a2206206994597C13D831ec7) { // https://data.chain.link/ethereum/mainnet/stablecoins/usdt-usd // Chainlink: USDT/USD feedAddress = 0x3E7d1eAB13ad0104d2750B8863b489D65364e32D; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0xc00e94Cb662C3520282E6f5717214004A7f26888) { // https://data.chain.link/ethereum/mainnet/crypto-usd/comp-usd // Chainlink: COMP/USD feedAddress = 0xdbd020CAeF83eFd542f4De03e3cF0C28A4428bd5; maxStaleness = 1 hours + STALENESS_BUFFER; } else if (asset == 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9) { // https://data.chain.link/ethereum/mainnet/crypto-usd/aave-usd // Chainlink: AAVE/USD feedAddress = 0x547a514d5e3769680Ce22B2361c10Ea13619e8a9; maxStaleness = 1 hours + STALENESS_BUFFER; } else if (asset == 0xD533a949740bb3306d119CC777fa900bA034cd52) { // https://data.chain.link/ethereum/mainnet/crypto-usd/crv-usd // Chainlink: CRV/USD feedAddress = 0xCd627aA160A6fA45Eb793D19Ef54f5062F20f33f; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B) { // Chainlink: CVX/USD feedAddress = 0xd962fC30A72A84cE50161031391756Bf2876Af5D; maxStaleness = 1 days + STALENESS_BUFFER; } else { revert("Asset not available"); } } } // @notice Oracle Router that denominates all prices in ETH contract OETHOracleRouter is OracleRouter { using StableMath for uint256; /** * @notice Returns the total price in 18 digit units for a given asset. * This implementation does not (!) do range checks as the * parent OracleRouter does. * @param asset address of the asset * @return uint256 unit price for 1 asset unit, in 18 decimal fixed */ function price(address asset) external view virtual override returns (uint256) { (address _feed, uint256 maxStaleness) = feedMetadata(asset); if (_feed == FIXED_PRICE) { return 1e18; } require(_feed != address(0), "Asset not available"); (, int256 _iprice, , uint256 updatedAt, ) = AggregatorV3Interface(_feed) .latestRoundData(); require( updatedAt + maxStaleness >= block.timestamp, "Oracle price too old" ); uint8 decimals = getDecimals(_feed); uint256 _price = uint256(_iprice).scaleBy(18, decimals); return _price; } /** * @dev The price feed contract to use for a particular asset along with * maximum data staleness * @param asset address of the asset * @return feedAddress address of the price feed for the asset * @return maxStaleness maximum acceptable data staleness duration */ function feedMetadata(address asset) internal pure virtual override returns (address feedAddress, uint256 maxStaleness) { if (asset == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) { // FIXED_PRICE: WETH/ETH feedAddress = FIXED_PRICE; maxStaleness = 0; } else if (asset == 0x5E8422345238F34275888049021821E8E08CAa1f) { // frxETH/ETH feedAddress = 0xC58F3385FBc1C8AD2c0C9a061D7c13b141D7A5Df; maxStaleness = 18 hours + STALENESS_BUFFER; } else if (asset == 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84) { // https://data.chain.link/ethereum/mainnet/crypto-eth/steth-eth // Chainlink: stETH/ETH feedAddress = 0x86392dC19c0b719886221c78AB11eb8Cf5c52812; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0xae78736Cd615f374D3085123A210448E74Fc6393) { // https://data.chain.link/ethereum/mainnet/crypto-eth/reth-eth // Chainlink: rETH/ETH feedAddress = 0x536218f9E9Eb48863970252233c8F271f554C2d0; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0xD533a949740bb3306d119CC777fa900bA034cd52) { // https://data.chain.link/ethereum/mainnet/crypto-eth/crv-eth // Chainlink: CRV/ETH feedAddress = 0x8a12Be339B0cD1829b91Adc01977caa5E9ac121e; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B) { // https://data.chain.link/ethereum/mainnet/crypto-eth/cvx-eth // Chainlink: CVX/ETH feedAddress = 0xC9CbF687f43176B302F03f5e58470b77D07c61c6; maxStaleness = 1 days + STALENESS_BUFFER; } else if (asset == 0xBe9895146f7AF43049ca1c1AE358B0541Ea49704) { // https://data.chain.link/ethereum/mainnet/crypto-eth/cbeth-eth // Chainlink: cbETH/ETH feedAddress = 0xF017fcB346A1885194689bA23Eff2fE6fA5C483b; maxStaleness = 1 days + STALENESS_BUFFER; } else { revert("Asset not available"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol) pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBasicToken { function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IOracle { /** * @dev returns the asset price in USD, in 8 decimal digits. * * The version of priceProvider deployed for OETH has 18 decimal digits */ function price(address asset) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IBasicToken } from "../interfaces/IBasicToken.sol"; library Helpers { /** * @notice Fetch the `symbol()` from an ERC20 token * @dev Grabs the `symbol()` from a contract * @param _token Address of the ERC20 token * @return string Symbol of the ERC20 token */ function getSymbol(address _token) internal view returns (string memory) { string memory symbol = IBasicToken(_token).symbol(); return symbol; } /** * @notice Fetch the `decimals()` from an ERC20 token * @dev Grabs the `decimals()` from a contract and fails if * the decimal value does not live within a certain range * @param _token Address of the ERC20 token * @return uint256 Decimals of the ERC20 token */ function getDecimals(address _token) internal view returns (uint256) { uint256 decimals = IBasicToken(_token).decimals(); require( decimals >= 4 && decimals <= 18, "Token must have sufficient decimal places" ); return decimals; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol"; // Based on StableMath from Stability Labs Pty. Ltd. // https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol library StableMath { using SafeMath for uint256; /** * @dev Scaling unit for use in specific calculations, * where 1 * 10**18, or 1e18 represents a unit '1' */ uint256 private constant FULL_SCALE = 1e18; /*************************************** Helpers ****************************************/ /** * @dev Adjust the scale of an integer * @param to Decimals to scale to * @param from Decimals to scale from */ function scaleBy( uint256 x, uint256 to, uint256 from ) internal pure returns (uint256) { if (to > from) { x = x.mul(10**(to - from)); } else if (to < from) { // slither-disable-next-line divide-before-multiply x = x.div(10**(from - to)); } return x; } /*************************************** Precise Arithmetic ****************************************/ /** * @dev Multiplies two precise units, and then truncates by the full scale * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) { return mulTruncateScale(x, y, FULL_SCALE); } /** * @dev Multiplies two precise units, and then truncates by the given scale. For example, * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18 * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @param scale Scale unit * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncateScale( uint256 x, uint256 y, uint256 scale ) internal pure returns (uint256) { // e.g. assume scale = fullScale // z = 10e18 * 9e17 = 9e36 uint256 z = x.mul(y); // return 9e36 / 1e18 = 9e18 return z.div(scale); } /** * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit, rounded up to the closest base unit. */ function mulTruncateCeil(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e17 * 17268172638 = 138145381104e17 uint256 scaled = x.mul(y); // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17 uint256 ceil = scaled.add(FULL_SCALE.sub(1)); // e.g. 13814538111.399...e18 / 1e18 = 13814538111 return ceil.div(FULL_SCALE); } /** * @dev Precisely divides two units, by first scaling the left hand operand. Useful * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17) * @param x Left hand input to division * @param y Right hand input to division * @return Result after multiplying the left operand by the scale, and * executing the division on the right hand input. */ function divPrecisely(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e18 * 1e18 = 8e36 uint256 z = x.mul(FULL_SCALE); // e.g. 8e36 / 10e18 = 8e17 return z.div(y); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"cacheDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061089c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806336b6d9441461003b578063aea9107814610065575b600080fd5b61004e61004936600461062c565b610086565b60405160ff90911681526020015b60405180910390f35b61007861007336600461062c565b6101bf565b60405190815260200161005c565b60008061009283610312565b5090506001600160a01b0381166100c45760405162461bcd60e51b81526004016100bb906106c8565b60405180910390fd5b6001600160a01b0381166001141561011e5760405162461bcd60e51b815260206004820152601f60248201527f4669786564207072696365206665656473206e6f7420737570706f727465640060448201526064016100bb565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561015957600080fd5b505afa15801561016d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019191906106a5565b6001600160a01b03929092166000908152602081905260409020805460ff191660ff84161790555092915050565b60008060006101cd84610312565b90925090506001600160a01b038216600114156101f55750670de0b6b3a76400009392505050565b6001600160a01b03821661021b5760405162461bcd60e51b81526004016100bb906106c8565b600080836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561025757600080fd5b505afa15801561026b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028f9190610655565b509350509250504283826102a391906106f5565b10156102e85760405162461bcd60e51b815260206004820152601460248201527313dc9858db19481c1c9a58d9481d1bdbc81bdb1960621b60448201526064016100bb565b60006102f38561051d565b9050600061030684601260ff851661058c565b98975050505050505050565b60008073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03841614156103465750600190506000915091565b735e8422345238f34275888049021821e8e08caa1f6001600160a01b03841614156103985773c58f3385fbc1c8ad2c0c9a061d7c13b141d7a5df91506103916201518061fd206106f5565b9050915091565b73ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b03841614156103e1577386392dc19c0b719886221c78ab11eb8cf5c52812915061039162015180806106f5565b73ae78736cd615f374d3085123a210448e74fc63936001600160a01b038416141561042a5773536218f9e9eb48863970252233c8f271f554c2d0915061039162015180806106f5565b73d533a949740bb3306d119cc777fa900ba034cd526001600160a01b038416141561047357738a12be339b0cd1829b91adc01977caa5e9ac121e915061039162015180806106f5565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03841614156104bc5773c9cbf687f43176b302f03f5e58470b77d07c61c6915061039162015180806106f5565b73be9895146f7af43049ca1c1ae358b0541ea497046001600160a01b03841614156105055773f017fcb346a1885194689ba23eff2fe6fa5c483b915061039162015180806106f5565b60405162461bcd60e51b81526004016100bb906106c8565b6001600160a01b03811660009081526020819052604081205460ff16806105865760405162461bcd60e51b815260206004820152601b60248201527f4f7261636c653a20446563696d616c73206e6f7420636163686564000000000060448201526064016100bb565b92915050565b6000818311156105bc576105b56105a38385610839565b6105ae90600a610772565b85906105ee565b93506105e6565b818310156105e6576105e36105d18484610839565b6105dc90600a610772565b8590610601565b93505b509192915050565b60006105fa828461081a565b9392505050565b60006105fa828461070d565b805169ffffffffffffffffffff8116811461062757600080fd5b919050565b60006020828403121561063e57600080fd5b81356001600160a01b03811681146105fa57600080fd5b600080600080600060a0868803121561066d57600080fd5b6106768661060d565b94506020860151935060408601519250606086015191506106996080870161060d565b90509295509295909350565b6000602082840312156106b757600080fd5b815160ff811681146105fa57600080fd5b6020808252601390820152724173736574206e6f7420617661696c61626c6560681b604082015260600190565b6000821982111561070857610708610850565b500190565b60008261072a57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b8085111561076a57816000190482111561075057610750610850565b8085161561075d57918102915b93841c9390800290610734565b509250929050565b60006105fa838360008261078857506001610586565b8161079557506000610586565b81600181146107ab57600281146107b5576107d1565b6001915050610586565b60ff8411156107c6576107c6610850565b50506001821b610586565b5060208310610133831016604e8410600b84101617156107f4575081810a610586565b6107fe838361072f565b806000190482111561081257610812610850565b029392505050565b600081600019048311821515161561083457610834610850565b500290565b60008282101561084b5761084b610850565b500390565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220b66fc794fbca0536355abd67a782ac6a9194aaf7601c2523f308f0dd208ba4a664736f6c63430008070033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100365760003560e01c806336b6d9441461003b578063aea9107814610065575b600080fd5b61004e61004936600461062c565b610086565b60405160ff90911681526020015b60405180910390f35b61007861007336600461062c565b6101bf565b60405190815260200161005c565b60008061009283610312565b5090506001600160a01b0381166100c45760405162461bcd60e51b81526004016100bb906106c8565b60405180910390fd5b6001600160a01b0381166001141561011e5760405162461bcd60e51b815260206004820152601f60248201527f4669786564207072696365206665656473206e6f7420737570706f727465640060448201526064016100bb565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561015957600080fd5b505afa15801561016d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019191906106a5565b6001600160a01b03929092166000908152602081905260409020805460ff191660ff84161790555092915050565b60008060006101cd84610312565b90925090506001600160a01b038216600114156101f55750670de0b6b3a76400009392505050565b6001600160a01b03821661021b5760405162461bcd60e51b81526004016100bb906106c8565b600080836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561025757600080fd5b505afa15801561026b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028f9190610655565b509350509250504283826102a391906106f5565b10156102e85760405162461bcd60e51b815260206004820152601460248201527313dc9858db19481c1c9a58d9481d1bdbc81bdb1960621b60448201526064016100bb565b60006102f38561051d565b9050600061030684601260ff851661058c565b98975050505050505050565b60008073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03841614156103465750600190506000915091565b735e8422345238f34275888049021821e8e08caa1f6001600160a01b03841614156103985773c58f3385fbc1c8ad2c0c9a061d7c13b141d7a5df91506103916201518061fd206106f5565b9050915091565b73ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b03841614156103e1577386392dc19c0b719886221c78ab11eb8cf5c52812915061039162015180806106f5565b73ae78736cd615f374d3085123a210448e74fc63936001600160a01b038416141561042a5773536218f9e9eb48863970252233c8f271f554c2d0915061039162015180806106f5565b73d533a949740bb3306d119cc777fa900ba034cd526001600160a01b038416141561047357738a12be339b0cd1829b91adc01977caa5e9ac121e915061039162015180806106f5565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03841614156104bc5773c9cbf687f43176b302f03f5e58470b77d07c61c6915061039162015180806106f5565b73be9895146f7af43049ca1c1ae358b0541ea497046001600160a01b03841614156105055773f017fcb346a1885194689ba23eff2fe6fa5c483b915061039162015180806106f5565b60405162461bcd60e51b81526004016100bb906106c8565b6001600160a01b03811660009081526020819052604081205460ff16806105865760405162461bcd60e51b815260206004820152601b60248201527f4f7261636c653a20446563696d616c73206e6f7420636163686564000000000060448201526064016100bb565b92915050565b6000818311156105bc576105b56105a38385610839565b6105ae90600a610772565b85906105ee565b93506105e6565b818310156105e6576105e36105d18484610839565b6105dc90600a610772565b8590610601565b93505b509192915050565b60006105fa828461081a565b9392505050565b60006105fa828461070d565b805169ffffffffffffffffffff8116811461062757600080fd5b919050565b60006020828403121561063e57600080fd5b81356001600160a01b03811681146105fa57600080fd5b600080600080600060a0868803121561066d57600080fd5b6106768661060d565b94506020860151935060408601519250606086015191506106996080870161060d565b90509295509295909350565b6000602082840312156106b757600080fd5b815160ff811681146105fa57600080fd5b6020808252601390820152724173736574206e6f7420617661696c61626c6560681b604082015260600190565b6000821982111561070857610708610850565b500190565b60008261072a57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b8085111561076a57816000190482111561075057610750610850565b8085161561075d57918102915b93841c9390800290610734565b509250929050565b60006105fa838360008261078857506001610586565b8161079557506000610586565b81600181146107ab57600281146107b5576107d1565b6001915050610586565b60ff8411156107c6576107c6610850565b50506001821b610586565b5060208310610133831016604e8410600b84101617156107f4575081810a610586565b6107fe838361072f565b806000190482111561081257610812610850565b029392505050565b600081600019048311821515161561083457610834610850565b500290565b60008282101561084b5761084b610850565b500390565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220b66fc794fbca0536355abd67a782ac6a9194aaf7601c2523f308f0dd208ba4a664736f6c63430008070033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.