diff --git a/contracts/deployments/sonic/.migrations.json b/contracts/deployments/sonic/.migrations.json index 13c390f734..59bca5e583 100644 --- a/contracts/deployments/sonic/.migrations.json +++ b/contracts/deployments/sonic/.migrations.json @@ -1,3 +1,4 @@ { - "001_vault_and_token": 1736867284 + "001_vault_and_token": 1736867284, + "002_oracle_router": 1737018791 } \ No newline at end of file diff --git a/contracts/deployments/sonic/OSonicOracleRouter.json b/contracts/deployments/sonic/OSonicOracleRouter.json new file mode 100644 index 0000000000..b995c2f6fa --- /dev/null +++ b/contracts/deployments/sonic/OSonicOracleRouter.json @@ -0,0 +1,157 @@ +{ + "address": "0xE68e0C66950a7e02335fc9f44daa05D115c4E88B", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_auraPriceFeed", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "auraPriceFeed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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" + } + ], + "transactionHash": "0xe16de472c67de6bf26123c8d7a92ba3eeb854d6f53a57ef0192a908ec83456a0", + "receipt": { + "to": null, + "from": "0xFD9E6005187F448957a0972a7d0C0A6dA2911236", + "contractAddress": "0xE68e0C66950a7e02335fc9f44daa05D115c4E88B", + "transactionIndex": 0, + "gasUsed": "204247", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x89717234bef8f4727424fcc5bde65b9dd41d9c7432332ec06420fc800a5acc1d", + "transactionHash": "0xe16de472c67de6bf26123c8d7a92ba3eeb854d6f53a57ef0192a908ec83456a0", + "logs": [], + "blockNumber": 4127603, + "cumulativeGasUsed": "204247", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "115fd4d0d3af5a2dabc9b75908a4db81", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_auraPriceFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"auraPriceFeed\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cacheDecimals(address)\":{\"params\":{\"asset\":\"address of the asset\"},\"returns\":{\"_0\":\"uint8 corresponding asset decimals\"}},\"price(address)\":{\"params\":{\"asset\":\"address of the asset\"},\"returns\":{\"_0\":\"uint256 unit price for 1 asset unit, in 18 decimal fixed\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cacheDecimals(address)\":{\"notice\":\"Before an asset/feed price is fetches for the first time the decimals need to be cached. This is a gas optimization\"},\"price(address)\":{\"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.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracle/OSonicOracleRouter.sol\":\"OSonicOracleRouter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits.\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits.\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x5c6caab697d302ad7eb59c234a4d2dbc965c1bae87709bd2850060b7695b28c7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n// CAUTION\\n// This version of SafeMath should only be used with Solidity 0.8 or later,\\n// because it relies on the compiler's built in overflow checks.\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations.\\n *\\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\\n * now has built in overflow checking.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator.\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa2f576be637946f767aa56601c26d717f48a0aff44f82e46f13807eea1009a21\",\"license\":\"MIT\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xa562062698aa12572123b36dfd2072f1a39e44fed2031cc19c2c9fd522f96ec2\",\"license\":\"MIT\"},\"contracts/interfaces/IOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOracle {\\n /**\\n * @dev returns the asset price in USD, in 8 decimal digits.\\n *\\n * The version of priceProvider deployed for OETH has 18 decimal digits\\n */\\n function price(address asset) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x9eabf152389f145c9c23ed71972af73fb1708cbc4b26e524a9ba29a557b7cfe5\",\"license\":\"MIT\"},\"contracts/interfaces/chainlink/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface AggregatorV3Interface {\\n function decimals() external view returns (uint8);\\n\\n function description() external view returns (string memory);\\n\\n function version() external view returns (uint256);\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(uint80 _roundId)\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n}\\n\",\"keccak256\":\"0x18fb68de95136c49f3874fe7795a7bda730339198b2816690ddbdf1eacd4e273\",\"license\":\"MIT\"},\"contracts/oracle/AbstractOracleRouter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../interfaces/chainlink/AggregatorV3Interface.sol\\\";\\nimport { IOracle } from \\\"../interfaces/IOracle.sol\\\";\\nimport { Helpers } from \\\"../utils/Helpers.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\nimport { SafeCast } from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n// @notice Abstract functionality that is shared between various Oracle Routers\\nabstract contract AbstractOracleRouter is IOracle {\\n using StableMath for uint256;\\n using SafeCast for int256;\\n\\n uint256 internal constant MIN_DRIFT = 0.7e18;\\n uint256 internal constant MAX_DRIFT = 1.3e18;\\n address internal constant FIXED_PRICE =\\n 0x0000000000000000000000000000000000000001;\\n // Maximum allowed staleness buffer above normal Oracle maximum staleness\\n uint256 internal constant STALENESS_BUFFER = 1 days;\\n mapping(address => uint8) internal decimalsCache;\\n\\n /**\\n * @dev The price feed contract to use for a particular asset along with\\n * maximum data staleness\\n * @param asset address of the asset\\n * @return feedAddress address of the price feed for the asset\\n * @return maxStaleness maximum acceptable data staleness duration\\n */\\n function feedMetadata(address asset)\\n internal\\n view\\n virtual\\n returns (address feedAddress, uint256 maxStaleness);\\n\\n /**\\n * @notice Returns the total price in 18 digit unit for a given asset.\\n * @param asset address of the asset\\n * @return uint256 unit price for 1 asset unit, in 18 decimal fixed\\n */\\n function price(address asset)\\n external\\n view\\n virtual\\n override\\n returns (uint256)\\n {\\n (address _feed, uint256 maxStaleness) = feedMetadata(asset);\\n require(_feed != address(0), \\\"Asset not available\\\");\\n require(_feed != FIXED_PRICE, \\\"Fixed price feeds not supported\\\");\\n\\n // slither-disable-next-line unused-return\\n (, int256 _iprice, , uint256 updatedAt, ) = AggregatorV3Interface(_feed)\\n .latestRoundData();\\n\\n require(\\n updatedAt + maxStaleness >= block.timestamp,\\n \\\"Oracle price too old\\\"\\n );\\n\\n uint8 decimals = getDecimals(_feed);\\n\\n uint256 _price = _iprice.toUint256().scaleBy(18, decimals);\\n if (shouldBePegged(asset)) {\\n require(_price <= MAX_DRIFT, \\\"Oracle: Price exceeds max\\\");\\n require(_price >= MIN_DRIFT, \\\"Oracle: Price under min\\\");\\n }\\n return _price;\\n }\\n\\n function getDecimals(address _feed) internal view virtual returns (uint8) {\\n uint8 decimals = decimalsCache[_feed];\\n require(decimals > 0, \\\"Oracle: Decimals not cached\\\");\\n return decimals;\\n }\\n\\n /**\\n * @notice Before an asset/feed price is fetches for the first time the\\n * decimals need to be cached. This is a gas optimization\\n * @param asset address of the asset\\n * @return uint8 corresponding asset decimals\\n */\\n function cacheDecimals(address asset) external returns (uint8) {\\n (address _feed, ) = feedMetadata(asset);\\n require(_feed != address(0), \\\"Asset not available\\\");\\n require(_feed != FIXED_PRICE, \\\"Fixed price feeds not supported\\\");\\n\\n uint8 decimals = AggregatorV3Interface(_feed).decimals();\\n decimalsCache[_feed] = decimals;\\n return decimals;\\n }\\n\\n function shouldBePegged(address _asset) internal view returns (bool) {\\n string memory symbol = Helpers.getSymbol(_asset);\\n bytes32 symbolHash = keccak256(abi.encodePacked(symbol));\\n return\\n symbolHash == keccak256(abi.encodePacked(\\\"DAI\\\")) ||\\n symbolHash == keccak256(abi.encodePacked(\\\"USDC\\\")) ||\\n symbolHash == keccak256(abi.encodePacked(\\\"USDT\\\"));\\n }\\n}\\n\",\"keccak256\":\"0x68c80bfe76102366520c15f6b2b66878f07888987a9d0781387b2e7f2badae2a\",\"license\":\"MIT\"},\"contracts/oracle/OETHFixedOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { OETHOracleRouter } from \\\"./OETHOracleRouter.sol\\\";\\n\\n// @notice Oracle Router that returns 1e18 for all prices\\n// used solely for deployment to testnets\\ncontract OETHFixedOracle is OETHOracleRouter {\\n constructor(address _auraPriceFeed) OETHOracleRouter(_auraPriceFeed) {}\\n\\n /**\\n * @dev The price feed contract to use for a particular asset along with\\n * maximum data staleness\\n * @param asset address of the asset\\n * @return feedAddress address of the price feed for the asset\\n * @return maxStaleness maximum acceptable data staleness duration\\n */\\n // solhint-disable-next-line no-unused-vars\\n function feedMetadata(address asset)\\n internal\\n view\\n virtual\\n override\\n returns (address feedAddress, uint256 maxStaleness)\\n {\\n // fixes price for all of the assets\\n feedAddress = FIXED_PRICE;\\n maxStaleness = 0;\\n }\\n}\\n\",\"keccak256\":\"0xf9631aaf6c865e3062d45d52db3752d7e6081cd77b5ce2fa9315bf98be96c19b\",\"license\":\"MIT\"},\"contracts/oracle/OETHOracleRouter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"../interfaces/chainlink/AggregatorV3Interface.sol\\\";\\nimport { AbstractOracleRouter } from \\\"./AbstractOracleRouter.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\n\\n// @notice Oracle Router that denominates all prices in ETH\\ncontract OETHOracleRouter is AbstractOracleRouter {\\n using StableMath for uint256;\\n\\n address public immutable auraPriceFeed;\\n\\n constructor(address _auraPriceFeed) {\\n auraPriceFeed = _auraPriceFeed;\\n }\\n\\n /**\\n * @notice Returns the total price in 18 digit units for a given asset.\\n * This implementation does not (!) do range checks as the\\n * parent OracleRouter does.\\n * @param asset address of the asset\\n * @return uint256 unit price for 1 asset unit, in 18 decimal fixed\\n */\\n function price(address asset)\\n external\\n view\\n virtual\\n override\\n returns (uint256)\\n {\\n (address _feed, uint256 maxStaleness) = feedMetadata(asset);\\n if (_feed == FIXED_PRICE) {\\n return 1e18;\\n }\\n require(_feed != address(0), \\\"Asset not available\\\");\\n\\n // slither-disable-next-line unused-return\\n (, int256 _iprice, , uint256 updatedAt, ) = AggregatorV3Interface(_feed)\\n .latestRoundData();\\n\\n require(\\n updatedAt + maxStaleness >= block.timestamp,\\n \\\"Oracle price too old\\\"\\n );\\n\\n uint8 decimals = getDecimals(_feed);\\n uint256 _price = uint256(_iprice).scaleBy(18, decimals);\\n return _price;\\n }\\n\\n /**\\n * @dev The price feed contract to use for a particular asset along with\\n * maximum data staleness\\n * @param asset address of the asset\\n * @return feedAddress address of the price feed for the asset\\n * @return maxStaleness maximum acceptable data staleness duration\\n */\\n function feedMetadata(address asset)\\n internal\\n view\\n virtual\\n override\\n returns (address feedAddress, uint256 maxStaleness)\\n {\\n if (asset == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) {\\n // FIXED_PRICE: WETH/ETH\\n feedAddress = FIXED_PRICE;\\n maxStaleness = 0;\\n } else if (asset == 0x5E8422345238F34275888049021821E8E08CAa1f) {\\n // frxETH/ETH\\n feedAddress = 0xC58F3385FBc1C8AD2c0C9a061D7c13b141D7A5Df;\\n maxStaleness = 18 hours + STALENESS_BUFFER;\\n } else if (asset == 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84) {\\n // https://data.chain.link/ethereum/mainnet/crypto-eth/steth-eth\\n // Chainlink: stETH/ETH\\n feedAddress = 0x86392dC19c0b719886221c78AB11eb8Cf5c52812;\\n maxStaleness = 1 days + STALENESS_BUFFER;\\n } else if (asset == 0xae78736Cd615f374D3085123A210448E74Fc6393) {\\n // https://data.chain.link/ethereum/mainnet/crypto-eth/reth-eth\\n // Chainlink: rETH/ETH\\n feedAddress = 0x536218f9E9Eb48863970252233c8F271f554C2d0;\\n maxStaleness = 1 days + STALENESS_BUFFER;\\n } else if (asset == 0xD533a949740bb3306d119CC777fa900bA034cd52) {\\n // https://data.chain.link/ethereum/mainnet/crypto-eth/crv-eth\\n // Chainlink: CRV/ETH\\n feedAddress = 0x8a12Be339B0cD1829b91Adc01977caa5E9ac121e;\\n maxStaleness = 1 days + STALENESS_BUFFER;\\n } else if (asset == 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B) {\\n // https://data.chain.link/ethereum/mainnet/crypto-eth/cvx-eth\\n // Chainlink: CVX/ETH\\n feedAddress = 0xC9CbF687f43176B302F03f5e58470b77D07c61c6;\\n maxStaleness = 1 days + STALENESS_BUFFER;\\n } else if (asset == 0xBe9895146f7AF43049ca1c1AE358B0541Ea49704) {\\n // https://data.chain.link/ethereum/mainnet/crypto-eth/cbeth-eth\\n // Chainlink: cbETH/ETH\\n feedAddress = 0xF017fcB346A1885194689bA23Eff2fE6fA5C483b;\\n maxStaleness = 1 days + STALENESS_BUFFER;\\n } else if (asset == 0xba100000625a3754423978a60c9317c58a424e3D) {\\n // https://data.chain.link/ethereum/mainnet/crypto-eth/bal-eth\\n // Chainlink: BAL/ETH\\n feedAddress = 0xC1438AA3823A6Ba0C159CfA8D98dF5A994bA120b;\\n maxStaleness = 1 days + STALENESS_BUFFER;\\n } else if (asset == 0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF) {\\n // AURA/ETH\\n feedAddress = auraPriceFeed;\\n maxStaleness = 0;\\n } else {\\n revert(\\\"Asset not available\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa431f43ffb6553dd24395f2d8feffb0571cb4e6a56b0078d908356ec634116bf\",\"license\":\"MIT\"},\"contracts/oracle/OSonicOracleRouter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { OETHFixedOracle } from \\\"./OETHFixedOracle.sol\\\";\\n\\n// @notice Oracle Router that returns 1e18 for all prices\\n// used solely for deployment to testnets\\ncontract OSonicOracleRouter is OETHFixedOracle {\\n constructor(address _auraPriceFeed) OETHFixedOracle(_auraPriceFeed) {}\\n}\\n\",\"keccak256\":\"0x6bbc02f27918ec3204c89a4cd66b5c1eae8bd599189343a30f48cf438dd831e5\",\"license\":\"MIT\"},\"contracts/utils/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { IBasicToken } from \\\"../interfaces/IBasicToken.sol\\\";\\n\\nlibrary Helpers {\\n /**\\n * @notice Fetch the `symbol()` from an ERC20 token\\n * @dev Grabs the `symbol()` from a contract\\n * @param _token Address of the ERC20 token\\n * @return string Symbol of the ERC20 token\\n */\\n function getSymbol(address _token) internal view returns (string memory) {\\n string memory symbol = IBasicToken(_token).symbol();\\n return symbol;\\n }\\n\\n /**\\n * @notice Fetch the `decimals()` from an ERC20 token\\n * @dev Grabs the `decimals()` from a contract and fails if\\n * the decimal value does not live within a certain range\\n * @param _token Address of the ERC20 token\\n * @return uint256 Decimals of the ERC20 token\\n */\\n function getDecimals(address _token) internal view returns (uint256) {\\n uint256 decimals = IBasicToken(_token).decimals();\\n require(\\n decimals >= 4 && decimals <= 18,\\n \\\"Token must have sufficient decimal places\\\"\\n );\\n\\n return decimals;\\n }\\n}\\n\",\"keccak256\":\"0x108b7a69e0140da0072ca18f90a03a3340574400f81aa6076cd2cccdf13699c2\",\"license\":\"MIT\"},\"contracts/utils/StableMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\n\\n// Based on StableMath from Stability Labs Pty. Ltd.\\n// https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol\\n\\nlibrary StableMath {\\n using SafeMath for uint256;\\n\\n /**\\n * @dev Scaling unit for use in specific calculations,\\n * where 1 * 10**18, or 1e18 represents a unit '1'\\n */\\n uint256 private constant FULL_SCALE = 1e18;\\n\\n /***************************************\\n Helpers\\n ****************************************/\\n\\n /**\\n * @dev Adjust the scale of an integer\\n * @param to Decimals to scale to\\n * @param from Decimals to scale from\\n */\\n function scaleBy(\\n uint256 x,\\n uint256 to,\\n uint256 from\\n ) internal pure returns (uint256) {\\n if (to > from) {\\n x = x.mul(10**(to - from));\\n } else if (to < from) {\\n // slither-disable-next-line divide-before-multiply\\n x = x.div(10**(from - to));\\n }\\n return x;\\n }\\n\\n /***************************************\\n Precise Arithmetic\\n ****************************************/\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the full scale\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit\\n */\\n function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulTruncateScale(x, y, FULL_SCALE);\\n }\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the given scale. For example,\\n * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @param scale Scale unit\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit\\n */\\n function mulTruncateScale(\\n uint256 x,\\n uint256 y,\\n uint256 scale\\n ) internal pure returns (uint256) {\\n // e.g. assume scale = fullScale\\n // z = 10e18 * 9e17 = 9e36\\n uint256 z = x.mul(y);\\n // return 9e36 / 1e18 = 9e18\\n return z.div(scale);\\n }\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit, rounded up to the closest base unit.\\n */\\n function mulTruncateCeil(uint256 x, uint256 y)\\n internal\\n pure\\n returns (uint256)\\n {\\n // e.g. 8e17 * 17268172638 = 138145381104e17\\n uint256 scaled = x.mul(y);\\n // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17\\n uint256 ceil = scaled.add(FULL_SCALE.sub(1));\\n // e.g. 13814538111.399...e18 / 1e18 = 13814538111\\n return ceil.div(FULL_SCALE);\\n }\\n\\n /**\\n * @dev Precisely divides two units, by first scaling the left hand operand. Useful\\n * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)\\n * @param x Left hand input to division\\n * @param y Right hand input to division\\n * @return Result after multiplying the left operand by the scale, and\\n * executing the division on the right hand input.\\n */\\n function divPrecisely(uint256 x, uint256 y)\\n internal\\n pure\\n returns (uint256)\\n {\\n // e.g. 8e18 * 1e18 = 8e36\\n uint256 z = x.mul(FULL_SCALE);\\n // e.g. 8e36 / 10e18 = 8e17\\n return z.div(y);\\n }\\n}\\n\",\"keccak256\":\"0x1eb49f6f79045d9e0a8e1dced8e01d9e559e5fac554dcbb53e43140b601b04e7\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052348015600f57600080fd5b50604051610338380380610338833981016040819052602c91603c565b6001600160a01b0316608052606a565b600060208284031215604d57600080fd5b81516001600160a01b0381168114606357600080fd5b9392505050565b6080516102b46100846000396000604b01526102b46000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806323e2c52f1461004657806336b6d9441461008a578063aea91078146100af575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009d6100983660046101dd565b6100d8565b60405160ff9091168152602001610081565b6100ca6100bd3660046101dd565b50670de0b6b3a764000090565b604051908152602001610081565b600060016100ea565b60405180910390fd5b6000196001600160a01b038216016101445760405162461bcd60e51b815260206004820152601f60248201527f4669786564207072696365206665656473206e6f7420737570706f727465640060448201526064016100e1565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610184573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a89190610206565b6001600160a01b03929092166000908152602081905260409020805460ff191660ff84161790555092915050565b9392505050565b6000602082840312156101ef57600080fd5b81356001600160a01b03811681146101d657600080fd5b60006020828403121561021857600080fd5b815160ff811681146101d657600080fd5b634e487b7160e01b600052601160045260246000fd5b60018411156102765780850481111561025a5761025a610229565b600184161561026857908102905b60019390931c92800261023f565b93509391505056fea2646970667358221220fffda8e7f91d8f0216f245f26522c740ed63c80845f7a33e5540d97c3721056b64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806323e2c52f1461004657806336b6d9441461008a578063aea91078146100af575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009d6100983660046101dd565b6100d8565b60405160ff9091168152602001610081565b6100ca6100bd3660046101dd565b50670de0b6b3a764000090565b604051908152602001610081565b600060016100ea565b60405180910390fd5b6000196001600160a01b038216016101445760405162461bcd60e51b815260206004820152601f60248201527f4669786564207072696365206665656473206e6f7420737570706f727465640060448201526064016100e1565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610184573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a89190610206565b6001600160a01b03929092166000908152602081905260409020805460ff191660ff84161790555092915050565b9392505050565b6000602082840312156101ef57600080fd5b81356001600160a01b03811681146101d657600080fd5b60006020828403121561021857600080fd5b815160ff811681146101d657600080fd5b634e487b7160e01b600052601160045260246000fd5b60018411156102765780850481111561025a5761025a610229565b600184161561026857908102905b60019390931c92800261023f565b93509391505056fea2646970667358221220fffda8e7f91d8f0216f245f26522c740ed63c80845f7a33e5540d97c3721056b64736f6c634300081c0033", + "libraries": {}, + "devdoc": { + "kind": "dev", + "methods": { + "cacheDecimals(address)": { + "params": { + "asset": "address of the asset" + }, + "returns": { + "_0": "uint8 corresponding asset decimals" + } + }, + "price(address)": { + "params": { + "asset": "address of the asset" + }, + "returns": { + "_0": "uint256 unit price for 1 asset unit, in 18 decimal fixed" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "cacheDecimals(address)": { + "notice": "Before an asset/feed price is fetches for the first time the decimals need to be cached. This is a gas optimization" + }, + "price(address)": { + "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." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 809, + "contract": "contracts/oracle/OSonicOracleRouter.sol:OSonicOracleRouter", + "label": "decimalsCache", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint8)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_uint8)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint8)", + "numberOfBytes": "32", + "value": "t_uint8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/contracts/deployments/sonic/solcInputs/115fd4d0d3af5a2dabc9b75908a4db81.json b/contracts/deployments/sonic/solcInputs/115fd4d0d3af5a2dabc9b75908a4db81.json new file mode 100644 index 0000000000..d287d1358b --- /dev/null +++ b/contracts/deployments/sonic/solcInputs/115fd4d0d3af5a2dabc9b75908a4db81.json @@ -0,0 +1,66 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "contracts/interfaces/chainlink/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n" + }, + "contracts/interfaces/IBasicToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBasicToken {\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOracle {\n /**\n * @dev returns the asset price in USD, in 8 decimal digits.\n *\n * The version of priceProvider deployed for OETH has 18 decimal digits\n */\n function price(address asset) external view returns (uint256);\n}\n" + }, + "contracts/oracle/AbstractOracleRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interfaces/chainlink/AggregatorV3Interface.sol\";\nimport { IOracle } from \"../interfaces/IOracle.sol\";\nimport { Helpers } from \"../utils/Helpers.sol\";\nimport { StableMath } from \"../utils/StableMath.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\n// @notice Abstract functionality that is shared between various Oracle Routers\nabstract contract AbstractOracleRouter is IOracle {\n using StableMath for uint256;\n using SafeCast for int256;\n\n uint256 internal constant MIN_DRIFT = 0.7e18;\n uint256 internal constant MAX_DRIFT = 1.3e18;\n address internal constant FIXED_PRICE =\n 0x0000000000000000000000000000000000000001;\n // Maximum allowed staleness buffer above normal Oracle maximum staleness\n uint256 internal constant STALENESS_BUFFER = 1 days;\n mapping(address => uint8) internal decimalsCache;\n\n /**\n * @dev The price feed contract to use for a particular asset along with\n * maximum data staleness\n * @param asset address of the asset\n * @return feedAddress address of the price feed for the asset\n * @return maxStaleness maximum acceptable data staleness duration\n */\n function feedMetadata(address asset)\n internal\n view\n virtual\n returns (address feedAddress, uint256 maxStaleness);\n\n /**\n * @notice Returns the total price in 18 digit unit for a given asset.\n * @param asset address of the asset\n * @return uint256 unit price for 1 asset unit, in 18 decimal fixed\n */\n function price(address asset)\n external\n view\n virtual\n override\n returns (uint256)\n {\n (address _feed, uint256 maxStaleness) = feedMetadata(asset);\n require(_feed != address(0), \"Asset not available\");\n require(_feed != FIXED_PRICE, \"Fixed price feeds not supported\");\n\n // slither-disable-next-line unused-return\n (, int256 _iprice, , uint256 updatedAt, ) = AggregatorV3Interface(_feed)\n .latestRoundData();\n\n require(\n updatedAt + maxStaleness >= block.timestamp,\n \"Oracle price too old\"\n );\n\n uint8 decimals = getDecimals(_feed);\n\n uint256 _price = _iprice.toUint256().scaleBy(18, decimals);\n if (shouldBePegged(asset)) {\n require(_price <= MAX_DRIFT, \"Oracle: Price exceeds max\");\n require(_price >= MIN_DRIFT, \"Oracle: Price under min\");\n }\n return _price;\n }\n\n function getDecimals(address _feed) internal view virtual returns (uint8) {\n uint8 decimals = decimalsCache[_feed];\n require(decimals > 0, \"Oracle: Decimals not cached\");\n return decimals;\n }\n\n /**\n * @notice Before an asset/feed price is fetches for the first time the\n * decimals need to be cached. This is a gas optimization\n * @param asset address of the asset\n * @return uint8 corresponding asset decimals\n */\n function cacheDecimals(address asset) external returns (uint8) {\n (address _feed, ) = feedMetadata(asset);\n require(_feed != address(0), \"Asset not available\");\n require(_feed != FIXED_PRICE, \"Fixed price feeds not supported\");\n\n uint8 decimals = AggregatorV3Interface(_feed).decimals();\n decimalsCache[_feed] = decimals;\n return decimals;\n }\n\n function shouldBePegged(address _asset) internal view returns (bool) {\n string memory symbol = Helpers.getSymbol(_asset);\n bytes32 symbolHash = keccak256(abi.encodePacked(symbol));\n return\n symbolHash == keccak256(abi.encodePacked(\"DAI\")) ||\n symbolHash == keccak256(abi.encodePacked(\"USDC\")) ||\n symbolHash == keccak256(abi.encodePacked(\"USDT\"));\n }\n}\n" + }, + "contracts/oracle/OETHFixedOracle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { OETHOracleRouter } from \"./OETHOracleRouter.sol\";\n\n// @notice Oracle Router that returns 1e18 for all prices\n// used solely for deployment to testnets\ncontract OETHFixedOracle is OETHOracleRouter {\n constructor(address _auraPriceFeed) OETHOracleRouter(_auraPriceFeed) {}\n\n /**\n * @dev The price feed contract to use for a particular asset along with\n * maximum data staleness\n * @param asset address of the asset\n * @return feedAddress address of the price feed for the asset\n * @return maxStaleness maximum acceptable data staleness duration\n */\n // solhint-disable-next-line no-unused-vars\n function feedMetadata(address asset)\n internal\n view\n virtual\n override\n returns (address feedAddress, uint256 maxStaleness)\n {\n // fixes price for all of the assets\n feedAddress = FIXED_PRICE;\n maxStaleness = 0;\n }\n}\n" + }, + "contracts/oracle/OETHOracleRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interfaces/chainlink/AggregatorV3Interface.sol\";\nimport { AbstractOracleRouter } from \"./AbstractOracleRouter.sol\";\nimport { StableMath } from \"../utils/StableMath.sol\";\n\n// @notice Oracle Router that denominates all prices in ETH\ncontract OETHOracleRouter is AbstractOracleRouter {\n using StableMath for uint256;\n\n address public immutable auraPriceFeed;\n\n constructor(address _auraPriceFeed) {\n auraPriceFeed = _auraPriceFeed;\n }\n\n /**\n * @notice Returns the total price in 18 digit units for a given asset.\n * This implementation does not (!) do range checks as the\n * parent OracleRouter does.\n * @param asset address of the asset\n * @return uint256 unit price for 1 asset unit, in 18 decimal fixed\n */\n function price(address asset)\n external\n view\n virtual\n override\n returns (uint256)\n {\n (address _feed, uint256 maxStaleness) = feedMetadata(asset);\n if (_feed == FIXED_PRICE) {\n return 1e18;\n }\n require(_feed != address(0), \"Asset not available\");\n\n // slither-disable-next-line unused-return\n (, int256 _iprice, , uint256 updatedAt, ) = AggregatorV3Interface(_feed)\n .latestRoundData();\n\n require(\n updatedAt + maxStaleness >= block.timestamp,\n \"Oracle price too old\"\n );\n\n uint8 decimals = getDecimals(_feed);\n uint256 _price = uint256(_iprice).scaleBy(18, decimals);\n return _price;\n }\n\n /**\n * @dev The price feed contract to use for a particular asset along with\n * maximum data staleness\n * @param asset address of the asset\n * @return feedAddress address of the price feed for the asset\n * @return maxStaleness maximum acceptable data staleness duration\n */\n function feedMetadata(address asset)\n internal\n view\n virtual\n override\n returns (address feedAddress, uint256 maxStaleness)\n {\n if (asset == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) {\n // FIXED_PRICE: WETH/ETH\n feedAddress = FIXED_PRICE;\n maxStaleness = 0;\n } else if (asset == 0x5E8422345238F34275888049021821E8E08CAa1f) {\n // frxETH/ETH\n feedAddress = 0xC58F3385FBc1C8AD2c0C9a061D7c13b141D7A5Df;\n maxStaleness = 18 hours + STALENESS_BUFFER;\n } else if (asset == 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84) {\n // https://data.chain.link/ethereum/mainnet/crypto-eth/steth-eth\n // Chainlink: stETH/ETH\n feedAddress = 0x86392dC19c0b719886221c78AB11eb8Cf5c52812;\n maxStaleness = 1 days + STALENESS_BUFFER;\n } else if (asset == 0xae78736Cd615f374D3085123A210448E74Fc6393) {\n // https://data.chain.link/ethereum/mainnet/crypto-eth/reth-eth\n // Chainlink: rETH/ETH\n feedAddress = 0x536218f9E9Eb48863970252233c8F271f554C2d0;\n maxStaleness = 1 days + STALENESS_BUFFER;\n } else if (asset == 0xD533a949740bb3306d119CC777fa900bA034cd52) {\n // https://data.chain.link/ethereum/mainnet/crypto-eth/crv-eth\n // Chainlink: CRV/ETH\n feedAddress = 0x8a12Be339B0cD1829b91Adc01977caa5E9ac121e;\n maxStaleness = 1 days + STALENESS_BUFFER;\n } else if (asset == 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B) {\n // https://data.chain.link/ethereum/mainnet/crypto-eth/cvx-eth\n // Chainlink: CVX/ETH\n feedAddress = 0xC9CbF687f43176B302F03f5e58470b77D07c61c6;\n maxStaleness = 1 days + STALENESS_BUFFER;\n } else if (asset == 0xBe9895146f7AF43049ca1c1AE358B0541Ea49704) {\n // https://data.chain.link/ethereum/mainnet/crypto-eth/cbeth-eth\n // Chainlink: cbETH/ETH\n feedAddress = 0xF017fcB346A1885194689bA23Eff2fE6fA5C483b;\n maxStaleness = 1 days + STALENESS_BUFFER;\n } else if (asset == 0xba100000625a3754423978a60c9317c58a424e3D) {\n // https://data.chain.link/ethereum/mainnet/crypto-eth/bal-eth\n // Chainlink: BAL/ETH\n feedAddress = 0xC1438AA3823A6Ba0C159CfA8D98dF5A994bA120b;\n maxStaleness = 1 days + STALENESS_BUFFER;\n } else if (asset == 0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF) {\n // AURA/ETH\n feedAddress = auraPriceFeed;\n maxStaleness = 0;\n } else {\n revert(\"Asset not available\");\n }\n }\n}\n" + }, + "contracts/oracle/OSonicOracleRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { OETHFixedOracle } from \"./OETHFixedOracle.sol\";\n\n// @notice Oracle Router that returns 1e18 for all prices\n// used solely for deployment to testnets\ncontract OSonicOracleRouter is OETHFixedOracle {\n constructor(address _auraPriceFeed) OETHFixedOracle(_auraPriceFeed) {}\n}\n" + }, + "contracts/utils/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IBasicToken } from \"../interfaces/IBasicToken.sol\";\n\nlibrary Helpers {\n /**\n * @notice Fetch the `symbol()` from an ERC20 token\n * @dev Grabs the `symbol()` from a contract\n * @param _token Address of the ERC20 token\n * @return string Symbol of the ERC20 token\n */\n function getSymbol(address _token) internal view returns (string memory) {\n string memory symbol = IBasicToken(_token).symbol();\n return symbol;\n }\n\n /**\n * @notice Fetch the `decimals()` from an ERC20 token\n * @dev Grabs the `decimals()` from a contract and fails if\n * the decimal value does not live within a certain range\n * @param _token Address of the ERC20 token\n * @return uint256 Decimals of the ERC20 token\n */\n function getDecimals(address _token) internal view returns (uint256) {\n uint256 decimals = IBasicToken(_token).decimals();\n require(\n decimals >= 4 && decimals <= 18,\n \"Token must have sufficient decimal places\"\n );\n\n return decimals;\n }\n}\n" + }, + "contracts/utils/StableMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { SafeMath } from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n// Based on StableMath from Stability Labs Pty. Ltd.\n// https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol\n\nlibrary StableMath {\n using SafeMath for uint256;\n\n /**\n * @dev Scaling unit for use in specific calculations,\n * where 1 * 10**18, or 1e18 represents a unit '1'\n */\n uint256 private constant FULL_SCALE = 1e18;\n\n /***************************************\n Helpers\n ****************************************/\n\n /**\n * @dev Adjust the scale of an integer\n * @param to Decimals to scale to\n * @param from Decimals to scale from\n */\n function scaleBy(\n uint256 x,\n uint256 to,\n uint256 from\n ) internal pure returns (uint256) {\n if (to > from) {\n x = x.mul(10**(to - from));\n } else if (to < from) {\n // slither-disable-next-line divide-before-multiply\n x = x.div(10**(from - to));\n }\n return x;\n }\n\n /***************************************\n Precise Arithmetic\n ****************************************/\n\n /**\n * @dev Multiplies two precise units, and then truncates by the full scale\n * @param x Left hand input to multiplication\n * @param y Right hand input to multiplication\n * @return Result after multiplying the two inputs and then dividing by the shared\n * scale unit\n */\n function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulTruncateScale(x, y, FULL_SCALE);\n }\n\n /**\n * @dev Multiplies two precise units, and then truncates by the given scale. For example,\n * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18\n * @param x Left hand input to multiplication\n * @param y Right hand input to multiplication\n * @param scale Scale unit\n * @return Result after multiplying the two inputs and then dividing by the shared\n * scale unit\n */\n function mulTruncateScale(\n uint256 x,\n uint256 y,\n uint256 scale\n ) internal pure returns (uint256) {\n // e.g. assume scale = fullScale\n // z = 10e18 * 9e17 = 9e36\n uint256 z = x.mul(y);\n // return 9e36 / 1e18 = 9e18\n return z.div(scale);\n }\n\n /**\n * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result\n * @param x Left hand input to multiplication\n * @param y Right hand input to multiplication\n * @return Result after multiplying the two inputs and then dividing by the shared\n * scale unit, rounded up to the closest base unit.\n */\n function mulTruncateCeil(uint256 x, uint256 y)\n internal\n pure\n returns (uint256)\n {\n // e.g. 8e17 * 17268172638 = 138145381104e17\n uint256 scaled = x.mul(y);\n // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17\n uint256 ceil = scaled.add(FULL_SCALE.sub(1));\n // e.g. 13814538111.399...e18 / 1e18 = 13814538111\n return ceil.div(FULL_SCALE);\n }\n\n /**\n * @dev Precisely divides two units, by first scaling the left hand operand. Useful\n * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)\n * @param x Left hand input to division\n * @param y Right hand input to division\n * @return Result after multiplying the left operand by the scale, and\n * executing the division on the right hand input.\n */\n function divPrecisely(uint256 x, uint256 y)\n internal\n pure\n returns (uint256)\n {\n // e.g. 8e18 * 1e18 = 8e36\n uint256 z = x.mul(FULL_SCALE);\n // e.g. 8e36 / 10e18 = 8e17\n return z.div(y);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/contracts/storageLayout/sonic/OSonicOracleRouter.json b/contracts/storageLayout/sonic/OSonicOracleRouter.json new file mode 100644 index 0000000000..ae9b067cfe --- /dev/null +++ b/contracts/storageLayout/sonic/OSonicOracleRouter.json @@ -0,0 +1,27 @@ +{ + "solcVersion": "0.8.28", + "storage": [ + { + "label": "decimalsCache", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint8)", + "contract": "AbstractOracleRouter", + "src": "contracts/oracle/AbstractOracleRouter.sol:21" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_uint8)": { + "label": "mapping(address => uint8)", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } +} \ No newline at end of file