diff --git a/contracts/CrowdPooling/impl/CP.sol b/contracts/CrowdPooling/impl/CP.sol index 94d2553..1cdc2da 100644 --- a/contracts/CrowdPooling/impl/CP.sol +++ b/contracts/CrowdPooling/impl/CP.sol @@ -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"); } } diff --git a/contracts/CrowdPooling/impl/CPFunding.sol b/contracts/CrowdPooling/impl/CPFunding.sol index 1bded4a..e1aed06 100644 --- a/contracts/CrowdPooling/impl/CPFunding.sol +++ b/contracts/CrowdPooling/impl/CPFunding.sol @@ -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); diff --git a/contracts/CrowdPooling/impl/CPStorage.sol b/contracts/CrowdPooling/impl/CPStorage.sol index 7412c53..6fd73d0 100644 --- a/contracts/CrowdPooling/impl/CPStorage.sol +++ b/contracts/CrowdPooling/impl/CPStorage.sol @@ -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 ============ diff --git a/contracts/CrowdPooling/intf/ICP.sol b/contracts/CrowdPooling/intf/ICP.sol index 86d6aa8..5499461 100644 --- a/contracts/CrowdPooling/intf/ICP.sol +++ b/contracts/CrowdPooling/intf/ICP.sol @@ -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; diff --git a/contracts/DODOPrivatePool/impl/DPP.sol b/contracts/DODOPrivatePool/impl/DPP.sol index dee0850..8adfc3a 100644 --- a/contracts/DODOPrivatePool/impl/DPP.sol +++ b/contracts/DODOPrivatePool/impl/DPP.sol @@ -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(); } diff --git a/contracts/DODOPrivatePool/impl/DPPStorage.sol b/contracts/DODOPrivatePool/impl/DPPStorage.sol index 17754ca..5202c88 100644 --- a/contracts/DODOPrivatePool/impl/DPPStorage.sol +++ b/contracts/DODOPrivatePool/impl/DPPStorage.sol @@ -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()); + } } diff --git a/contracts/DODOPrivatePool/impl/DPPTrader.sol b/contracts/DODOPrivatePool/impl/DPPTrader.sol index f4b7eef..698ee8c 100644 --- a/contracts/DODOPrivatePool/impl/DPPTrader.sol +++ b/contracts/DODOPrivatePool/impl/DPPTrader.sol @@ -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()); - } } diff --git a/contracts/DODOPrivatePool/impl/DPPVault.sol b/contracts/DODOPrivatePool/impl/DPPVault.sol index fdb861f..c1e808e 100644 --- a/contracts/DODOPrivatePool/impl/DPPVault.sol +++ b/contracts/DODOPrivatePool/impl/DPPVault.sol @@ -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( diff --git a/contracts/DODOPrivatePool/intf/IDPP.sol b/contracts/DODOPrivatePool/intf/IDPP.sol index 70eda0c..ee1c7b9 100644 --- a/contracts/DODOPrivatePool/intf/IDPP.sol +++ b/contracts/DODOPrivatePool/intf/IDPP.sol @@ -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); diff --git a/contracts/DODOVendingMachine/impl/DVM.sol b/contracts/DODOVendingMachine/impl/DVM.sol index 5aa1c0b..fd0b180 100644 --- a/contracts/DODOVendingMachine/impl/DVM.sol +++ b/contracts/DODOVendingMachine/impl/DVM.sol @@ -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"; diff --git a/contracts/DODOVendingMachine/impl/DVMStorage.sol b/contracts/DODOVendingMachine/impl/DVMStorage.sol index 5053808..dc9127d 100644 --- a/contracts/DODOVendingMachine/impl/DVMStorage.sol +++ b/contracts/DODOVendingMachine/impl/DVMStorage.sol @@ -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()); + } } diff --git a/contracts/DODOVendingMachine/impl/DVMTrader.sol b/contracts/DODOVendingMachine/impl/DVMTrader.sol index 9ffb47c..079b4a0 100644 --- a/contracts/DODOVendingMachine/impl/DVMTrader.sol +++ b/contracts/DODOVendingMachine/impl/DVMTrader.sol @@ -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()); - } } diff --git a/contracts/DODOVendingMachine/impl/DVMVault.sol b/contracts/DODOVendingMachine/impl/DVMVault.sol index 80e3f77..a57e1c2 100644 --- a/contracts/DODOVendingMachine/impl/DVMVault.sol +++ b/contracts/DODOVendingMachine/impl/DVMVault.sol @@ -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(); } diff --git a/contracts/DODOVendingMachine/intf/IDVM.sol b/contracts/DODOVendingMachine/intf/IDVM.sol index 08efbb2..9b20488 100644 --- a/contracts/DODOVendingMachine/intf/IDVM.sol +++ b/contracts/DODOVendingMachine/intf/IDVM.sol @@ -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); diff --git a/contracts/Factory/CrowdPoolingFactory.sol b/contracts/Factory/CrowdPoolingFactory.sol index b30fd23..e0e2747 100644 --- a/contracts/Factory/CrowdPoolingFactory.sol +++ b/contracts/Factory/CrowdPoolingFactory.sol @@ -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 ); } diff --git a/contracts/Factory/DPPFactory.sol b/contracts/Factory/DPPFactory.sol index 0f32f2f..377e7eb 100644 --- a/contracts/Factory/DPPFactory.sol +++ b/contracts/Factory/DPPFactory.sol @@ -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 ); } diff --git a/contracts/Factory/DVMFactory.sol b/contracts/Factory/DVMFactory.sol index f640f90..fccfcbe 100644 --- a/contracts/Factory/DVMFactory.sol +++ b/contracts/Factory/DVMFactory.sol @@ -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); diff --git a/contracts/SmartRoute/DODOV2Proxy01.sol b/contracts/SmartRoute/DODOV2Proxy01.sol index a797e4b..171077a 100644 --- a/contracts/SmartRoute/DODOV2Proxy01.sol +++ b/contracts/SmartRoute/DODOV2Proxy01.sol @@ -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 ); } diff --git a/contracts/SmartRoute/intf/IDODOV2.sol b/contracts/SmartRoute/intf/IDODOV2.sol index 86dabe9..4e9cea3 100644 --- a/contracts/SmartRoute/intf/IDODOV2.sol +++ b/contracts/SmartRoute/intf/IDODOV2.sol @@ -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; diff --git a/contracts/SmartRoute/intf/IDODOV2Proxy01.sol b/contracts/SmartRoute/intf/IDODOV2Proxy01.sol index 3cc1eaa..587cb58 100644 --- a/contracts/SmartRoute/intf/IDODOV2Proxy01.sol +++ b/contracts/SmartRoute/intf/IDODOV2Proxy01.sol @@ -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); diff --git a/deploy-detail-v2.0.txt b/deploy-detail-v2.0.txt index 3b346c5..0731567 100644 --- a/deploy-detail-v2.0.txt +++ b/deploy-detail-v2.0.txt @@ -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 diff --git a/kovan-mock-v2.0.txt b/kovan-mock-v2.0.txt index f117425..c2000ba 100644 --- a/kovan-mock-v2.0.txt +++ b/kovan-mock-v2.0.txt @@ -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 diff --git a/migrations/3_deploy_v2.js b/migrations/3_deploy_v2.js index b88d654..2f5df56 100644 --- a/migrations/3_deploy_v2.js +++ b/migrations/3_deploy_v2.js @@ -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 = ""; diff --git a/migrations/4_deploy_v2_mock.js b/migrations/4_deploy_v2_mock.js index 61c2e79..ff2dde1 100644 --- a/migrations/4_deploy_v2_mock.js +++ b/migrations/4_deploy_v2_mock.js @@ -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", diff --git a/test/V2Proxy/proxy.cp.test.ts b/test/V2Proxy/proxy.cp.test.ts index e7685e6..90db7d6 100644 --- a/test/V2Proxy/proxy.cp.test.ts +++ b/test/V2Proxy/proxy.cp.test.ts @@ -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(); diff --git a/test/V2Proxy/proxy.dpp.test.ts b/test/V2Proxy/proxy.dpp.test.ts index 23ebe58..963c422 100644 --- a/test/V2Proxy/proxy.dpp.test.ts +++ b/test/V2Proxy/proxy.dpp.test.ts @@ -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(); diff --git a/test/V2Proxy/proxy.dvm.test.ts b/test/V2Proxy/proxy.dvm.test.ts index f3944ec..0d3b93c 100644 --- a/test/V2Proxy/proxy.dvm.test.ts +++ b/test/V2Proxy/proxy.dvm.test.ts @@ -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(); diff --git a/test/V2Proxy/proxy.incentive.test.ts b/test/V2Proxy/proxy.incentive.test.ts index d47355d..72ce6b7 100644 --- a/test/V2Proxy/proxy.incentive.test.ts +++ b/test/V2Proxy/proxy.incentive.test.ts @@ -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; diff --git a/test/V2Proxy/proxy.mix.test.ts b/test/V2Proxy/proxy.mix.test.ts index 94fa6b3..fc84c9a 100644 --- a/test/V2Proxy/proxy.mix.test.ts +++ b/test/V2Proxy/proxy.mix.test.ts @@ -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; diff --git a/test/V2Proxy/proxy.twap.test.ts b/test/V2Proxy/proxy.twap.test.ts new file mode 100644 index 0000000..c3f79b5 --- /dev/null +++ b/test/V2Proxy/proxy.twap.test.ts @@ -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 { + 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 { + 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 { + 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") + }); + }); + +}); diff --git a/test/utils-v1/ProxyContextV1.ts b/test/utils-v1/ProxyContextV1.ts index 99b1c40..e7f5e3c 100644 --- a/test/utils-v1/ProxyContextV1.ts +++ b/test/utils-v1/ProxyContextV1.ts @@ -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] diff --git a/test/utils/ProxyContextV2.ts b/test/utils/ProxyContextV2.ts index a1c62a4..4c3da14 100644 --- a/test/utils/ProxyContextV2.ts +++ b/test/utils/ProxyContextV2.ts @@ -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, diff --git a/truffle-config.js b/truffle-config.js index 9be4893..89eb1df 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -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: { diff --git a/truffle-test.sh b/truffle-test.sh index 0f64f7d..24e566e 100644 --- a/truffle-test.sh +++ b/truffle-test.sh @@ -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