add dppOracle

This commit is contained in:
owen05
2021-06-15 16:42:16 +08:00
parent c7202eeae7
commit d02b9b0eb8
9 changed files with 787 additions and 4 deletions

View File

@@ -8,7 +8,7 @@
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {DPP} from "./DPP.sol";
import {DPP} from "../DPP.sol";
/**
* @title DODO PrivatePool

View File

@@ -8,9 +8,9 @@
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IDPP} from "../intf/IDPP.sol";
import {IDODOApproveProxy} from "../../SmartRoute/DODOApproveProxy.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {IDPP} from "../../intf/IDPP.sol";
import {IDODOApproveProxy} from "../../../SmartRoute/DODOApproveProxy.sol";
import {InitializableOwnable} from "../../../lib/InitializableOwnable.sol";
/**
* @title DPPAdmin

View File

@@ -0,0 +1,84 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IFeeRateModel} from "../../../lib/FeeRateModel.sol";
import {IERC20} from "../../../intf/IERC20.sol";
import {DPPTrader} from "./DPPTrader.sol";
/**
* @title DODO PrivatePool
* @author DODO Breeder
*
* @notice DODOPrivatePool with oracle price
*/
contract DPPOracle is DPPTrader {
function init(
address owner,
address maintainer,
address baseTokenAddress,
address quoteTokenAddress,
uint256 lpFeeRate,
address mtFeeRateModel,
uint256 k,
address i,
bool isOpenTWAP
) external {
initOwner(owner);
require(baseTokenAddress != quoteTokenAddress, "BASE_QUOTE_CAN_NOT_BE_SAME");
_BASE_TOKEN_ = IERC20(baseTokenAddress);
_QUOTE_TOKEN_ = IERC20(quoteTokenAddress);
_MAINTAINER_ = maintainer;
_MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel);
require(lpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE");
require(k <= 1e18, "K_OUT_OF_RANGE");
require(i != address(0), "INVALID_ORACLE");
_LP_FEE_RATE_ = uint64(lpFeeRate);
_K_ = uint64(k);
_I_ = i;
_IS_OPEN_TWAP_ = isOpenTWAP;
if(isOpenTWAP) _BLOCK_TIMESTAMP_LAST_ = uint32(block.timestamp % 2**32);
_resetTargetAndReserve();
}
function tuneParameters(
uint256 newLpFeeRate,
uint256 newK,
uint256 minBaseReserve,
uint256 minQuoteReserve
) public preventReentrant onlyOwner returns (bool) {
require(
_BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve,
"RESERVE_AMOUNT_IS_NOT_ENOUGH"
);
require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE");
require(newK <= 1e18, "K_OUT_OF_RANGE");
_LP_FEE_RATE_ = uint64(newLpFeeRate);
_K_ = uint64(newK);
emit LpFeeRateChange(newLpFeeRate);
return true;
}
// ============ Version Control ============
function version() external pure returns (string memory) {
return "DPP Oracle 1.0.0";
}
}

View File

@@ -0,0 +1,120 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IDPPOracle} from "../../intf/IDPPOracle.sol";
import {IDODOApproveProxy} from "../../../SmartRoute/DODOApproveProxy.sol";
import {InitializableOwnable} from "../../../lib/InitializableOwnable.sol";
/**
* @title DPPOracleAdmin
* @author DODO Breeder
*
* @notice Admin of Oracle DODOPrivatePool
*/
contract DPPOracleAdmin is InitializableOwnable {
address public _DPP_;
address public _OPERATOR_;
address public _DODO_APPROVE_PROXY_;
uint256 public _FREEZE_TIMESTAMP_;
modifier notFreezed() {
require(block.timestamp >= _FREEZE_TIMESTAMP_, "ADMIN_FREEZED");
_;
}
function init(
address owner,
address dpp,
address operator,
address dodoApproveProxy
) external {
initOwner(owner);
_DPP_ = dpp;
_OPERATOR_ = operator;
_DODO_APPROVE_PROXY_ = dodoApproveProxy;
}
function sync() external notFreezed onlyOwner {
IDPPOracle(_DPP_).ratioSync();
}
function setFreezeTimestamp(uint256 timestamp) external notFreezed onlyOwner {
_FREEZE_TIMESTAMP_ = timestamp;
}
function setOperator(address newOperator) external notFreezed onlyOwner {
_OPERATOR_ = newOperator;
}
function retrieve(
address payable to,
address token,
uint256 amount
) external notFreezed onlyOwner {
IDPPOracle(_DPP_).retrieve(to, token, amount);
}
function tuneParameters(
address operator,
uint256 newLpFeeRate,
uint256 newK,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external notFreezed returns (bool) {
require(
msg.sender == _OWNER_ ||
(IDODOApproveProxy(_DODO_APPROVE_PROXY_).isAllowedProxy(msg.sender) &&
operator == _OPERATOR_),
"TUNEPARAMS FORBIDDEN!"
);
return
IDPPOracle(_DPP_).tuneParameters(
newLpFeeRate,
newK,
minBaseReserve,
minQuoteReserve
);
}
function reset(
address operator,
uint256 newLpFeeRate,
uint256 newK,
uint256 baseOutAmount,
uint256 quoteOutAmount,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external notFreezed returns (bool) {
require(
msg.sender == _OWNER_ ||
(IDODOApproveProxy(_DODO_APPROVE_PROXY_).isAllowedProxy(msg.sender) &&
operator == _OPERATOR_),
"RESET FORBIDDEN"
);
return
IDPPOracle(_DPP_).reset(
_OWNER_, //only support asset transfer out to owner
newLpFeeRate,
newK,
baseOutAmount,
quoteOutAmount,
minBaseReserve,
minQuoteReserve
);
}
// ============ Admin Version Control ============
function version() external pure returns (string memory) {
return "DPPOracle Admin 1.0.0"; // 1.0.0
}
}

View File

@@ -0,0 +1,89 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "../../../lib/InitializableOwnable.sol";
import {SafeMath} from "../../../lib/SafeMath.sol";
import {DecimalMath} from "../../../lib/DecimalMath.sol";
import {ReentrancyGuard} from "../../../lib/ReentrancyGuard.sol";
import {IFeeRateModel} from "../../../lib/FeeRateModel.sol";
import {IERC20} from "../../../intf/IERC20.sol";
import {PMMPricing} from "../../../lib/PMMPricing.sol";
import {IOracle} from "../../intf/IOracle.sol";
contract DPPStorage is InitializableOwnable, ReentrancyGuard {
using SafeMath for uint256;
bool public _IS_OPEN_TWAP_ = false;
// ============ Core Address ============
address public _MAINTAINER_;
IERC20 public _BASE_TOKEN_;
IERC20 public _QUOTE_TOKEN_;
uint112 public _BASE_RESERVE_;
uint112 public _QUOTE_RESERVE_;
uint32 public _BLOCK_TIMESTAMP_LAST_;
uint112 public _BASE_TARGET_;
uint112 public _QUOTE_TARGET_;
uint32 public _RState_;
uint256 public _BASE_PRICE_CUMULATIVE_LAST_;
// ============ Variables for Pricing ============
IFeeRateModel public _MT_FEE_RATE_MODEL_;
uint64 public _LP_FEE_RATE_;
uint64 public _K_;
address public _I_;
// ============ Helper Functions ============
function getPMMState() public view returns (PMMPricing.PMMState memory state) {
(state.i,,,) = IOracle(_I_).getPrice(address(_BASE_TOKEN_));
state.K = _K_;
state.B = _BASE_RESERVE_;
state.Q = _QUOTE_RESERVE_;
state.B0 = _BASE_TARGET_;
state.Q0 = _QUOTE_TARGET_;
state.R = PMMPricing.RState(_RState_);
PMMPricing.adjustedTarget(state);
}
function getPMMStateForCall()
external
view
returns (
uint256 i,
uint256 K,
uint256 B,
uint256 Q,
uint256 B0,
uint256 Q0,
uint256 R
)
{
PMMPricing.PMMState memory state = getPMMState();
i = state.i;
K = state.K;
B = state.B;
Q = state.Q;
B0 = state.B0;
Q0 = state.Q0;
R = uint256(state.R);
}
function getMidPrice() public view returns (uint256 midPrice) {
return PMMPricing.getMidPrice(getPMMState());
}
}

View File

@@ -0,0 +1,255 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {DPPVault} from "./DPPVault.sol";
import {SafeMath} from "../../../lib/SafeMath.sol";
import {DecimalMath} from "../../../lib/DecimalMath.sol";
import {PMMPricing} from "../../../lib/PMMPricing.sol";
import {IDODOCallee} from "../../../intf/IDODOCallee.sol";
import {IOracle} from "../../intf/IOracle.sol";
contract DPPTrader is DPPVault {
using SafeMath for uint256;
// ============ Events ============
event DODOSwap(
address fromToken,
address toToken,
uint256 fromAmount,
uint256 toAmount,
address trader,
address receiver
);
event DODOFlashLoan(
address borrower,
address assetTo,
uint256 baseAmount,
uint256 quoteAmount
);
event RChange(PMMPricing.RState newRState);
modifier isOraclePriceValid() {
(, bool isValid, bool isStale,) = IOracle(_I_).getPrice(address(_BASE_TOKEN_));
require(isValid, "ORACLE_PRICE_INVALID");
require(!isStale, "ORACLE_PRICE_STALE");
_;
}
// ============ Trade Functions ============
function sellBase(address to)
external
preventReentrant
isOraclePriceValid
returns (uint256 receiveQuoteAmount)
{
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 baseInput = baseBalance.sub(uint256(_BASE_RESERVE_));
uint256 mtFee;
uint256 newBaseTarget;
PMMPricing.RState newRState;
(receiveQuoteAmount, mtFee, newRState, newBaseTarget) = querySellBase(tx.origin, baseInput);
_transferQuoteOut(to, receiveQuoteAmount);
_transferQuoteOut(_MAINTAINER_, mtFee);
// update TARGET
if (_RState_ != uint32(newRState)) {
require(newBaseTarget <= uint112(-1),"OVERFLOW");
_BASE_TARGET_ = uint112(newBaseTarget);
_RState_ = uint32(newRState);
emit RChange(newRState);
}
_setReserve(baseBalance, _QUOTE_TOKEN_.balanceOf(address(this)));
emit DODOSwap(
address(_BASE_TOKEN_),
address(_QUOTE_TOKEN_),
baseInput,
receiveQuoteAmount,
msg.sender,
to
);
}
function sellQuote(address to)
external
preventReentrant
isOraclePriceValid
returns (uint256 receiveBaseAmount)
{
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
uint256 quoteInput = quoteBalance.sub(uint256(_QUOTE_RESERVE_));
uint256 mtFee;
uint256 newQuoteTarget;
PMMPricing.RState newRState;
(receiveBaseAmount, mtFee, newRState, newQuoteTarget) = querySellQuote(
tx.origin,
quoteInput
);
_transferBaseOut(to, receiveBaseAmount);
_transferBaseOut(_MAINTAINER_, mtFee);
// update TARGET
if (_RState_ != uint32(newRState)) {
require(newQuoteTarget <= uint112(-1),"OVERFLOW");
_QUOTE_TARGET_ = uint112(newQuoteTarget);
_RState_ = uint32(newRState);
emit RChange(newRState);
}
_setReserve(_BASE_TOKEN_.balanceOf(address(this)), quoteBalance);
emit DODOSwap(
address(_QUOTE_TOKEN_),
address(_BASE_TOKEN_),
quoteInput,
receiveBaseAmount,
msg.sender,
to
);
}
function flashLoan(
uint256 baseAmount,
uint256 quoteAmount,
address _assetTo,
bytes calldata data
) external isOraclePriceValid preventReentrant {
address assetTo = _assetTo;
_transferBaseOut(assetTo, baseAmount);
_transferQuoteOut(assetTo, quoteAmount);
if (data.length > 0)
IDODOCallee(assetTo).DPPFlashLoanCall(msg.sender, baseAmount, quoteAmount, data);
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
// no input -> pure loss
require(
baseBalance >= _BASE_RESERVE_ || quoteBalance >= _QUOTE_RESERVE_,
"FLASH_LOAN_FAILED"
);
// sell quote case
// quote input + base output
if (baseBalance < _BASE_RESERVE_) {
uint256 quoteInput = quoteBalance.sub(uint256(_QUOTE_RESERVE_));
(
uint256 receiveBaseAmount,
uint256 mtFee,
PMMPricing.RState newRState,
uint256 newQuoteTarget
) = querySellQuote(tx.origin, quoteInput); // revert if quoteBalance<quoteReserve
require(uint256(_BASE_RESERVE_).sub(baseBalance) <= receiveBaseAmount, "FLASH_LOAN_FAILED");
_transferBaseOut(_MAINTAINER_, mtFee);
if (_RState_ != uint32(newRState)) {
require(newQuoteTarget <= uint112(-1),"OVERFLOW");
_QUOTE_TARGET_ = uint112(newQuoteTarget);
_RState_ = uint32(newRState);
emit RChange(newRState);
}
emit DODOSwap(
address(_QUOTE_TOKEN_),
address(_BASE_TOKEN_),
quoteInput,
receiveBaseAmount,
msg.sender,
assetTo
);
}
// sell base case
// base input + quote output
if (quoteBalance < _QUOTE_RESERVE_) {
uint256 baseInput = baseBalance.sub(uint256(_BASE_RESERVE_));
(
uint256 receiveQuoteAmount,
uint256 mtFee,
PMMPricing.RState newRState,
uint256 newBaseTarget
) = querySellBase(tx.origin, baseInput); // revert if baseBalance<baseReserve
require(uint256(_QUOTE_RESERVE_).sub(quoteBalance) <= receiveQuoteAmount, "FLASH_LOAN_FAILED");
_transferQuoteOut(_MAINTAINER_, mtFee);
if (_RState_ != uint32(newRState)) {
require(newBaseTarget <= uint112(-1),"OVERFLOW");
_BASE_TARGET_ = uint112(newBaseTarget);
_RState_ = uint32(newRState);
emit RChange(newRState);
}
emit DODOSwap(
address(_BASE_TOKEN_),
address(_QUOTE_TOKEN_),
baseInput,
receiveQuoteAmount,
msg.sender,
assetTo
);
}
_sync();
emit DODOFlashLoan(msg.sender, assetTo, baseAmount, quoteAmount);
}
// ============ Query Functions ============
function querySellBase(address trader, uint256 payBaseAmount)
public
view
returns (
uint256 receiveQuoteAmount,
uint256 mtFee,
PMMPricing.RState newRState,
uint256 newBaseTarget
)
{
PMMPricing.PMMState memory state = getPMMState();
(receiveQuoteAmount, newRState) = PMMPricing.sellBaseToken(state, payBaseAmount);
uint256 lpFeeRate = _LP_FEE_RATE_;
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader);
mtFee = DecimalMath.mulFloor(receiveQuoteAmount, mtFeeRate);
receiveQuoteAmount = receiveQuoteAmount
.sub(DecimalMath.mulFloor(receiveQuoteAmount, lpFeeRate))
.sub(mtFee);
newBaseTarget = state.B0;
}
function querySellQuote(address trader, uint256 payQuoteAmount)
public
view
returns (
uint256 receiveBaseAmount,
uint256 mtFee,
PMMPricing.RState newRState,
uint256 newQuoteTarget
)
{
PMMPricing.PMMState memory state = getPMMState();
(receiveBaseAmount, newRState) = PMMPricing.sellQuoteToken(state, payQuoteAmount);
uint256 lpFeeRate = _LP_FEE_RATE_;
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader);
mtFee = DecimalMath.mulFloor(receiveBaseAmount, mtFeeRate);
receiveBaseAmount = receiveBaseAmount
.sub(DecimalMath.mulFloor(receiveBaseAmount, lpFeeRate))
.sub(mtFee);
newQuoteTarget = state.Q0;
}
}

View File

@@ -0,0 +1,171 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {DPPStorage} from "./DPPStorage.sol";
import {IERC20} from "../../../intf/IERC20.sol";
import {IDODOCallee} from "../../../intf/IDODOCallee.sol";
import {SafeMath} from "../../../lib/SafeMath.sol";
import {DecimalMath} from "../../../lib/DecimalMath.sol";
import {SafeERC20} from "../../../lib/SafeERC20.sol";
import {PMMPricing} from "../../../lib/PMMPricing.sol";
contract DPPVault is DPPStorage {
using SafeMath for uint256;
using SafeERC20 for IERC20;
// ============ Events ============
event LpFeeRateChange(uint256 newLpFeeRate);
// ============ View Functions ============
function getVaultReserve() external view returns (uint256 baseReserve, uint256 quoteReserve) {
baseReserve = _BASE_RESERVE_;
quoteReserve = _QUOTE_RESERVE_;
}
function getUserFeeRate(address user)
external
view
returns (uint256 lpFeeRate, uint256 mtFeeRate)
{
lpFeeRate = _LP_FEE_RATE_;
mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(user);
}
// ============ Get Input ============
function getBaseInput() public view returns (uint256 input) {
return _BASE_TOKEN_.balanceOf(address(this)).sub(uint256(_BASE_RESERVE_));
}
function getQuoteInput() public view returns (uint256 input) {
return _QUOTE_TOKEN_.balanceOf(address(this)).sub(uint256(_QUOTE_RESERVE_));
}
// ============ TWAP UPDATE ===========
function _twapUpdate() internal {
uint32 blockTimestamp = uint32(block.timestamp % 2**32);
uint32 timeElapsed = blockTimestamp - _BLOCK_TIMESTAMP_LAST_;
if (timeElapsed > 0 && _BASE_RESERVE_ != 0 && _QUOTE_RESERVE_ != 0) {
_BASE_PRICE_CUMULATIVE_LAST_ += getMidPrice() * timeElapsed;
}
_BLOCK_TIMESTAMP_LAST_ = blockTimestamp;
}
// ============ Set Status ============
function _setReserve(uint256 baseReserve, uint256 quoteReserve) internal {
require(baseReserve <= uint112(-1) && quoteReserve <= uint112(-1), "OVERFLOW");
_BASE_RESERVE_ = uint112(baseReserve);
_QUOTE_RESERVE_ = uint112(quoteReserve);
if(_IS_OPEN_TWAP_) _twapUpdate();
}
function _sync() internal {
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
if (baseBalance != _BASE_RESERVE_) {
_BASE_RESERVE_ = uint112(baseBalance);
}
if (quoteBalance != _QUOTE_RESERVE_) {
_QUOTE_RESERVE_ = uint112(quoteBalance);
}
if(_IS_OPEN_TWAP_) _twapUpdate();
}
function _resetTargetAndReserve() internal {
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
_BASE_RESERVE_ = uint112(baseBalance);
_QUOTE_RESERVE_ = uint112(quoteBalance);
_BASE_TARGET_ = uint112(baseBalance);
_QUOTE_TARGET_ = uint112(quoteBalance);
_RState_ = uint32(PMMPricing.RState.ONE);
if(_IS_OPEN_TWAP_) _twapUpdate();
}
function ratioSync() external preventReentrant onlyOwner {
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
if (baseBalance != _BASE_RESERVE_) {
_BASE_TARGET_ = uint112(uint256(_BASE_TARGET_).mul(baseBalance).div(uint256(_BASE_RESERVE_)));
_BASE_RESERVE_ = uint112(baseBalance);
}
if (quoteBalance != _QUOTE_RESERVE_) {
_QUOTE_TARGET_ = uint112(uint256(_QUOTE_TARGET_).mul(quoteBalance).div(uint256(_QUOTE_RESERVE_)));
_QUOTE_RESERVE_ = uint112(quoteBalance);
}
if(_IS_OPEN_TWAP_) _twapUpdate();
}
function reset(
address assetTo,
uint256 newLpFeeRate,
uint256 newK,
uint256 baseOutAmount,
uint256 quoteOutAmount,
uint256 minBaseReserve,
uint256 minQuoteReserve
) public preventReentrant onlyOwner returns (bool) {
require(
_BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve,
"RESERVE_AMOUNT_IS_NOT_ENOUGH"
);
require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE");
require(newK <= 1e18, "K_OUT_OF_RANGE");
_LP_FEE_RATE_ = uint64(newLpFeeRate);
_K_ = uint64(newK);
_transferBaseOut(assetTo, baseOutAmount);
_transferQuoteOut(assetTo, quoteOutAmount);
_resetTargetAndReserve();
emit LpFeeRateChange(newLpFeeRate);
return true;
}
// ============ Asset Out ============
function _transferBaseOut(address to, uint256 amount) internal {
if (amount > 0) {
_BASE_TOKEN_.safeTransfer(to, amount);
}
}
function _transferQuoteOut(address to, uint256 amount) internal {
if (amount > 0) {
_QUOTE_TOKEN_.safeTransfer(to, amount);
}
}
function retrieve(
address to,
address token,
uint256 amount
) external preventReentrant onlyOwner {
require(token != address(_BASE_TOKEN_) && token != address(_QUOTE_TOKEN_), "USE_RESET");
IERC20(token).safeTransfer(to, amount);
}
}

View File

@@ -0,0 +1,52 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface IDPPOracle {
function init(
address owner,
address maintainer,
address baseTokenAddress,
address quoteTokenAddress,
uint256 lpFeeRate,
address mtFeeRateModel,
uint256 k,
address i, //oracle address
bool isOpenTWAP
) external;
function _MT_FEE_RATE_MODEL_() external returns (address);
//=========== admin ==========
function ratioSync() external;
function retrieve(
address payable to,
address token,
uint256 amount
) external;
function reset(
address assetTo,
uint256 newLpFeeRate,
uint256 newK,
uint256 baseOutAmount,
uint256 quoteOutAmount,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external returns (bool);
function tuneParameters(
uint256 newLpFeeRate,
uint256 newK,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external returns (bool);
}

View File

@@ -0,0 +1,12 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
interface IOracle {
function getPrice(address base) external view returns (uint256 latestPrice,bool isValid,bool isStale,uint256 timestamp);
}