编译器
0.8.16+commit.07a7930e
文件 1 的 6:AggregatorV3Interface.sol
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);
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
);
}
文件 2 的 6:D3Oracle.sol
pragma solidity 0.8.16;
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
import {ID3Oracle} from "../../intf/ID3Oracle.sol";
import "../lib/DecimalMath.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
struct PriceSource {
address oracle;
bool isWhitelisted;
uint256 priceTolerance;
uint8 priceDecimal;
uint8 tokenDecimal;
uint256 heartBeat;
}
contract D3Oracle is ID3Oracle, InitializableOwnable {
mapping(address => PriceSource) public priceSources;
address public sequencerFeed;
uint256 private constant GRACE_PERIOD_TIME = 3600;
error SequencerDown();
error GracePeriodNotOver();
constructor() {
initOwner(msg.sender);
}
function setSequencer(address addr) external onlyOwner {
sequencerFeed = addr;
}
function setPriceSource(address token, PriceSource calldata source) external onlyOwner {
priceSources[token] = source;
require(source.priceTolerance <= DecimalMath.ONE && source.priceTolerance >= 1e10, "INVALID_PRICE_TOLERANCE");
}
function setTokenOracleFeasible(address token, bool isAvailable) external onlyOwner {
priceSources[token].isWhitelisted = isAvailable;
}
function getPrice(address token) public view override returns (uint256) {
uint256 price = getPriceFromFeed(token);
return price * 10 ** (36 - priceSources[token].priceDecimal - priceSources[token].tokenDecimal);
}
function getOriginalPrice(address token) public view override returns (uint256, uint8) {
uint256 price = getPriceFromFeed(token);
uint8 priceDecimal = priceSources[token].priceDecimal;
return (price, priceDecimal);
}
function getDec18Price(address token) public view override returns (uint256) {
uint256 price = getPriceFromFeed(token);
return price * 10 ** (18 - priceSources[token].priceDecimal);
}
function isFeasible(address token) external view override returns (bool) {
return priceSources[token].isWhitelisted;
}
function getMaxReceive(address fromToken, address toToken, uint256 fromAmount) external view returns (uint256) {
uint256 fromTlr = priceSources[fromToken].priceTolerance;
uint256 toTlr = priceSources[toToken].priceTolerance;
return DecimalMath.div((fromAmount * getDec18Price(fromToken)) / getDec18Price(toToken), DecimalMath.mul(fromTlr, toTlr));
}
function getPriceFromFeed(address token) internal view returns (uint256) {
checkSequencerActive();
require(priceSources[token].isWhitelisted, "INVALID_TOKEN");
AggregatorV3Interface priceFeed = AggregatorV3Interface(priceSources[token].oracle);
(uint80 roundID, int256 price,, uint256 updatedAt, uint80 answeredInRound) = priceFeed.latestRoundData();
require(price > 0, "Chainlink: Incorrect Price");
require(block.timestamp - updatedAt < priceSources[token].heartBeat, "Chainlink: Stale Price");
require(answeredInRound >= roundID, "Chainlink: Stale Price");
return uint256(price);
}
function checkSequencerActive() internal view {
if (sequencerFeed == address(0)) return;
(, int256 answer, uint256 startedAt, ,) = AggregatorV3Interface(sequencerFeed).latestRoundData();
if (answer == 1) revert SequencerDown();
if (block.timestamp - startedAt <= GRACE_PERIOD_TIME) revert GracePeriodNotOver();
}
}
文件 3 的 6:DecimalMath.sol
pragma solidity 0.8.16;
pragma experimental ABIEncoderV2;
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
library DecimalMath {
uint256 internal constant ONE = 10 ** 18;
uint256 internal constant ONE2 = 10 ** 36;
function mul(uint256 target, uint256 d) internal pure returns (uint256) {
return target * d / (10 ** 18);
}
function mulFloor(uint256 target, uint256 d) internal pure returns (uint256) {
return target * d / (10 ** 18);
}
function mulCeil(uint256 target, uint256 d) internal pure returns (uint256) {
return _divCeil(target * d, 10 ** 18);
}
function div(uint256 target, uint256 d) internal pure returns (uint256) {
return target * (10 ** 18) / d;
}
function divFloor(uint256 target, uint256 d) internal pure returns (uint256) {
return target * (10 ** 18) / d;
}
function divCeil(uint256 target, uint256 d) internal pure returns (uint256) {
return _divCeil(target * (10 ** 18), d);
}
function reciprocalFloor(uint256 target) internal pure returns (uint256) {
return uint256(10 ** 36) / target;
}
function reciprocalCeil(uint256 target) internal pure returns (uint256) {
return _divCeil(uint256(10 ** 36), target);
}
function sqrt(uint256 target) internal pure returns (uint256) {
return Math.sqrt(target * ONE);
}
function powFloor(uint256 target, uint256 e) internal pure returns (uint256) {
if (e == 0) {
return 10 ** 18;
} else if (e == 1) {
return target;
} else {
uint256 p = powFloor(target, e / 2);
p = p * p / (10 ** 18);
if (e % 2 == 1) {
p = p * target / (10 ** 18);
}
return p;
}
}
function _divCeil(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 quotient = a / b;
uint256 remainder = a - quotient * b;
if (remainder > 0) {
return quotient + 1;
} else {
return quotient;
}
}
}
文件 4 的 6:ID3Oracle.sol
pragma solidity 0.8.16;
interface ID3Oracle {
function getMaxReceive(address fromToken, address toToken, uint256 fromAmount) external view returns (uint256);
function getPrice(address base) external view returns (uint256);
function getDec18Price(address base) external view returns(uint256);
function getOriginalPrice(address base) external view returns (uint256 price, uint8 priceDecimal);
function isFeasible(address base) external view returns (bool);
}
文件 5 的 6:InitializableOwnable.sol
pragma solidity 0.8.16;
contract InitializableOwnable {
address public _OWNER_;
address public _NEW_OWNER_;
bool internal _INITIALIZED_;
event OwnershipTransferPrepared(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
modifier notInitialized() {
require(!_INITIALIZED_, "DODO_INITIALIZED");
_;
}
modifier onlyOwner() {
require(msg.sender == _OWNER_, "NOT_OWNER");
_;
}
function initOwner(address newOwner) public notInitialized {
_INITIALIZED_ = true;
_OWNER_ = newOwner;
}
function transferOwnership(address newOwner) public onlyOwner {
emit OwnershipTransferPrepared(_OWNER_, newOwner);
_NEW_OWNER_ = newOwner;
}
function claimOwnership() public {
require(msg.sender == _NEW_OWNER_, "INVALID_CLAIM");
emit OwnershipTransferred(_OWNER_, _NEW_OWNER_);
_OWNER_ = _NEW_OWNER_;
_NEW_OWNER_ = address(0);
}
}
文件 6 的 6:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
{
"compilationTarget": {
"contracts/DODOV3MM/periphery/D3Oracle.sol": "D3Oracle"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"GracePeriodNotOver","type":"error"},{"inputs":[],"name":"SequencerDown","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferPrepared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"_NEW_OWNER_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_OWNER_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getDec18Price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"}],"name":"getMaxReceive","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getOriginalPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"initOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isFeasible","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"priceSources","outputs":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bool","name":"isWhitelisted","type":"bool"},{"internalType":"uint256","name":"priceTolerance","type":"uint256"},{"internalType":"uint8","name":"priceDecimal","type":"uint8"},{"internalType":"uint8","name":"tokenDecimal","type":"uint8"},{"internalType":"uint256","name":"heartBeat","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sequencerFeed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"components":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bool","name":"isWhitelisted","type":"bool"},{"internalType":"uint256","name":"priceTolerance","type":"uint256"},{"internalType":"uint8","name":"priceDecimal","type":"uint8"},{"internalType":"uint8","name":"tokenDecimal","type":"uint8"},{"internalType":"uint256","name":"heartBeat","type":"uint256"}],"internalType":"struct PriceSource","name":"source","type":"tuple"}],"name":"setPriceSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setSequencer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"isAvailable","type":"bool"}],"name":"setTokenOracleFeasible","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]