add twap switch
This commit is contained in:
@@ -30,7 +30,8 @@ contract CP is CPVesting {
|
||||
function init(
|
||||
address[] calldata addressList,
|
||||
uint256[] calldata timeLine,
|
||||
uint256[] calldata valueList
|
||||
uint256[] calldata valueList,
|
||||
bool isOpenTWAP
|
||||
) external {
|
||||
/*
|
||||
Address List
|
||||
@@ -94,6 +95,8 @@ contract CP is CPVesting {
|
||||
|
||||
_TOTAL_BASE_ = _BASE_TOKEN_.balanceOf(address(this));
|
||||
|
||||
_IS_OPEN_TWAP_ = isOpenTWAP;
|
||||
|
||||
require(address(this).balance == _SETTEL_FUND_, "SETTLE_FUND_NOT_MATCH");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,8 @@ contract CPFunding is CPStorage {
|
||||
_poolQuoteToken,
|
||||
3e15, // 0.3% lp feeRate
|
||||
poolI,
|
||||
DecimalMath.ONE
|
||||
DecimalMath.ONE,
|
||||
_IS_OPEN_TWAP_
|
||||
);
|
||||
|
||||
uint256 avgPrice = unUsedBase == 0 ? _I_ : DecimalMath.divCeil(poolQuote, unUsedBase);
|
||||
|
||||
@@ -22,6 +22,7 @@ contract CPStorage is InitializableOwnable, ReentrancyGuard {
|
||||
|
||||
uint256 internal constant _SETTLEMENT_EXPIRE_ = 86400 * 7;
|
||||
uint256 internal constant _SETTEL_FUND_ = 200 finney;
|
||||
bool public _IS_OPEN_TWAP_ = false;
|
||||
|
||||
// ============ Timeline ============
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ interface ICP {
|
||||
function init(
|
||||
address[] calldata addressList,
|
||||
uint256[] calldata timeLine,
|
||||
uint256[] calldata valueList
|
||||
uint256[] calldata valueList,
|
||||
bool isOpenTWAP
|
||||
) external;
|
||||
|
||||
function bid(address to) external;
|
||||
|
||||
@@ -27,7 +27,8 @@ contract DPP is DPPTrader {
|
||||
uint256 lpFeeRate,
|
||||
address mtFeeRateModel,
|
||||
uint256 k,
|
||||
uint256 i
|
||||
uint256 i,
|
||||
bool isOpenTWAP
|
||||
) external {
|
||||
initOwner(owner);
|
||||
|
||||
@@ -44,6 +45,10 @@ contract DPP is DPPTrader {
|
||||
_LP_FEE_RATE_ = uint64(lpFeeRate);
|
||||
_K_ = uint64(k);
|
||||
_I_ = uint128(i);
|
||||
|
||||
_IS_OPEN_TWAP_ = isOpenTWAP;
|
||||
if(isOpenTWAP) _BLOCK_TIMESTAMP_LAST_ = uint32(block.timestamp % 2**32);
|
||||
|
||||
_resetTargetAndReserve();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import {PMMPricing} from "../../lib/PMMPricing.sol";
|
||||
contract DPPStorage is InitializableOwnable, ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
|
||||
bool public _IS_OPEN_TWAP_ = false;
|
||||
|
||||
// ============ Core Address ============
|
||||
|
||||
address public _MAINTAINER_;
|
||||
@@ -26,12 +28,15 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard {
|
||||
IERC20 public _BASE_TOKEN_;
|
||||
IERC20 public _QUOTE_TOKEN_;
|
||||
|
||||
uint128 public _BASE_RESERVE_;
|
||||
uint128 public _QUOTE_RESERVE_;
|
||||
uint112 public _BASE_RESERVE_;
|
||||
uint112 public _QUOTE_RESERVE_;
|
||||
uint32 public _BLOCK_TIMESTAMP_LAST_;
|
||||
|
||||
uint120 public _BASE_TARGET_;
|
||||
uint120 public _QUOTE_TARGET_;
|
||||
uint16 public _RState_;
|
||||
uint112 public _BASE_TARGET_;
|
||||
uint112 public _QUOTE_TARGET_;
|
||||
uint32 public _RState_;
|
||||
|
||||
uint256 public _BASE_PRICE_CUMULATIVE_LAST_;
|
||||
|
||||
// ============ Variables for Pricing ============
|
||||
|
||||
@@ -40,4 +45,44 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard {
|
||||
uint64 public _LP_FEE_RATE_;
|
||||
uint64 public _K_;
|
||||
uint128 public _I_;
|
||||
|
||||
// ============ Helper Functions ============
|
||||
|
||||
function getPMMState() public view returns (PMMPricing.PMMState memory state) {
|
||||
state.i = _I_;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,10 +56,10 @@ contract DPPTrader is DPPVault {
|
||||
_setReserve(baseBalance, _QUOTE_TOKEN_.balanceOf(address(this)));
|
||||
|
||||
// update TARGET
|
||||
if (_RState_ != uint16(newRState)) {
|
||||
_RState_ = uint16(newRState);
|
||||
require(newBaseTarget <= uint120(-1),"OVERFLOW");
|
||||
_BASE_TARGET_ = uint120(newBaseTarget);
|
||||
if (_RState_ != uint32(newRState)) {
|
||||
require(newBaseTarget <= uint112(-1),"OVERFLOW");
|
||||
_BASE_TARGET_ = uint112(newBaseTarget);
|
||||
_RState_ = uint32(newRState);
|
||||
emit RChange(newRState);
|
||||
}
|
||||
|
||||
@@ -93,10 +93,10 @@ contract DPPTrader is DPPVault {
|
||||
_setReserve(_BASE_TOKEN_.balanceOf(address(this)), quoteBalance);
|
||||
|
||||
// update TARGET
|
||||
if (_RState_ != uint16(newRState)) {
|
||||
_RState_ = uint16(newRState);
|
||||
require(newQuoteTarget <= uint120(-1),"OVERFLOW");
|
||||
_QUOTE_TARGET_ = uint120(newQuoteTarget);
|
||||
if (_RState_ != uint32(newRState)) {
|
||||
require(newQuoteTarget <= uint112(-1),"OVERFLOW");
|
||||
_QUOTE_TARGET_ = uint112(newQuoteTarget);
|
||||
_RState_ = uint32(newRState);
|
||||
emit RChange(newRState);
|
||||
}
|
||||
|
||||
@@ -144,10 +144,10 @@ contract DPPTrader is DPPVault {
|
||||
require(uint256(_BASE_RESERVE_).sub(baseBalance) <= receiveBaseAmount, "FLASH_LOAN_FAILED");
|
||||
|
||||
_transferBaseOut(_MAINTAINER_, mtFee);
|
||||
if (_RState_ != uint16(newRState)) {
|
||||
_RState_ = uint16(newRState);
|
||||
require(newQuoteTarget <= uint120(-1),"OVERFLOW");
|
||||
_QUOTE_TARGET_ = uint120(newQuoteTarget);
|
||||
if (_RState_ != uint32(newRState)) {
|
||||
require(newQuoteTarget <= uint112(-1),"OVERFLOW");
|
||||
_QUOTE_TARGET_ = uint112(newQuoteTarget);
|
||||
_RState_ = uint32(newRState);
|
||||
emit RChange(newRState);
|
||||
}
|
||||
emit DODOSwap(
|
||||
@@ -173,10 +173,10 @@ contract DPPTrader is DPPVault {
|
||||
require(uint256(_QUOTE_RESERVE_).sub(quoteBalance) <= receiveQuoteAmount, "FLASH_LOAN_FAILED");
|
||||
|
||||
_transferQuoteOut(_MAINTAINER_, mtFee);
|
||||
if (_RState_ != uint16(newRState)) {
|
||||
_RState_ = uint16(newRState);
|
||||
require(newBaseTarget <= uint120(-1),"OVERFLOW");
|
||||
_BASE_TARGET_ = uint120(newBaseTarget);
|
||||
if (_RState_ != uint32(newRState)) {
|
||||
require(newBaseTarget <= uint112(-1),"OVERFLOW");
|
||||
_BASE_TARGET_ = uint112(newBaseTarget);
|
||||
_RState_ = uint32(newRState);
|
||||
emit RChange(newRState);
|
||||
}
|
||||
emit DODOSwap(
|
||||
@@ -239,44 +239,4 @@ contract DPPTrader is DPPVault {
|
||||
.sub(mtFee);
|
||||
newQuoteTarget = state.Q0;
|
||||
}
|
||||
|
||||
// ============ Helper Functions ============
|
||||
|
||||
function getPMMState() public view returns (PMMPricing.PMMState memory state) {
|
||||
state.i = _I_;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,62 +44,81 @@ contract DPPVault is DPPStorage {
|
||||
// ============ Get Input ============
|
||||
|
||||
function getBaseInput() public view returns (uint256 input) {
|
||||
return _BASE_TOKEN_.balanceOf(address(this)).sub(_BASE_RESERVE_);
|
||||
return _BASE_TOKEN_.balanceOf(address(this)).sub(uint256(_BASE_RESERVE_));
|
||||
}
|
||||
|
||||
function getQuoteInput() public view returns (uint256 input) {
|
||||
return _QUOTE_TOKEN_.balanceOf(address(this)).sub(_QUOTE_RESERVE_);
|
||||
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 <= uint120(-1) && quoteReserve <= uint120(-1), "OVERFLOW");
|
||||
_BASE_RESERVE_ = uint128(baseReserve);
|
||||
_QUOTE_RESERVE_ = uint128(quoteReserve);
|
||||
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 <= uint120(-1) && quoteBalance <= uint120(-1), "OVERFLOW");
|
||||
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
|
||||
|
||||
if (baseBalance != _BASE_RESERVE_) {
|
||||
_BASE_RESERVE_ = uint128(baseBalance);
|
||||
_BASE_RESERVE_ = uint112(baseBalance);
|
||||
}
|
||||
if (quoteBalance != _QUOTE_RESERVE_) {
|
||||
_QUOTE_RESERVE_ = uint128(quoteBalance);
|
||||
_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 <= uint120(-1) && quoteBalance <= uint120(-1), "OVERFLOW");
|
||||
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
|
||||
|
||||
_BASE_RESERVE_ = uint128(baseBalance);
|
||||
_QUOTE_RESERVE_ = uint128(quoteBalance);
|
||||
_BASE_TARGET_ = uint120(baseBalance);
|
||||
_QUOTE_TARGET_ = uint120(quoteBalance);
|
||||
_RState_ = uint16(PMMPricing.RState.ONE);
|
||||
_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 <= uint120(-1) && quoteBalance <= uint120(-1), "OVERFLOW");
|
||||
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
|
||||
|
||||
if (baseBalance != _BASE_RESERVE_) {
|
||||
_BASE_TARGET_ = uint120(uint256(_BASE_TARGET_).mul(baseBalance).div(uint256(_BASE_RESERVE_)));
|
||||
_BASE_RESERVE_ = uint128(baseBalance);
|
||||
_BASE_TARGET_ = uint112(uint256(_BASE_TARGET_).mul(baseBalance).div(uint256(_BASE_RESERVE_)));
|
||||
_BASE_RESERVE_ = uint112(baseBalance);
|
||||
}
|
||||
if (quoteBalance != _QUOTE_RESERVE_) {
|
||||
_QUOTE_TARGET_ = uint120(uint256(_QUOTE_TARGET_).mul(quoteBalance).div(uint256(_QUOTE_RESERVE_)));
|
||||
_QUOTE_RESERVE_ = uint128(quoteBalance);
|
||||
_QUOTE_TARGET_ = uint112(uint256(_QUOTE_TARGET_).mul(quoteBalance).div(uint256(_QUOTE_RESERVE_)));
|
||||
_QUOTE_RESERVE_ = uint112(quoteBalance);
|
||||
}
|
||||
|
||||
if(_IS_OPEN_TWAP_) _twapUpdate();
|
||||
}
|
||||
|
||||
function reset(
|
||||
|
||||
@@ -17,7 +17,8 @@ interface IDPP {
|
||||
uint256 lpFeeRate,
|
||||
address mtFeeRateModel,
|
||||
uint256 k,
|
||||
uint256 i
|
||||
uint256 i,
|
||||
bool isOpenTWAP
|
||||
) external;
|
||||
|
||||
function _MT_FEE_RATE_MODEL_() external returns (address);
|
||||
|
||||
@@ -28,7 +28,8 @@ contract DVM is DVMTrader, DVMFunding {
|
||||
uint256 lpFeeRate,
|
||||
address mtFeeRateModel,
|
||||
uint256 i,
|
||||
uint256 k
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external {
|
||||
require(baseTokenAddress != quoteTokenAddress, "BASE_QUOTE_CAN_NOT_BE_SAME");
|
||||
_BASE_TOKEN_ = IERC20(baseTokenAddress);
|
||||
@@ -44,6 +45,9 @@ contract DVM is DVMTrader, DVMFunding {
|
||||
_MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel);
|
||||
_MAINTAINER_ = maintainer;
|
||||
|
||||
_IS_OPEN_TWAP_ = isOpenTWAP;
|
||||
if(isOpenTWAP) _BLOCK_TIMESTAMP_LAST_ = uint32(block.timestamp % 2**32);
|
||||
|
||||
string memory connect = "_";
|
||||
string memory suffix = "DLP";
|
||||
|
||||
|
||||
@@ -14,10 +14,13 @@ import {DODOMath} from "../../lib/DODOMath.sol";
|
||||
import {DecimalMath} from "../../lib/DecimalMath.sol";
|
||||
import {IFeeRateModel} from "../../lib/FeeRateModel.sol";
|
||||
import {IERC20} from "../../intf/IERC20.sol";
|
||||
import {PMMPricing} from "../../lib/PMMPricing.sol";
|
||||
|
||||
contract DVMStorage is ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
|
||||
bool public _IS_OPEN_TWAP_ = false;
|
||||
|
||||
// ============ Core Address ============
|
||||
|
||||
address public _MAINTAINER_;
|
||||
@@ -25,8 +28,11 @@ contract DVMStorage is ReentrancyGuard {
|
||||
IERC20 public _BASE_TOKEN_;
|
||||
IERC20 public _QUOTE_TOKEN_;
|
||||
|
||||
uint128 public _BASE_RESERVE_;
|
||||
uint128 public _QUOTE_RESERVE_;
|
||||
uint112 public _BASE_RESERVE_;
|
||||
uint112 public _QUOTE_RESERVE_;
|
||||
uint32 public _BLOCK_TIMESTAMP_LAST_;
|
||||
|
||||
uint256 public _BASE_PRICE_CUMULATIVE_LAST_;
|
||||
|
||||
// ============ Shares (ERC20) ============
|
||||
|
||||
@@ -51,4 +57,45 @@ contract DVMStorage is ReentrancyGuard {
|
||||
IFeeRateModel public _MT_FEE_RATE_MODEL_;
|
||||
uint256 public _K_;
|
||||
uint256 public _I_;
|
||||
|
||||
|
||||
// ============ Helper Functions ============
|
||||
|
||||
function getPMMState() public view returns (PMMPricing.PMMState memory state) {
|
||||
state.i = _I_;
|
||||
state.K = _K_;
|
||||
state.B = _BASE_RESERVE_;
|
||||
state.Q = _QUOTE_RESERVE_;
|
||||
state.B0 = 0; // will be calculated in adjustedTarget
|
||||
state.Q0 = 0;
|
||||
state.R = PMMPricing.RState.ABOVE_ONE;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,44 +177,4 @@ contract DVMTrader is DVMVault {
|
||||
.sub(DecimalMath.mulFloor(receiveBaseAmount, lpFeeRate))
|
||||
.sub(mtFee);
|
||||
}
|
||||
|
||||
// ============ Helper Functions ============
|
||||
|
||||
function getPMMState() public view returns (PMMPricing.PMMState memory state) {
|
||||
state.i = _I_;
|
||||
state.K = _K_;
|
||||
state.B = _BASE_RESERVE_;
|
||||
state.Q = _QUOTE_RESERVE_;
|
||||
state.B0 = 0; // will be calculated in adjustedTarget
|
||||
state.Q0 = 0;
|
||||
state.R = PMMPricing.RState.ABOVE_ONE;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,31 +43,46 @@ contract DVMVault is DVMStorage {
|
||||
// ============ Asset In ============
|
||||
|
||||
function getBaseInput() public view returns (uint256 input) {
|
||||
return _BASE_TOKEN_.balanceOf(address(this)).sub(_BASE_RESERVE_);
|
||||
return _BASE_TOKEN_.balanceOf(address(this)).sub(uint256(_BASE_RESERVE_));
|
||||
}
|
||||
|
||||
function getQuoteInput() public view returns (uint256 input) {
|
||||
return _QUOTE_TOKEN_.balanceOf(address(this)).sub(_QUOTE_RESERVE_);
|
||||
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 States ============
|
||||
|
||||
function _setReserve(uint256 baseReserve, uint256 quoteReserve) internal {
|
||||
require(baseReserve <= uint128(-1) && quoteReserve <= uint128(-1), "OVERFLOW");
|
||||
_BASE_RESERVE_ = uint128(baseReserve);
|
||||
_QUOTE_RESERVE_ = uint128(quoteReserve);
|
||||
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 <= uint128(-1) && quoteBalance <= uint128(-1), "OVERFLOW");
|
||||
require(baseBalance <= uint112(-1) && quoteBalance <= uint112(-1), "OVERFLOW");
|
||||
if (baseBalance != _BASE_RESERVE_) {
|
||||
_BASE_RESERVE_ = uint128(baseBalance);
|
||||
_BASE_RESERVE_ = uint112(baseBalance);
|
||||
}
|
||||
if (quoteBalance != _QUOTE_RESERVE_) {
|
||||
_QUOTE_RESERVE_ = uint128(quoteBalance);
|
||||
_QUOTE_RESERVE_ = uint112(quoteBalance);
|
||||
}
|
||||
|
||||
if(_IS_OPEN_TWAP_) _twapUpdate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ interface IDVM {
|
||||
uint256 lpFeeRate,
|
||||
address mtFeeRateModel,
|
||||
uint256 i,
|
||||
uint256 k
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external;
|
||||
|
||||
function _BASE_TOKEN_() external returns (address);
|
||||
|
||||
@@ -105,7 +105,8 @@ contract CrowdPoolingFactory is InitializableOwnable {
|
||||
address baseToken,
|
||||
address quoteToken,
|
||||
uint256[] memory timeLine,
|
||||
uint256[] memory valueList
|
||||
uint256[] memory valueList,
|
||||
bool isOpenTWAP
|
||||
) external valueCheck(cpAddress,baseToken,timeLine,valueList) {
|
||||
{
|
||||
address[] memory addressList = new address[](7);
|
||||
@@ -120,7 +121,8 @@ contract CrowdPoolingFactory is InitializableOwnable {
|
||||
ICP(cpAddress).init(
|
||||
addressList,
|
||||
timeLine,
|
||||
valueList
|
||||
valueList,
|
||||
isOpenTWAP
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,8 @@ contract DPPFactory is InitializableOwnable {
|
||||
address quoteToken,
|
||||
uint256 lpFeeRate,
|
||||
uint256 k,
|
||||
uint256 i
|
||||
uint256 i,
|
||||
bool isOpenTwap
|
||||
) external {
|
||||
{
|
||||
address _dppAddress = dppAddress;
|
||||
@@ -96,7 +97,8 @@ contract DPPFactory is InitializableOwnable {
|
||||
lpFeeRate,
|
||||
_DEFAULT_MT_FEE_RATE_MODEL_,
|
||||
k,
|
||||
i
|
||||
i,
|
||||
isOpenTwap
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ interface IDVMFactory {
|
||||
address quoteToken,
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external returns (address newVendingMachine);
|
||||
}
|
||||
|
||||
@@ -74,7 +75,8 @@ contract DVMFactory is InitializableOwnable {
|
||||
address quoteToken,
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external returns (address newVendingMachine) {
|
||||
newVendingMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_);
|
||||
{
|
||||
@@ -85,7 +87,8 @@ contract DVMFactory is InitializableOwnable {
|
||||
lpFeeRate,
|
||||
_DEFAULT_MT_FEE_RATE_MODEL_,
|
||||
i,
|
||||
k
|
||||
k,
|
||||
isOpenTWAP
|
||||
);
|
||||
}
|
||||
_REGISTRY_[baseToken][quoteToken].push(newVendingMachine);
|
||||
|
||||
@@ -114,6 +114,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k,
|
||||
bool isOpenTWAP,
|
||||
uint256 deadLine
|
||||
)
|
||||
external
|
||||
@@ -131,7 +132,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
_quoteToken,
|
||||
lpFeeRate,
|
||||
i,
|
||||
k
|
||||
k,
|
||||
isOpenTWAP
|
||||
);
|
||||
}
|
||||
|
||||
@@ -234,6 +236,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k,
|
||||
bool isOpenTwap,
|
||||
uint256 deadLine
|
||||
)
|
||||
external
|
||||
@@ -266,7 +269,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
_quoteToken,
|
||||
lpFeeRate,
|
||||
k,
|
||||
i
|
||||
i,
|
||||
isOpenTwap
|
||||
);
|
||||
}
|
||||
|
||||
@@ -658,6 +662,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
uint256 baseInAmount,
|
||||
uint256[] memory timeLine,
|
||||
uint256[] memory valueList,
|
||||
bool isOpenTWAP,
|
||||
uint256 deadLine
|
||||
) external override payable preventReentrant judgeExpired(deadLine) returns (address payable newCrowdPooling) {
|
||||
address _baseToken = baseToken;
|
||||
@@ -681,7 +686,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
_baseToken,
|
||||
_quoteToken,
|
||||
timeLine,
|
||||
valueList
|
||||
valueList,
|
||||
isOpenTWAP
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ interface IDODOV2 {
|
||||
address quoteToken,
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k
|
||||
uint256 k,
|
||||
bool isOpenTWAP
|
||||
) external returns (address newVendingMachine);
|
||||
|
||||
function buyShares(address to) external returns (uint256,uint256,uint256);
|
||||
@@ -59,7 +60,8 @@ interface IDODOV2 {
|
||||
address quoteToken,
|
||||
uint256 lpFeeRate,
|
||||
uint256 k,
|
||||
uint256 i
|
||||
uint256 i,
|
||||
bool isOpenTwap
|
||||
) external;
|
||||
|
||||
function reset(
|
||||
@@ -87,7 +89,8 @@ interface IDODOV2 {
|
||||
address baseToken,
|
||||
address quoteToken,
|
||||
uint256[] memory timeLine,
|
||||
uint256[] memory valueList
|
||||
uint256[] memory valueList,
|
||||
bool isOpenTWAP
|
||||
) external;
|
||||
|
||||
function bid(address to) external;
|
||||
|
||||
@@ -48,6 +48,7 @@ interface IDODOV2Proxy01 {
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k,
|
||||
bool isOpenTWAP,
|
||||
uint256 deadLine
|
||||
) external payable returns (address newVendingMachine, uint256 shares);
|
||||
|
||||
@@ -76,6 +77,7 @@ interface IDODOV2Proxy01 {
|
||||
uint256 lpFeeRate,
|
||||
uint256 i,
|
||||
uint256 k,
|
||||
bool isOpenTwap,
|
||||
uint256 deadLine
|
||||
) external payable returns (address newPrivatePool);
|
||||
|
||||
@@ -95,6 +97,7 @@ interface IDODOV2Proxy01 {
|
||||
uint256 baseInAmount,
|
||||
uint256[] memory timeLine,
|
||||
uint256[] memory valueList,
|
||||
bool isOpenTWAP,
|
||||
uint256 deadLine
|
||||
) external payable returns (address payable newCrowdPooling);
|
||||
|
||||
@@ -111,7 +114,7 @@ interface IDODOV2Proxy01 {
|
||||
uint256 quoteAmount,
|
||||
uint256 baseMinShares,
|
||||
uint256 quoteMinShares,
|
||||
uint8 flag, // 0 erc20 Out 1 baseOutETH 2 quoteOut ETH
|
||||
uint8 flag, // 0 erc20 Out 1 baseInETH 2 quoteInETH
|
||||
uint256 deadLine
|
||||
) external payable returns(uint256, uint256);
|
||||
|
||||
|
||||
@@ -334,3 +334,22 @@ UniAdapter Address: 0x92FC2498B36d1b0Ad3F5315026Dd2529bE05a4Aa
|
||||
DODOV1RouterHelper Address: 0xC972069473a686b1c11Bd9347D719c87e6745d39
|
||||
DODOV2RouteHelper Address: 0x83eE2294e51b3A882dAF160F500775942065B153
|
||||
DODOV1RouterHelper Address: 0xE52ef9814B27C2D0Aed230fed3e6429B8D5A27e7
|
||||
====================================================
|
||||
network type: kovan
|
||||
Deploy time: 2021/1/19 下午12:46:45
|
||||
Deploy type: V2
|
||||
DODOApprove Address: 0x25b5C731822E534A1df126985bb8781f1b979eF9
|
||||
DODOIncentiveAddress: 0x21105B823d058C85503baB85103F7B9907B2A646
|
||||
DODOIncentive Init tx: 0x1ce0420cc07d4324ed8648bc31f1ecb04aa5f7e054d9371c3dd7eb62d83ee396
|
||||
DvmFactoryAddress: 0xFcD6835a9490Dc673944d4AB30F73D7FB8f4fbaA
|
||||
Init DvmFactory Tx: 0xdabf95a17ae069cb45edd5376ba282dcac9aecf7ad58773421238a5d230fcea6
|
||||
DppFactoryAddress: 0x29d2feD26D37167d775f3eCAafAEe3e62B5f4fF6
|
||||
Init DppFactory Tx: 0xd58ea07b0268a5fbc64fdd20b77b4ca857f61317b820ca31c8e299ab860bbc84
|
||||
CpFactoryAddress: 0x2d497332D957E33858714C7114842f4D5DD565A8
|
||||
Init CpFactory Tx: 0x2291d2b4c46989fef831f3d089cd75dc3f59bb46a9b51c0e603cdef8a672e396
|
||||
DODOV2RouteHelper Address: 0xb591abA39645dffd1A94C09E8D5ccC962972d5E0
|
||||
DODOProxyV2 Address: 0x3566c45117438485331c0628e10bA7bE09a1fFCB
|
||||
Init DODOProxyV2 Tx: 0xb0650364cc4ed399b0bfd17d7c42a613be74f4743c2112c30f49bd1b7cbc4800
|
||||
DODOApprove Init tx: 0x018bd3ef5453a2fb8bba51811f16cc9fdf3158bf941da656b8abbb495a215c3c
|
||||
DODOIncentive ChangeProxy tx: 0x763dce9273565bd19a6eb8ea27fc3a268b9de0b327bccc9bf06385fb8bd8161b
|
||||
DODOIncentive OpenSwitch tx: 0x3042d4bb1a4f8110a78ffd53846ecac94b0ea13359334ce4d6bcdd2a1ea7b8e9
|
||||
|
||||
@@ -335,3 +335,20 @@ Create DPP: 0xd8C30a4E866B188F16aD266dC3333BD47F34ebaE-0x43688f367eb83697c3ca5d0
|
||||
Create DPP: 0xd8C30a4E866B188F16aD266dC3333BD47F34ebaE-0x156595bAF85D5C29E91d959889B022d952190A64 Pool:0x14D4E63d050f235D8bf1Fd3dD3CDc484168FB246 Tx: 0xed71901c2c96d8b9d39839bf47f0efe8caf06fc0e8f6156a989c4d60c0dd927b
|
||||
Create DPP: 0xd7f02D1b4F9495B549787808503Ecfd231C3fbDA-0x43688f367eb83697c3ca5d03c5055b6bd6f6ac4b Pool:0x82a777E65d14D462cdb8fE1886115Bbbc1F24039 Tx: 0x10360317368344c2e1519aba4fff57e6c247c0c4d95adeba1aac5c1e917acdbb
|
||||
Create DPP: 0xd7f02D1b4F9495B549787808503Ecfd231C3fbDA-0x156595bAF85D5C29E91d959889B022d952190A64 Pool:0xBA9b148769BdF0D872439ac31Ff103D487e10f64 Tx: 0x912cf081eb7e8abeae94c3dbb45b745e926d0aec76387ba897dc0e49fc660378
|
||||
====================================================
|
||||
network type: kovan
|
||||
Deploy time: 2021/1/19 下午12:25:59
|
||||
Manual add target Pool: V2
|
||||
Approve:0xCcf0733cA7B6299D59b1Bddf87f3a8AAaD87461F Tx: 0x242435d2b174bcd06935040868eabc50d2074d52f1178bb46523ca3c3cef6a15
|
||||
Approve:0x43688f367eb83697c3ca5d03c5055b6bd6f6ac4b Tx: 0x5e9d0f882967df12bca28f9beb3a500d5a942f2ac50dff10b48662bfa390c81f
|
||||
====================================================
|
||||
network type: kovan
|
||||
Deploy time: 2021/1/19 下午12:35:14
|
||||
Manual add target Pool: V2
|
||||
====================================================
|
||||
network type: kovan
|
||||
Deploy time: 2021/1/19 下午1:21:12
|
||||
Manual add target Pool: V2
|
||||
Approve:0xCcf0733cA7B6299D59b1Bddf87f3a8AAaD87461F Tx: 0xebbd30fc18190d0fd7df03ffd24fb784122c0b1e7e73ee5ad2da64c1877ecd0e
|
||||
Approve:0x43688f367eb83697c3ca5d03c5055b6bd6f6ac4b Tx: 0x1de48a27ef0e08a0bffeb016991b5e9d29ba35920bd9ea5478dc273568616ee7
|
||||
Create DPP: 0xCcf0733cA7B6299D59b1Bddf87f3a8AAaD87461F-0x43688f367eb83697c3ca5d03c5055b6bd6f6ac4b Pool:0x961A1E706907e9AcA5b3d784325C8D571CdACef9 Tx: 0x3a698fbf1e71603dd84ed89ae23c106bc689743b104898e5a5afba9a26f86d35
|
||||
|
||||
@@ -74,7 +74,7 @@ module.exports = async (deployer, network, accounts) => {
|
||||
WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b";
|
||||
chiAddress = "0x0000000000004946c0e9f43f4dee607b0ef1fa1c";
|
||||
DODOCalleeHelperAddress = "0x507EBbb195CF54E0aF147A2b269C08a38EA36989";
|
||||
DODORouteV2HelperAddress = "0x0546641b5288942675A36345E25210695d1d4d50";
|
||||
DODORouteV2HelperAddress = "";
|
||||
//Template
|
||||
CloneFactoryAddress = "0xf7959fe661124C49F96CF30Da33729201aEE1b27";
|
||||
// FeeRateModelTemplateAddress = "0xEF3137780B387313c5889B999D03BdCf9aeEa892";
|
||||
@@ -89,10 +89,10 @@ module.exports = async (deployer, network, accounts) => {
|
||||
DvmTemplateAddress = "0xD47B0782EDdAc44Bd2B6a51C949feaE9Af382A51";
|
||||
DppTemplateAddress = "0xA0C3C6Ad75fBfaCb490E315BA762A6D20084b5a8";
|
||||
DppAdminTemplateAddress = "0xe39E02c4f269c4E235Ca8979a125608644c8924a";
|
||||
CpTemplateAddress = "";
|
||||
CpTemplateAddress = "0x6E0c3D0F6f916B8067999c6196A1806d80840a12";
|
||||
//Factory
|
||||
DvmFactoryAddress = "0x01B7fCc1890Ab90Da33dE2F0dC54aDF3C7501F04";
|
||||
DppFactoryAddress = "0x67c4765D04C3848FFa7967231fc7B7E58f67A887";
|
||||
DvmFactoryAddress = "";
|
||||
DppFactoryAddress = "";
|
||||
CpFactoryAddress = "";
|
||||
//Approve
|
||||
DODOApproveAddress = "";
|
||||
|
||||
@@ -64,10 +64,10 @@ module.exports = async (deployer, network, accounts) => {
|
||||
let MintableERC20TemplateAddress = "0xA45a64DAba80757432fA4d654Df12f65f020C13C";
|
||||
let ERC20FactoryAddress = "0xCb1A2f64EfB02803276BFB5a8D511C4D950282a0";
|
||||
|
||||
let DPPFactoryAddress = "0x67c4765D04C3848FFa7967231fc7B7E58f67A887";
|
||||
let DVMFactoryAddress = "0x01B7fCc1890Ab90Da33dE2F0dC54aDF3C7501F04";
|
||||
let DODOApproveAddress = "0x5e56Db19C3f52594876E2A3e1a47d15acD8DC570";
|
||||
let DODOProxyV2Address = "0xA730229607b710cd06AEAad1eDc644Dbb70A5E85";
|
||||
let DPPFactoryAddress = "0x29d2feD26D37167d775f3eCAafAEe3e62B5f4fF6";
|
||||
let DVMFactoryAddress = "0xFcD6835a9490Dc673944d4AB30F73D7FB8f4fbaA";
|
||||
let DODOApproveAddress = "0x25b5C731822E534A1df126985bb8781f1b979eF9";
|
||||
let DODOProxyV2Address = "0x3566c45117438485331c0628e10bA7bE09a1fFCB";
|
||||
|
||||
const provider = new Web3.providers.HttpProvider("https://kovan.infura.io/v3/22d4a3b2df0e47b78d458f43fe50a199");
|
||||
|
||||
@@ -81,8 +81,42 @@ module.exports = async (deployer, network, accounts) => {
|
||||
logger.log("network type: " + network);
|
||||
logger.log("Deploy time: " + new Date().toLocaleString());
|
||||
|
||||
if(deploySwitch.MANUAL_ADD_POOL) {
|
||||
logger.log("Manual add Pool: V2");
|
||||
|
||||
if (deploySwitch.MOCK_TARGET_POOL) {
|
||||
logger.log("Manual add target Pool: V2");
|
||||
var tx;
|
||||
const token0Addr = "0xCcf0733cA7B6299D59b1Bddf87f3a8AAaD87461F";
|
||||
const quote0Addr = "0x43688f367eb83697c3ca5d03c5055b6bd6f6ac4b";
|
||||
const token0 = await ERC20Template.at(token0Addr);
|
||||
const quote0 = await ERC20Template.at(quote0Addr);
|
||||
|
||||
tx = await token0.approve(DODOApproveAddress, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
logger.log("Approve:" + token0Addr + " Tx:", tx.tx);
|
||||
tx = await quote0.approve(DODOApproveAddress, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
logger.log("Approve:" + quote0Addr + " Tx:", tx.tx);
|
||||
const DODOProxyV2Instance = await DODOProxyV2.at(DODOProxyV2Address);
|
||||
const DPPFactoryInstance = await DPPFactory.at(DPPFactoryAddress);
|
||||
|
||||
const baseInAmount = web3.utils.toWei("0", 'ether');
|
||||
const quoteInAmount = web3.utils.toWei("0", 'mwei');
|
||||
const deadline = Math.floor(new Date().getTime() / 1000 + 60 * 10);
|
||||
//DPP Pool
|
||||
tx = await DODOProxyV2Instance.createDODOPrivatePool(
|
||||
token0Addr,
|
||||
quote0Addr,
|
||||
baseInAmount,
|
||||
quoteInAmount,
|
||||
'0',
|
||||
'1000000',
|
||||
'1000000000000000000',
|
||||
deadline
|
||||
);
|
||||
var poolAddress = await DPPFactoryInstance._REGISTRY_(token0Addr, quote0Addr, 0);
|
||||
logger.log("Create DPP: " + token0Addr + "-" + quote0Addr + " Pool:" + poolAddress + " Tx:", tx.tx);
|
||||
}
|
||||
|
||||
if (deploySwitch.MANUAL_ADD_POOL) {
|
||||
logger.log("Manual add Pool: V2");
|
||||
const DPPFactoryInstance = await DPPFactory.at(DPPFactoryAddress);
|
||||
var tx = await DPPFactoryInstance.addPoolByAdmin(
|
||||
"0x7e83d9d94837ee82f0cc18a691da6f42f03f1d86",
|
||||
|
||||
@@ -38,6 +38,7 @@ async function initCreateCP(ctx: ProxyContext, token0: string, token1: string, t
|
||||
token0Amount,
|
||||
timeLine,
|
||||
valueList,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, "0.2"));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
@@ -120,6 +121,7 @@ describe("DODOProxyV2.0", () => {
|
||||
baseAmount,
|
||||
timeLine,
|
||||
valueList,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(project, "0.2"), "createCP");
|
||||
var addrs = await ctx.CPFactory.methods.getCrowdPooling(baseToken, quoteToken).call();
|
||||
|
||||
@@ -53,6 +53,7 @@ async function initCreateDPP(ctx: ProxyContext, token0: string, token1: string,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
@@ -115,6 +116,7 @@ describe("DODOProxyV2.0", () => {
|
||||
config.lpFeeRate,
|
||||
config.i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(project), "createDPP");
|
||||
var addrs = await ctx.DPPFactory.methods.getPrivatePool(baseToken, quoteToken).call();
|
||||
|
||||
@@ -52,6 +52,7 @@ async function initCreateDVM(ctx: ProxyContext, token0: string, token1: string,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
true,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
@@ -115,6 +116,7 @@ describe("DODOProxyV2.0", () => {
|
||||
config.lpFeeRate,
|
||||
config.i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(project), "createDVM");
|
||||
var addrs = await ctx.DVMFactory.methods.getVendingMachine(baseToken, quoteToken).call();
|
||||
|
||||
@@ -49,6 +49,7 @@ async function initCreateDPP(ctx: ProxyContext, token0: string, token1: string,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
@@ -67,6 +68,7 @@ async function initCreateDVM(ctx: ProxyContext, token0: string, token1: string,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
|
||||
@@ -49,6 +49,7 @@ async function initCreateDPP(ctx: ProxyContext, token0: string, token1: string,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
@@ -67,6 +68,7 @@ async function initCreateDVM(ctx: ProxyContext, token0: string, token1: string,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
|
||||
184
test/V2Proxy/proxy.twap.test.ts
Normal file
184
test/V2Proxy/proxy.twap.test.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 DODO ZOO.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
*/
|
||||
|
||||
import { decimalStr, mweiStr } from '../utils/Converter';
|
||||
import { logGas } from '../utils/Log';
|
||||
import { ProxyContext, getProxyContext } from '../utils/ProxyContextV2';
|
||||
import { assert } from 'chai';
|
||||
import * as contracts from '../utils/Contracts';
|
||||
|
||||
let lp: string;
|
||||
let project: string;
|
||||
let trader: string;
|
||||
|
||||
let config = {
|
||||
lpFeeRate: decimalStr("0.002"),
|
||||
mtFeeRate: decimalStr("0.001"),
|
||||
k: decimalStr("0.1"),
|
||||
i: decimalStr("100"),
|
||||
};
|
||||
|
||||
async function init(ctx: ProxyContext): Promise<void> {
|
||||
lp = ctx.SpareAccounts[0];
|
||||
project = ctx.SpareAccounts[1];
|
||||
trader = ctx.SpareAccounts[2];
|
||||
|
||||
await ctx.mintTestToken(lp, ctx.DODO, decimalStr("1000000"));
|
||||
await ctx.mintTestToken(project, ctx.DODO, decimalStr("1000000"));
|
||||
|
||||
await ctx.mintTestToken(lp, ctx.USDT, mweiStr("1000000"));
|
||||
await ctx.mintTestToken(project, ctx.USDT, mweiStr("1000000"));
|
||||
|
||||
await ctx.approveProxy(lp);
|
||||
await ctx.approveProxy(project);
|
||||
await ctx.approveProxy(trader);
|
||||
}
|
||||
|
||||
|
||||
async function initCreateDPP(ctx: ProxyContext, token0: string, token1: string, token0Amount: string, token1Amount: string, ethValue: string, i: string): Promise<string> {
|
||||
let PROXY = ctx.DODOProxyV2;
|
||||
await PROXY.methods.createDODOPrivatePool(
|
||||
token0,
|
||||
token1,
|
||||
token0Amount,
|
||||
token1Amount,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
true,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
if (token1 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token1 = ctx.WETH.options.address;
|
||||
var addr = await ctx.DPPFactory.methods._REGISTRY_(token0, token1, 0).call();
|
||||
return addr;
|
||||
}
|
||||
|
||||
async function initCreateDVM(ctx: ProxyContext, token0: string, token1: string, token0Amount: string, token1Amount: string, ethValue: string, i: string): Promise<string> {
|
||||
let PROXY = ctx.DODOProxyV2;
|
||||
await PROXY.methods.createDODOVendingMachine(
|
||||
token0,
|
||||
token1,
|
||||
token0Amount,
|
||||
token1Amount,
|
||||
config.lpFeeRate,
|
||||
i,
|
||||
config.k,
|
||||
true,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project, ethValue));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
if (token1 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token1 = ctx.WETH.options.address;
|
||||
var addr = await ctx.DVMFactory.methods._REGISTRY_(token0, token1, 0).call();
|
||||
return addr;
|
||||
}
|
||||
|
||||
describe("DODOProxyV2.0", () => {
|
||||
let snapshotId: string;
|
||||
let ctx: ProxyContext;
|
||||
let dpp_DODO_USDT: string;
|
||||
let dvm_WETH_USDT: string;
|
||||
|
||||
before(async () => {
|
||||
let ETH = await contracts.newContract(
|
||||
contracts.WETH_CONTRACT_NAME
|
||||
);
|
||||
ctx = await getProxyContext(ETH.options.address);
|
||||
await init(ctx);
|
||||
dpp_DODO_USDT = await initCreateDPP(ctx, ctx.DODO.options.address, ctx.USDT.options.address, decimalStr("100000"), mweiStr("20000"), "0", mweiStr("0.2"));
|
||||
dvm_WETH_USDT = await initCreateDVM(ctx, '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', ctx.USDT.options.address, decimalStr("5"), mweiStr("3000"), "5", mweiStr("600"));
|
||||
console.log("dpp_DODO_USDT:", dpp_DODO_USDT);
|
||||
console.log("dvm_WETH_USDT:", dvm_WETH_USDT);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
snapshotId = await ctx.EVM.snapshot();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await ctx.EVM.reset(snapshotId);
|
||||
});
|
||||
|
||||
describe("DODOProxy", () => {
|
||||
|
||||
it("swap - two jump", async () => {
|
||||
let WETH_USDT_INSTANCE = contracts.getContractWithAddress(contracts.DVM_NAME, dvm_WETH_USDT);
|
||||
|
||||
var firstPriceCumulative = await WETH_USDT_INSTANCE.methods._BASE_PRICE_CUMULATIVE_LAST_().call();
|
||||
var firstBlockTimestampLast = await WETH_USDT_INSTANCE.methods._BLOCK_TIMESTAMP_LAST_().call();
|
||||
console.log("0 - WETH-USDT - priceCumulative:" + firstPriceCumulative + ";blockTimestampLast:" + firstBlockTimestampLast)
|
||||
|
||||
|
||||
await ctx.mintTestToken(trader, ctx.DODO, decimalStr("1000"));
|
||||
|
||||
//Aim to increase block
|
||||
await ctx.mintTestToken(lp, ctx.DODO, decimalStr("1000"));
|
||||
await ctx.mintTestToken(lp, ctx.DODO, decimalStr("1000"));
|
||||
await ctx.mintTestToken(lp, ctx.DODO, decimalStr("1000"));
|
||||
|
||||
|
||||
var b_DOOD = await ctx.DODO.methods.balanceOf(trader).call();
|
||||
var b_WETH = await ctx.WETH.methods.balanceOf(trader).call();
|
||||
var dodoPairs = [
|
||||
dpp_DODO_USDT,
|
||||
dvm_WETH_USDT
|
||||
]
|
||||
var directions = 2
|
||||
await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2TokenToToken(
|
||||
ctx.DODO.options.address,
|
||||
ctx.WETH.options.address,
|
||||
decimalStr("500"),
|
||||
1,
|
||||
dodoPairs,
|
||||
directions,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(trader), "swap - two jump");
|
||||
|
||||
|
||||
|
||||
var priceCumulative = await WETH_USDT_INSTANCE.methods._BASE_PRICE_CUMULATIVE_LAST_().call();
|
||||
var blockTimestampLast = await WETH_USDT_INSTANCE.methods._BLOCK_TIMESTAMP_LAST_().call();
|
||||
console.log("1 - WETH-USDT - priceCumulative:" + priceCumulative + ";blockTimestampLast:" + blockTimestampLast)
|
||||
|
||||
var a_DOOD = await ctx.DODO.methods.balanceOf(trader).call();
|
||||
var a_WETH = await ctx.WETH.methods.balanceOf(trader).call();
|
||||
console.log("b_DOOD:" + b_DOOD + " a_DODO:" + a_DOOD);
|
||||
console.log("b_WETH:" + b_WETH + " a_WETH:" + a_WETH);
|
||||
assert.equal(a_DOOD, decimalStr("500"));
|
||||
assert.equal(a_WETH, "129932374904193666");
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2TokenToToken(
|
||||
ctx.DODO.options.address,
|
||||
ctx.WETH.options.address,
|
||||
decimalStr("500"),
|
||||
1,
|
||||
dodoPairs,
|
||||
directions,
|
||||
false,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(trader), "swap - two jump");
|
||||
|
||||
var lastPriceCumulative = await WETH_USDT_INSTANCE.methods._BASE_PRICE_CUMULATIVE_LAST_().call();
|
||||
var lastBlockTimestampLast = await WETH_USDT_INSTANCE.methods._BLOCK_TIMESTAMP_LAST_().call();
|
||||
var midPrice = await WETH_USDT_INSTANCE.methods.getMidPrice().call();
|
||||
|
||||
console.log("2 - WETH-USDT - priceCumulative:" + lastPriceCumulative + ";blockTimestampLast:" + lastBlockTimestampLast)
|
||||
|
||||
var blockNumber = await ctx.Web3.eth.getBlockNumber();
|
||||
var blockInfo = await ctx.Web3.eth.getBlock(blockNumber);
|
||||
var curTimeStamp = blockInfo['timestamp']
|
||||
|
||||
lastPriceCumulative += (parseInt(curTimeStamp + "") - parseInt(lastBlockTimestampLast)) * midPrice
|
||||
|
||||
console.log("twap:", (lastPriceCumulative - firstPriceCumulative) / (parseInt(curTimeStamp + "") - firstBlockTimestampLast))
|
||||
|
||||
assert((lastPriceCumulative - firstPriceCumulative) / (parseInt(curTimeStamp + "") - firstBlockTimestampLast) + "", "7722062520")
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -77,8 +77,7 @@ export class DODOContext {
|
||||
DODOSellHelper: Contract;
|
||||
//Helper
|
||||
DODOSwapCalcHelper: Contract;
|
||||
//Functions
|
||||
DODOIncentive: Contract;
|
||||
|
||||
|
||||
constructor() { }
|
||||
|
||||
@@ -227,12 +226,6 @@ export class DODOContext {
|
||||
contracts.SMART_APPROVE
|
||||
);
|
||||
|
||||
//DODO Incentive
|
||||
this.DODOIncentive = await contracts.newContract(
|
||||
contracts.DODO_INCENTIVE,
|
||||
[this.DODO.options.address]
|
||||
)
|
||||
|
||||
//Gas Token
|
||||
this.CHI = await contracts.newContract(
|
||||
contracts.CHI_TOKEN
|
||||
@@ -248,16 +241,14 @@ export class DODOContext {
|
||||
|
||||
this.DODOV1Proxy02 = await contracts.newContract(
|
||||
contracts.SMART_SWAP_02,
|
||||
[this.DODOApprove.options.address, this.DODOSellHelper.options.address, this.WETH.options.address, this.CHI.options.address,this.DODOIncentive.options.address]
|
||||
[this.DODOApprove.options.address, this.DODOSellHelper.options.address, this.WETH.options.address, this.CHI.options.address]
|
||||
// [this.DODOApprove.options.address, this.DODOSellHelper.options.address, this.WETH.options.address, "0x0000000000000000000000000000000000000000"]
|
||||
);
|
||||
|
||||
await this.DODOV1Proxy01.methods.initOwner(this.Deployer).send(this.sendParam(this.Deployer));
|
||||
await this.DODOV1Proxy02.methods.initOwner(this.Deployer).send(this.sendParam(this.Deployer));
|
||||
await this.DODOIncentive.methods.initOwner(this.Deployer).send(this.sendParam(this.Deployer));
|
||||
|
||||
await this.DODOApprove.methods.init(this.Deployer, this.DODOV1Proxy01.options.address).send(this.sendParam(this.Deployer));
|
||||
await this.DODOIncentive.methods.changeDODOProxy(this.DODOV1Proxy02.options.address).send(this.sendParam(this.Deployer));
|
||||
|
||||
this.DODOSwapCalcHelper = await contracts.newContract(
|
||||
contracts.DODO_SWAP_CALC_HELPER,[this.DODOSellHelper.options.address]
|
||||
|
||||
@@ -85,6 +85,7 @@ export class ProxyContext {
|
||||
// await mtFeeRateModelTemplate.methods.init(this.Deployer,decimalStr("0.01")).send(this.sendParam(this.Deployer));
|
||||
await mtFeeRateModelTemplate.methods.init(this.Deployer,decimalStr("0")).send(this.sendParam(this.Deployer));
|
||||
|
||||
|
||||
this.DVMFactory = await contracts.newContract(contracts.DVM_FACTORY_NAME,
|
||||
[
|
||||
cloneFactory.options.address,
|
||||
@@ -130,6 +131,7 @@ export class ProxyContext {
|
||||
contracts.DODO_SELL_HELPER
|
||||
);
|
||||
|
||||
|
||||
this.DODOProxyV2 = await contracts.newContract(contracts.DODO_PROXY_NAME,
|
||||
[
|
||||
this.DVMFactory.options.address,
|
||||
|
||||
@@ -45,7 +45,8 @@ module.exports = {
|
||||
MOCK_V2_POOL: false,
|
||||
MOCK_V2_SWAP: false,
|
||||
MANUAL_ADD_POOL: false,
|
||||
ROUTER_HELPER: true
|
||||
ROUTER_HELPER: false,
|
||||
MOCK_TARGET_POOL: false
|
||||
},
|
||||
|
||||
networks: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
truffle compile --all
|
||||
# truffle compile --all
|
||||
|
||||
if [ "$1"x = "proxy-dpp"x ]
|
||||
then
|
||||
@@ -31,6 +31,11 @@ then
|
||||
truffle test ./test/V2Proxy/proxy.incentive.test.ts
|
||||
fi
|
||||
|
||||
if [ "$1"x = "proxy-twap"x ]
|
||||
then
|
||||
truffle test ./test/V2Proxy/proxy.twap.test.ts
|
||||
fi
|
||||
|
||||
# if [ "$1"x = "route-incentive"x ]
|
||||
# then
|
||||
# truffle test ./test/Route/Incentive.test.ts
|
||||
|
||||
Reference in New Issue
Block a user