update DPPOracle

This commit is contained in:
tracy
2022-06-22 14:18:37 +08:00
parent a1453561ae
commit eb631f6255
7 changed files with 157 additions and 14 deletions

View File

@@ -20,6 +20,9 @@ import {DPPTrader} from "./DPPTrader.sol";
*/ */
contract DPPOracle is DPPTrader { contract DPPOracle is DPPTrader {
event ToggleOracleStatus(bool isEnabled);
event ChangeOracle(address indexed oracle);
function init( function init(
address owner, address owner,
address maintainer, address maintainer,
@@ -28,8 +31,10 @@ contract DPPOracle is DPPTrader {
uint256 lpFeeRate, uint256 lpFeeRate,
address mtFeeRateModel, address mtFeeRateModel,
uint256 k, uint256 k,
address i, uint256 i,
bool isOpenTWAP address o,
bool isOpenTWAP,
bool isOracleEnabled
) external { ) external {
initOwner(owner); initOwner(owner);
@@ -42,21 +47,36 @@ contract DPPOracle is DPPTrader {
require(lpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE"); require(lpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE");
require(k <= 1e18, "K_OUT_OF_RANGE"); require(k <= 1e18, "K_OUT_OF_RANGE");
require(i != address(0), "INVALID_ORACLE"); require(i > 0 && i <= 1e36, "I_OUT_OF_RANGE");
require(o != address(0), "INVALID_ORACLE");
_LP_FEE_RATE_ = uint64(lpFeeRate); _LP_FEE_RATE_ = uint64(lpFeeRate);
_K_ = uint64(k); _K_ = uint64(k);
_I_ = i; _I_ = uint128(i);
_O_ = o;
_IS_OPEN_TWAP_ = isOpenTWAP; _IS_OPEN_TWAP_ = isOpenTWAP;
_IS_ORACLE_ENABLED = isOracleEnabled;
if(isOpenTWAP) _BLOCK_TIMESTAMP_LAST_ = uint32(block.timestamp % 2**32); if(isOpenTWAP) _BLOCK_TIMESTAMP_LAST_ = uint32(block.timestamp % 2**32);
_resetTargetAndReserve(); _resetTargetAndReserve();
} }
function changeOracle(address newOracle) public preventReentrant onlyOwner {
require(newOracle != address(0), "INVALID_ORACLE");
_O_ = newOracle;
emit ChangeOracle(newOracle);
}
function toggleOracleStatus(bool enabled) public preventReentrant onlyOwner returns (bool) {
_IS_ORACLE_ENABLED = enabled;
emit ToggleOracleStatus(enabled);
return enabled;
}
function tuneParameters( function tuneParameters(
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newI,
uint256 newK, uint256 newK,
uint256 minBaseReserve, uint256 minBaseReserve,
uint256 minQuoteReserve uint256 minQuoteReserve
@@ -67,18 +87,34 @@ contract DPPOracle is DPPTrader {
); );
require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE"); require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE");
require(newK <= 1e18, "K_OUT_OF_RANGE"); require(newK <= 1e18, "K_OUT_OF_RANGE");
require(newI > 0 && newI <= 1e36, "I_OUT_OF_RANGE");
_LP_FEE_RATE_ = uint64(newLpFeeRate); _LP_FEE_RATE_ = uint64(newLpFeeRate);
_K_ = uint64(newK); _K_ = uint64(newK);
_I_ = uint128(newI);
emit LpFeeRateChange(newLpFeeRate); emit LpFeeRateChange(newLpFeeRate);
return true; return true;
} }
function tunePrice(
uint256 newI,
uint256 minBaseReserve,
uint256 minQuoteReserve
) public preventReentrant onlyOwner returns (bool) {
require(
_BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve,
"RESERVE_AMOUNT_IS_NOT_ENOUGH"
);
require(newI > 0 && newI <= 1e36, "I_OUT_OF_RANGE");
_I_ = uint128(newI);
return true;
}
// ============ Version Control ============ // ============ Version Control ============
function version() external pure returns (string memory) { function version() external pure returns (string memory) {
return "DPP Oracle 1.0.0"; return "DPP Oracle 1.1.0";
} }
} }

View File

@@ -62,9 +62,28 @@ contract DPPOracleAdmin is InitializableOwnable {
IDPPOracle(_DPP_).retrieve(to, token, amount); IDPPOracle(_DPP_).retrieve(to, token, amount);
} }
function changeOracle(address newOracle) external notFreezed {
require(
msg.sender == _OWNER_ ||
(IDODOApproveProxy(_DODO_APPROVE_PROXY_).isAllowedProxy(msg.sender)),
"CHANGEORACLE FORBIDDEN!"
);
IDPPOracle(_DPP_).changeOracle(newOracle);
}
function toggleOracleStatus(bool enabled) external notFreezed {
require(
msg.sender == _OWNER_ ||
(IDODOApproveProxy(_DODO_APPROVE_PROXY_).isAllowedProxy(msg.sender)),
"CHANGEORACLE FORBIDDEN!"
);
IDPPOracle(_DPP_).toggleOracleStatus(enabled);
}
function tuneParameters( function tuneParameters(
address operator, address operator,
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newI,
uint256 newK, uint256 newK,
uint256 minBaseReserve, uint256 minBaseReserve,
uint256 minQuoteReserve uint256 minQuoteReserve
@@ -78,16 +97,38 @@ contract DPPOracleAdmin is InitializableOwnable {
return return
IDPPOracle(_DPP_).tuneParameters( IDPPOracle(_DPP_).tuneParameters(
newLpFeeRate, newLpFeeRate,
newI,
newK, newK,
minBaseReserve, minBaseReserve,
minQuoteReserve minQuoteReserve
); );
} }
function tunePrice(
address operator,
uint256 newI,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external notFreezed returns (bool) {
require(
msg.sender == _OWNER_ ||
(IDODOApproveProxy(_DODO_APPROVE_PROXY_).isAllowedProxy(msg.sender) &&
operator == _OPERATOR_),
"TUNEPRICE FORBIDDEN"
);
return
IDPPOracle(_DPP_).tunePrice(
newI,
minBaseReserve,
minQuoteReserve
);
}
function reset( function reset(
address operator, address operator,
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newI,
uint256 newK, uint256 newK,
uint256 baseOutAmount, uint256 baseOutAmount,
uint256 quoteOutAmount, uint256 quoteOutAmount,
@@ -104,6 +145,7 @@ contract DPPOracleAdmin is InitializableOwnable {
IDPPOracle(_DPP_).reset( IDPPOracle(_DPP_).reset(
_OWNER_, //only support asset transfer out to owner _OWNER_, //only support asset transfer out to owner
newLpFeeRate, newLpFeeRate,
newI,
newK, newK,
baseOutAmount, baseOutAmount,
quoteOutAmount, quoteOutAmount,
@@ -115,6 +157,6 @@ contract DPPOracleAdmin is InitializableOwnable {
// ============ Admin Version Control ============ // ============ Admin Version Control ============
function version() external pure returns (string memory) { function version() external pure returns (string memory) {
return "DPPOracle Admin 1.0.0"; // 1.0.0 return "DPPOracle Admin 1.1.0";
} }
} }

View File

@@ -21,6 +21,7 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard {
using SafeMath for uint256; using SafeMath for uint256;
bool public _IS_OPEN_TWAP_ = false; bool public _IS_OPEN_TWAP_ = false;
bool public _IS_ORACLE_ENABLED = true;
// ============ Core Address ============ // ============ Core Address ============
@@ -45,12 +46,17 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard {
uint64 public _LP_FEE_RATE_; uint64 public _LP_FEE_RATE_;
uint64 public _K_; uint64 public _K_;
address public _I_; uint128 public _I_;
address public _O_;
// ============ Helper Functions ============ // ============ Helper Functions ============
function getPMMState() public view returns (PMMPricing.PMMState memory state) { function getPMMState() public view returns (PMMPricing.PMMState memory state) {
state.i = IOracle(_I_).prices(address(_BASE_TOKEN_)); if (_IS_ORACLE_ENABLED) {
state.i = IOracle(_O_).prices(address(_BASE_TOKEN_));
} else {
state.i = _I_;
}
state.K = _K_; state.K = _K_;
state.B = _BASE_RESERVE_; state.B = _BASE_RESERVE_;
state.Q = _QUOTE_RESERVE_; state.Q = _QUOTE_RESERVE_;

View File

@@ -38,9 +38,11 @@ contract DPPTrader is DPPVault {
event RChange(PMMPricing.RState newRState); event RChange(PMMPricing.RState newRState);
modifier isOraclePriceValid() { modifier isPriceValid() {
bool isFeasible = IOracle(_I_).isFeasible(address(_BASE_TOKEN_)); if (_IS_ORACLE_ENABLED) {
require(isFeasible, "ORACLE_PRICE_INVALID"); bool isFeasible = IOracle(_I_).isFeasible(address(_BASE_TOKEN_));
require(isFeasible, "ORACLE_PRICE_INVALID");
}
_; _;
} }
@@ -49,7 +51,7 @@ contract DPPTrader is DPPVault {
function sellBase(address to) function sellBase(address to)
external external
preventReentrant preventReentrant
isOraclePriceValid isPriceValid
returns (uint256 receiveQuoteAmount) returns (uint256 receiveQuoteAmount)
{ {
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this)); uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
@@ -85,7 +87,7 @@ contract DPPTrader is DPPVault {
function sellQuote(address to) function sellQuote(address to)
external external
preventReentrant preventReentrant
isOraclePriceValid isPriceValid
returns (uint256 receiveBaseAmount) returns (uint256 receiveBaseAmount)
{ {
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this)); uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
@@ -126,7 +128,7 @@ contract DPPTrader is DPPVault {
uint256 quoteAmount, uint256 quoteAmount,
address _assetTo, address _assetTo,
bytes calldata data bytes calldata data
) external isOraclePriceValid preventReentrant { ) external isPriceValid preventReentrant {
address assetTo = _assetTo; address assetTo = _assetTo;
_transferBaseOut(assetTo, baseAmount); _transferBaseOut(assetTo, baseAmount);
_transferQuoteOut(assetTo, quoteAmount); _transferQuoteOut(assetTo, quoteAmount);

View File

@@ -123,6 +123,7 @@ contract DPPVault is DPPStorage {
function reset( function reset(
address assetTo, address assetTo,
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newI,
uint256 newK, uint256 newK,
uint256 baseOutAmount, uint256 baseOutAmount,
uint256 quoteOutAmount, uint256 quoteOutAmount,
@@ -135,9 +136,11 @@ contract DPPVault is DPPStorage {
); );
require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE"); require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE");
require(newK <= 1e18, "K_OUT_OF_RANGE"); require(newK <= 1e18, "K_OUT_OF_RANGE");
require(newI > 0 && newI <= 1e36, "I_OUT_OF_RANGE");
_LP_FEE_RATE_ = uint64(newLpFeeRate); _LP_FEE_RATE_ = uint64(newLpFeeRate);
_K_ = uint64(newK); _K_ = uint64(newK);
_I_ = uint128(newI);
_transferBaseOut(assetTo, baseOutAmount); _transferBaseOut(assetTo, baseOutAmount);
_transferQuoteOut(assetTo, quoteOutAmount); _transferQuoteOut(assetTo, quoteOutAmount);

View File

@@ -0,0 +1,42 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IOracle} from "../../intf/IOracle.sol";
interface IWooracle {
function timestamp() external view returns (uint256);
function isFeasible(address base) external view returns (bool);
function getPrice(address base) external view returns (uint256);
function price(address base) external view returns (uint256 priceNow, bool feasible);
}
contract OracleAdapter is IOracle {
IWooracle oracle;
constructor(address oracleAddress) public {
oracle = IWooracle(oracleAddress);
}
function getPrice(address base) external override view returns (uint256 latestPrice,bool isValid,bool isStale,uint256 timestamp) {
latestPrice = oracle.getPrice(base);
isValid = oracle.isFeasible(base);
isStale = !isValid;
timestamp = oracle.timestamp();
return (latestPrice, isValid, isStale, timestamp);
}
function prices(address base) external override view returns (uint256) {
return oracle.getPrice(base);
}
function isFeasible(address base) external override view returns (bool) {
return oracle.isFeasible(base);
}
}

View File

@@ -35,6 +35,7 @@ interface IDPPOracle {
function reset( function reset(
address assetTo, address assetTo,
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newI,
uint256 newK, uint256 newK,
uint256 baseOutAmount, uint256 baseOutAmount,
uint256 quoteOutAmount, uint256 quoteOutAmount,
@@ -45,8 +46,19 @@ interface IDPPOracle {
function tuneParameters( function tuneParameters(
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newI,
uint256 newK, uint256 newK,
uint256 minBaseReserve, uint256 minBaseReserve,
uint256 minQuoteReserve uint256 minQuoteReserve
) external returns (bool); ) external returns (bool);
function tunePrice(
uint256 newI,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external returns (bool);
function changeOracle(address newOracle) external;
function toggleOracleStatus(bool enabled) external;
} }