diff --git a/contracts/DODOPrivatePool/impl/DPP.sol b/contracts/DODOPrivatePool/impl/DPP.sol index 32ceda3..e3aa069 100644 --- a/contracts/DODOPrivatePool/impl/DPP.sol +++ b/contracts/DODOPrivatePool/impl/DPP.sol @@ -38,6 +38,8 @@ contract DPP is DPPTrader { _GAS_PRICE_LIMIT_ = IExternalValue(gasPriceSource); _TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager); _resetTargetAndReserve(); + _checkIK(); + require(_BASE_TOKEN_ != _QUOTE_TOKEN_, "BASE_QUOTE_CAN_NOT_BE_SAME"); } // ============ Version Control ============ diff --git a/contracts/DODOPrivatePool/impl/DPPAdmin.sol b/contracts/DODOPrivatePool/impl/DPPAdmin.sol index e08ad97..68b56bd 100644 --- a/contracts/DODOPrivatePool/impl/DPPAdmin.sol +++ b/contracts/DODOPrivatePool/impl/DPPAdmin.sol @@ -9,16 +9,20 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; import {IDPP} from "../intf/IDPP.sol"; -import {IDODOApprove} from '../../intf/IDODOApprove.sol'; +import {IDODOApprove} from "../../intf/IDODOApprove.sol"; import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; contract DPPAdmin is InitializableOwnable { - address public _DPP_; - address public _OPERATOR_; + address public _OPERATOR_; address public _DODO_APPROVE_; - function init(address owner, address dpp,address operator, address dodoApprove) external { + function init( + address owner, + address dpp, + address operator, + address dodoApprove + ) external { initOwner(owner); _DPP_ = dpp; _OPERATOR_ = operator; @@ -29,33 +33,33 @@ contract DPPAdmin is InitializableOwnable { _OPERATOR_ = newOperator; } - function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner { - IDPP(_DPP_).setLpFeeRateModel(newLpFeeRateModel); - } + // function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner { + // IDPP(_DPP_).setLpFeeRateModel(newLpFeeRateModel); + // } - function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner { - IDPP(_DPP_).setMtFeeRateModel(newMtFeeRateModel); - } + // function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner { + // IDPP(_DPP_).setMtFeeRateModel(newMtFeeRateModel); + // } - function setTradePermissionManager(address newTradePermissionManager) external onlyOwner { - IDPP(_DPP_).setTradePermissionManager(newTradePermissionManager); - } + // function setTradePermissionManager(address newTradePermissionManager) external onlyOwner { + // IDPP(_DPP_).setTradePermissionManager(newTradePermissionManager); + // } function setMaintainer(address newMaintainer) external onlyOwner { IDPP(_DPP_).setMaintainer(newMaintainer); } - function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner { - IDPP(_DPP_).setGasPriceSource(newGasPriceLimitSource); - } + // function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner { + // IDPP(_DPP_).setGasPriceSource(newGasPriceLimitSource); + // } - function setISource(address newISource) external onlyOwner { - IDPP(_DPP_).setISource(newISource); - } + // function setISource(address newISource) external onlyOwner { + // IDPP(_DPP_).setISource(newISource); + // } - function setKSource(address newKSource) external onlyOwner { - IDPP(_DPP_).setKSource(newKSource); - } + // function setKSource(address newKSource) external onlyOwner { + // IDPP(_DPP_).setKSource(newKSource); + // } function setBuy(bool open) external onlyOwner { IDPP(_DPP_).setBuy(open); @@ -65,12 +69,16 @@ contract DPPAdmin is InitializableOwnable { IDPP(_DPP_).setSell(open); } - function retrieve(address payable to,address token,uint256 amount) external onlyOwner { - IDPP(_DPP_).retrieve(to,token,amount); + function retrieve( + address payable to, + address token, + uint256 amount + ) external onlyOwner { + IDPP(_DPP_).retrieve(to, token, amount); } function reset( - address assetTo, + address operator, uint256 newLpFeeRate, uint256 newMtFeeRate, uint256 newI, @@ -78,28 +86,12 @@ contract DPPAdmin is InitializableOwnable { uint256 baseOutAmount, uint256 quoteOutAmount ) external { - require(msg.sender == _OWNER_ || (msg.sender == IDODOApprove(_DODO_APPROVE_).getDODOProxy() && assetTo == _OPERATOR_), "RESET FORBIDDEN!"); - IDPP(_DPP_).reset( - assetTo, - newLpFeeRate, - newMtFeeRate, - newI, - newK, - baseOutAmount, - quoteOutAmount + require( + msg.sender == _OWNER_ || + (msg.sender == IDODOApprove(_DODO_APPROVE_).getDODOProxy() && + operator == _OPERATOR_), + "RESET FORBIDDEN!" ); - } - - function resetETH( - address from, - uint256 newLpFeeRate, - uint256 newMtFeeRate, - uint256 newI, - uint256 newK, - uint256 baseOutAmount, - uint256 quoteOutAmount - ) external { - require(msg.sender == _OWNER_ || (msg.sender == IDODOApprove(_DODO_APPROVE_).getDODOProxy() && from == _OPERATOR_), "RESET FORBIDDEN!"); IDPP(_DPP_).reset( msg.sender, newLpFeeRate, diff --git a/contracts/DODOPrivatePool/impl/DPPStorage.sol b/contracts/DODOPrivatePool/impl/DPPStorage.sol index 50ec915..5b5d729 100644 --- a/contracts/DODOPrivatePool/impl/DPPStorage.sol +++ b/contracts/DODOPrivatePool/impl/DPPStorage.sol @@ -96,6 +96,13 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard { _SELLING_CLOSE_ = !open; } + function _checkIK() internal view { + uint256 k = _K_.get(); + uint256 i = _I_.get(); + require(k > 0 && k <= 1e18, "K_OUT_OF_RANGE"); + require(i > 0 && i <= 1e36, "I_OUT_OF_RANGE"); + } + // ============ View Functions ============ function getLpFeeRate(address trader) external view returns (uint256 feeRate) { @@ -105,5 +112,4 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard { function getMtFeeRate(address trader) external view returns (uint256 feeRate) { return _MT_FEE_RATE_MODEL_.getFeeRate(trader); } - } diff --git a/contracts/DODOPrivatePool/impl/DPPTrader.sol b/contracts/DODOPrivatePool/impl/DPPTrader.sol index 3e3ac0e..1d9b52a 100644 --- a/contracts/DODOPrivatePool/impl/DPPTrader.sol +++ b/contracts/DODOPrivatePool/impl/DPPTrader.sol @@ -117,9 +117,6 @@ contract DPPTrader is DPPVault { "FLASH_LOAN_FAILED" ); - // no output -> pure profit - if (baseBalance >= _BASE_RESERVE_ && quoteBalance >= _QUOTE_RESERVE_) return; - // sell quote case // quote input + base output if (baseBalance < _BASE_RESERVE_) { @@ -137,8 +134,6 @@ contract DPPTrader is DPPVault { _RState_ = newRState; _QUOTE_TARGET_ = newQuoteTarget; } - - _syncReserve(); } // sell base case @@ -158,9 +153,9 @@ contract DPPTrader is DPPVault { _RState_ = newRState; _BASE_TARGET_ = newBaseTarget; } - - _syncReserve(); } + + _syncReserve(); } // ============ Query Functions ============ @@ -180,11 +175,10 @@ contract DPPTrader is DPPVault { uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader); uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader); - mtFee = DecimalMath.mulCeil(receiveQuoteAmount, mtFeeRate); - receiveQuoteAmount = DecimalMath.mulFloor( - receiveQuoteAmount, - DecimalMath.ONE.sub(mtFeeRate).sub(lpFeeRate) - ); + mtFee = DecimalMath.mulFloor(receiveQuoteAmount, mtFeeRate); + receiveQuoteAmount = receiveQuoteAmount + .sub(DecimalMath.mulFloor(receiveQuoteAmount, lpFeeRate)) + .sub(mtFee); return (receiveQuoteAmount, mtFee, newRState, state.B0); } @@ -204,11 +198,10 @@ contract DPPTrader is DPPVault { uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader); uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader); - mtFee = DecimalMath.mulCeil(receiveBaseAmount, mtFeeRate); - receiveBaseAmount = DecimalMath.mulFloor( - receiveBaseAmount, - DecimalMath.ONE.sub(mtFeeRate).sub(lpFeeRate) - ); + mtFee = DecimalMath.mulFloor(receiveBaseAmount, mtFeeRate); + receiveBaseAmount = receiveBaseAmount + .sub(DecimalMath.mulFloor(receiveBaseAmount, lpFeeRate)) + .sub(mtFee); return (receiveBaseAmount, mtFee, newRState, state.Q0); } diff --git a/contracts/DODOPrivatePool/impl/DPPVault.sol b/contracts/DODOPrivatePool/impl/DPPVault.sol index 0783ed4..cb0f760 100644 --- a/contracts/DODOPrivatePool/impl/DPPVault.sol +++ b/contracts/DODOPrivatePool/impl/DPPVault.sol @@ -43,7 +43,7 @@ contract DPPVault is DPPStorage { return (_BASE_RESERVE_, _QUOTE_RESERVE_); } - // ============ Set Status ============ + // ============ Set States ============ function setTarget(uint256 baseTarget, uint256 quoteTarget) public preventReentrant onlyOwner { _BASE_TARGET_ = baseTarget; @@ -68,8 +68,6 @@ contract DPPVault is DPPStorage { uint256 baseOutAmount, uint256 quoteOutAmount ) public preventReentrant onlyOwner { - require(newK >= 1e12 && newK <= 1e18, "K_OUT_OF_RANGE"); - require(newI > 0 && newI <= 1e36, "I_OUT_OF_RANGE"); _LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate); _MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate); _I_.set(newI); @@ -77,6 +75,7 @@ contract DPPVault is DPPStorage { _transferBaseOut(assetTo, baseOutAmount); _transferQuoteOut(assetTo, quoteOutAmount); _resetTargetAndReserve(); + _checkIK(); } function _setRState() internal { diff --git a/contracts/DODOPrivatePool/intf/IDPP.sol b/contracts/DODOPrivatePool/intf/IDPP.sol index cf7dc6f..c7c5b6b 100644 --- a/contracts/DODOPrivatePool/intf/IDPP.sol +++ b/contracts/DODOPrivatePool/intf/IDPP.sol @@ -22,6 +22,10 @@ interface IDPP { address tradePermissionManager ) external; + function _LP_FEE_RATE_MODEL_() external returns (address); + + function _MT_FEE_RATE_MODEL_() external returns (address); + //=========== admin ========== function setLpFeeRateModel(address newLpFeeRateModel) external; @@ -40,9 +44,14 @@ interface IDPP { function setBuy(bool open) external; function setSell(bool open) external; - //============================== - function retrieve(address payable to,address token,uint256 amount) external; + //============================== + + function retrieve( + address payable to, + address token, + uint256 amount + ) external; function reset( address assetTo, @@ -53,6 +62,4 @@ interface IDPP { uint256 baseOutAmount, uint256 quoteOutAmount ) external; - - } diff --git a/contracts/DODOToken/DODOMine.sol b/contracts/DODOToken/DODOMine.sol index 699c0fb..6261665 100644 --- a/contracts/DODOToken/DODOMine.sol +++ b/contracts/DODOToken/DODOMine.sol @@ -15,7 +15,6 @@ import {SafeMath} from "../lib/SafeMath.sol"; import {IERC20} from "../intf/IERC20.sol"; import {IDODORewardVault, DODORewardVault} from "./DODORewardVault.sol"; - contract DODOMine is Ownable { using SafeMath for uint256; using SafeERC20 for IERC20; @@ -157,7 +156,7 @@ contract DODOMine is Ownable { .div(totalAllocPoint); accDODOPerShare = accDODOPerShare.add(DecimalMath.divFloor(DODOReward, lpSupply)); } - return DecimalMath.mul(user.amount, accDODOPerShare).sub(user.rewardDebt); + return DecimalMath.mulFloor(user.amount, accDODOPerShare).sub(user.rewardDebt); } function getAllPendingReward(address _user) external view returns (uint256) { @@ -181,7 +180,7 @@ contract DODOMine is Ownable { accDODOPerShare = accDODOPerShare.add(DecimalMath.divFloor(DODOReward, lpSupply)); } totalReward = totalReward.add( - DecimalMath.mul(user.amount, accDODOPerShare).sub(user.rewardDebt) + DecimalMath.mulFloor(user.amount, accDODOPerShare).sub(user.rewardDebt) ); } return totalReward; @@ -237,14 +236,14 @@ contract DODOMine is Ownable { UserInfo storage user = userInfo[pid][msg.sender]; updatePool(pid); if (user.amount > 0) { - uint256 pending = DecimalMath.mul(user.amount, pool.accDODOPerShare).sub( + uint256 pending = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare).sub( user.rewardDebt ); safeDODOTransfer(msg.sender, pending); } IERC20(pool.lpToken).safeTransferFrom(address(msg.sender), address(this), _amount); user.amount = user.amount.add(_amount); - user.rewardDebt = DecimalMath.mul(user.amount, pool.accDODOPerShare); + user.rewardDebt = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare); emit Deposit(msg.sender, pid, _amount); } @@ -254,10 +253,12 @@ contract DODOMine is Ownable { UserInfo storage user = userInfo[pid][msg.sender]; require(user.amount >= _amount, "withdraw too much"); updatePool(pid); - uint256 pending = DecimalMath.mul(user.amount, pool.accDODOPerShare).sub(user.rewardDebt); + uint256 pending = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare).sub( + user.rewardDebt + ); safeDODOTransfer(msg.sender, pending); user.amount = user.amount.sub(_amount); - user.rewardDebt = DecimalMath.mul(user.amount, pool.accDODOPerShare); + user.rewardDebt = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare); IERC20(pool.lpToken).safeTransfer(address(msg.sender), _amount); emit Withdraw(msg.sender, pid, _amount); } @@ -285,8 +286,10 @@ contract DODOMine is Ownable { PoolInfo storage pool = poolInfos[pid]; UserInfo storage user = userInfo[pid][msg.sender]; updatePool(pid); - uint256 pending = DecimalMath.mul(user.amount, pool.accDODOPerShare).sub(user.rewardDebt); - user.rewardDebt = DecimalMath.mul(user.amount, pool.accDODOPerShare); + uint256 pending = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare).sub( + user.rewardDebt + ); + user.rewardDebt = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare); safeDODOTransfer(msg.sender, pending); } @@ -301,9 +304,9 @@ contract DODOMine is Ownable { UserInfo storage user = userInfo[pid][msg.sender]; updatePool(pid); pending = pending.add( - DecimalMath.mul(user.amount, pool.accDODOPerShare).sub(user.rewardDebt) + DecimalMath.mulFloor(user.amount, pool.accDODOPerShare).sub(user.rewardDebt) ); - user.rewardDebt = DecimalMath.mul(user.amount, pool.accDODOPerShare); + user.rewardDebt = DecimalMath.mulFloor(user.amount, pool.accDODOPerShare); } safeDODOTransfer(msg.sender, pending); } diff --git a/contracts/DODOToken/LockedTokenVault.sol b/contracts/DODOToken/LockedTokenVault.sol index 682a158..396b9f1 100644 --- a/contracts/DODOToken/LockedTokenVault.sol +++ b/contracts/DODOToken/LockedTokenVault.sol @@ -14,7 +14,6 @@ import {Ownable} from "../lib/Ownable.sol"; import {SafeERC20} from "../lib/SafeERC20.sol"; import {IERC20} from "../intf/IERC20.sol"; - /** * @title LockedTokenVault * @author DODO Breeder @@ -154,7 +153,7 @@ contract LockedTokenVault is Ownable { function getRemainingBalance(address holder) public view returns (uint256) { uint256 remainingRatio = getRemainingRatio(block.timestamp); - return DecimalMath.mul(originBalances[holder], remainingRatio); + return DecimalMath.mulFloor(originBalances[holder], remainingRatio); } function getRemainingRatio(uint256 timestamp) public view returns (uint256) { diff --git a/contracts/DODOVendingMachine/impl/DVM.sol b/contracts/DODOVendingMachine/impl/DVM.sol index 0f24422..2ec13b9 100644 --- a/contracts/DODOVendingMachine/impl/DVM.sol +++ b/contracts/DODOVendingMachine/impl/DVM.sol @@ -38,7 +38,9 @@ contract DVM is DVMTrader, DVMFunding { _GAS_PRICE_LIMIT_ = IExternalValue(gasPriceSource); _MAINTAINER_ = maintainer; - require(i > 0 && i < 10**36); + require(_BASE_TOKEN_ != _QUOTE_TOKEN_, "BASE_QUOTE_CAN_NOT_BE_SAME"); + + require(i > 0 && i <= 10**36); _I_ = i; require(k > 0 && k <= 10**18); @@ -46,7 +48,13 @@ contract DVM is DVMTrader, DVMFunding { string memory connect = "_"; string memory suffix = "DLP"; - string memory uid = string(abi.encodePacked(address(this))); + uint32 uid = uint32(address(this)); + bytes memory id = new bytes(4); + id[0] = bytes1(uint8(48 + (uid % 10))); + id[1] = bytes1(uint8(48 + ((uid / 10) % 10))); + id[2] = bytes1(uint8(48 + ((uid / 100) % 10))); + id[3] = bytes1(uint8(48 + ((uid / 1000) % 10))); + name = string( abi.encodePacked( suffix, @@ -55,7 +63,7 @@ contract DVM is DVMTrader, DVMFunding { connect, _QUOTE_TOKEN_.symbol(), connect, - uid + string(id) ) ); symbol = "DLP"; diff --git a/contracts/DODOVendingMachine/impl/DVMAdmin.sol b/contracts/DODOVendingMachine/impl/DVMAdmin.sol index c1bacc5..6ac17a8 100644 --- a/contracts/DODOVendingMachine/impl/DVMAdmin.sol +++ b/contracts/DODOVendingMachine/impl/DVMAdmin.sol @@ -10,9 +10,9 @@ pragma experimental ABIEncoderV2; import {IDVM} from "../intf/IDVM.sol"; import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; +import {IExternalValue} from "../../lib/ExternalValue.sol"; contract DVMAdmin is InitializableOwnable { - address public _DVM_; function init(address owner, address dvm) external { @@ -20,25 +20,33 @@ contract DVMAdmin is InitializableOwnable { _DVM_ = dvm; } - function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner { - IDVM(_DVM_).setLpFeeRateModel(newLpFeeRateModel); + // function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner { + // IDVM(_DVM_).setLpFeeRateModel(newLpFeeRateModel); + // } + + function setLpFeeRateValue(uint256 newLpFeeRate) external onlyOwner { + IExternalValue(IDVM(_DVM_)._LP_FEE_RATE_MODEL_()).set(newLpFeeRate); } - function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner { - IDVM(_DVM_).setMtFeeRateModel(newMtFeeRateModel); + // function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner { + // IDVM(_DVM_).setMtFeeRateModel(newMtFeeRateModel); + // } + + function setMtFeeRateValue(uint256 newMtFeeRate) external onlyOwner { + IExternalValue(IDVM(_DVM_)._MT_FEE_RATE_MODEL_()).set(newMtFeeRate); } - function setTradePermissionManager(address newTradePermissionManager) external onlyOwner { - IDVM(_DVM_).setTradePermissionManager(newTradePermissionManager); - } + // function setTradePermissionManager(address newTradePermissionManager) external onlyOwner { + // IDVM(_DVM_).setTradePermissionManager(newTradePermissionManager); + // } function setMaintainer(address newMaintainer) external onlyOwner { IDVM(_DVM_).setMaintainer(newMaintainer); } - function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner { - IDVM(_DVM_).setGasPriceSource(newGasPriceLimitSource); - } + // function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner { + // IDVM(_DVM_).setGasPriceSource(newGasPriceLimitSource); + // } function setBuy(bool open) external onlyOwner { IDVM(_DVM_).setBuy(open); diff --git a/contracts/DODOVendingMachine/impl/DVMTrader.sol b/contracts/DODOVendingMachine/impl/DVMTrader.sol index 18bad0d..d3c2449 100644 --- a/contracts/DODOVendingMachine/impl/DVMTrader.sol +++ b/contracts/DODOVendingMachine/impl/DVMTrader.sol @@ -44,11 +44,10 @@ contract DVMTrader is DVMVault { external preventReentrant limitGasPrice - isSellAllow(to) + isSellAllow(to) // set DVM address in trade permission returns (uint256 receiveQuoteAmount) { uint256 baseInput = getBaseInput(); - require(baseInput > 0, "INSUFFICIENT_BASE_INPUT"); uint256 mtFee; (receiveQuoteAmount, mtFee) = querySellBase(tx.origin, baseInput); _transferQuoteOut(to, receiveQuoteAmount); @@ -65,7 +64,6 @@ contract DVMTrader is DVMVault { returns (uint256 receiveBaseAmount) { uint256 quoteInput = getQuoteInput(); - require(quoteInput > 0, "INSUFFICIENT_QUOTE_INPUT"); uint256 mtFee; (receiveBaseAmount, mtFee) = querySellQuote(tx.origin, quoteInput); _transferBaseOut(to, receiveBaseAmount); @@ -74,8 +72,6 @@ contract DVMTrader is DVMVault { return receiveBaseAmount; } - // 这是一个试验性质的函数 - // 没有走标准库,需要仔细考虑下 function flashLoan( uint256 baseAmount, uint256 quoteAmount, @@ -96,9 +92,6 @@ contract DVMTrader is DVMVault { "FLASH_LOAN_FAILED" ); - // no output -> pure profit - if (baseBalance >= _BASE_RESERVE_ && quoteBalance >= _QUOTE_RESERVE_) return; - if (baseBalance < _BASE_RESERVE_) { (uint256 receiveBaseAmount, uint256 mtFee) = querySellQuote( tx.origin, @@ -120,6 +113,8 @@ contract DVMTrader is DVMVault { _sync(); } + // ============ View Functions ============ + function querySellBase(address trader, uint256 payBaseAmount) public view @@ -129,11 +124,10 @@ contract DVMTrader is DVMVault { uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader); uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader); - mtFee = DecimalMath.mulCeil(receiveQuoteAmount, mtFeeRate); - receiveQuoteAmount = DecimalMath.mulFloor( - receiveQuoteAmount, - DecimalMath.ONE.sub(mtFeeRate).sub(lpFeeRate) - ); + mtFee = DecimalMath.mulFloor(receiveQuoteAmount, mtFeeRate); + receiveQuoteAmount = receiveQuoteAmount + .sub(DecimalMath.mulFloor(receiveQuoteAmount, lpFeeRate)) + .sub(mtFee); return (receiveQuoteAmount, mtFee); } @@ -147,18 +141,13 @@ contract DVMTrader is DVMVault { uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader); uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader); - mtFee = DecimalMath.mulCeil(receiveBaseAmount, mtFeeRate); - receiveBaseAmount = DecimalMath.mulFloor( - receiveBaseAmount, - DecimalMath.ONE.sub(mtFeeRate).sub(lpFeeRate) - ); + mtFee = DecimalMath.mulFloor(receiveBaseAmount, mtFeeRate); + receiveBaseAmount = receiveBaseAmount + .sub(DecimalMath.mulFloor(receiveBaseAmount, lpFeeRate)) + .sub(mtFee); return (receiveBaseAmount, mtFee); } - function getMidPrice() public view returns (uint256 midPrice) { - return PMMPricing.getMidPrice(getPMMState()); - } - // ============ Helper Functions ============ function getPMMState() public view returns (PMMPricing.PMMState memory state) { @@ -166,30 +155,14 @@ contract DVMTrader is DVMVault { state.K = _K_; state.B = _BASE_RESERVE_; state.Q = _QUOTE_RESERVE_; - state.B0 = calculateBase0(state.B, state.Q); + state.B0 = 0; // recalculate in adjustedTarget state.Q0 = 0; state.R = PMMPricing.RState.ABOVE_ONE; + PMMPricing.adjustedTarget(state); return state; } - function calculateBase0(uint256 baseAmount, uint256 quoteAmount) public view returns (uint256) { - return - DODOMath._SolveQuadraticFunctionForTarget( - baseAmount, - quoteAmount, - DecimalMath.reciprocalFloor(_I_), - _K_ - ); - } - - function getBase0() public view returns (uint256) { - (uint256 baseAmount, uint256 quoteAmount) = getVaultReserve(); - return - DODOMath._SolveQuadraticFunctionForTarget( - baseAmount, - quoteAmount, - DecimalMath.reciprocalFloor(_I_), - _K_ - ); + function getMidPrice() public view returns (uint256 midPrice) { + return PMMPricing.getMidPrice(getPMMState()); } } diff --git a/contracts/DODOVendingMachine/intf/IDVM.sol b/contracts/DODOVendingMachine/intf/IDVM.sol index b8225af..05423d2 100644 --- a/contracts/DODOVendingMachine/intf/IDVM.sol +++ b/contracts/DODOVendingMachine/intf/IDVM.sol @@ -26,6 +26,10 @@ interface IDVM { function _QUOTE_TOKEN_() external returns (address); + function _LP_FEE_RATE_MODEL_() external returns (address); + + function _MT_FEE_RATE_MODEL_() external returns (address); + function getVaultReserve() external returns (uint256 baseReserve, uint256 quoteReserve); function sellBase(address to) external returns (uint256); @@ -34,7 +38,6 @@ interface IDVM { function buyShares(address to) external returns (uint256); - //=========== admin ========== function setLpFeeRateModel(address newLpFeeRateModel) external; @@ -49,5 +52,5 @@ interface IDVM { function setBuy(bool open) external; function setSell(bool open) external; - //============================== + //============================== } diff --git a/contracts/DODOZoo.sol b/contracts/DODOZoo.sol deleted file mode 100644 index d536cef..0000000 --- a/contracts/DODOZoo.sol +++ /dev/null @@ -1,134 +0,0 @@ -/* - - Copyright 2020 DODO ZOO. - SPDX-License-Identifier: Apache-2.0 - -*/ - -pragma solidity 0.6.9; -pragma experimental ABIEncoderV2; - -import {Ownable} from "./lib/Ownable.sol"; -import {IDODO} from "./intf/IDODO.sol"; -import {ICloneFactory} from "./lib/CloneFactory.sol"; - - -/** - * @title DODOZoo - * @author DODO Breeder - * - * @notice Register of All DODO - */ -contract DODOZoo is Ownable { - address public _DODO_LOGIC_; - address public _CLONE_FACTORY_; - - address public _DEFAULT_SUPERVISOR_; - - mapping(address => mapping(address => address)) internal _DODO_REGISTER_; - address[] public _DODOs; - - // ============ Events ============ - - event DODOBirth(address newBorn, address baseToken, address quoteToken); - - // ============ Constructor Function ============ - - constructor( - address _dodoLogic, - address _cloneFactory, - address _defaultSupervisor - ) public { - _DODO_LOGIC_ = _dodoLogic; - _CLONE_FACTORY_ = _cloneFactory; - _DEFAULT_SUPERVISOR_ = _defaultSupervisor; - } - - // ============ Admin Function ============ - - function setDODOLogic(address _dodoLogic) external onlyOwner { - _DODO_LOGIC_ = _dodoLogic; - } - - function setCloneFactory(address _cloneFactory) external onlyOwner { - _CLONE_FACTORY_ = _cloneFactory; - } - - function setDefaultSupervisor(address _defaultSupervisor) external onlyOwner { - _DEFAULT_SUPERVISOR_ = _defaultSupervisor; - } - - function removeDODO(address dodo) external onlyOwner { - address baseToken = IDODO(dodo)._BASE_TOKEN_(); - address quoteToken = IDODO(dodo)._QUOTE_TOKEN_(); - require(isDODORegistered(baseToken, quoteToken), "DODO_NOT_REGISTERED"); - _DODO_REGISTER_[baseToken][quoteToken] = address(0); - for (uint256 i = 0; i <= _DODOs.length - 1; i++) { - if (_DODOs[i] == dodo) { - _DODOs[i] = _DODOs[_DODOs.length - 1]; - _DODOs.pop(); - break; - } - } - } - - function addDODO(address dodo) public onlyOwner { - address baseToken = IDODO(dodo)._BASE_TOKEN_(); - address quoteToken = IDODO(dodo)._QUOTE_TOKEN_(); - require(!isDODORegistered(baseToken, quoteToken), "DODO_REGISTERED"); - _DODO_REGISTER_[baseToken][quoteToken] = dodo; - _DODOs.push(dodo); - } - - // ============ Breed DODO Function ============ - - function breedDODO( - address maintainer, - address baseToken, - address quoteToken, - address oracle, - uint256 lpFeeRate, - uint256 mtFeeRate, - uint256 k, - uint256 gasPriceLimit - ) external onlyOwner returns (address newBornDODO) { - require(!isDODORegistered(baseToken, quoteToken), "DODO_REGISTERED"); - newBornDODO = ICloneFactory(_CLONE_FACTORY_).clone(_DODO_LOGIC_); - IDODO(newBornDODO).init( - _OWNER_, - _DEFAULT_SUPERVISOR_, - maintainer, - baseToken, - quoteToken, - oracle, - lpFeeRate, - mtFeeRate, - k, - gasPriceLimit - ); - addDODO(newBornDODO); - emit DODOBirth(newBornDODO, baseToken, quoteToken); - return newBornDODO; - } - - // ============ View Functions ============ - - function isDODORegistered(address baseToken, address quoteToken) public view returns (bool) { - if ( - _DODO_REGISTER_[baseToken][quoteToken] == address(0) && - _DODO_REGISTER_[quoteToken][baseToken] == address(0) - ) { - return false; - } else { - return true; - } - } - - function getDODO(address baseToken, address quoteToken) external view returns (address) { - return _DODO_REGISTER_[baseToken][quoteToken]; - } - - function getDODOs() external view returns (address[] memory) { - return _DODOs; - } -} diff --git a/contracts/Factory/DPPFactory.sol b/contracts/Factory/DPPFactory.sol index a241edc..c5a5150 100644 --- a/contracts/Factory/DPPFactory.sol +++ b/contracts/Factory/DPPFactory.sol @@ -26,20 +26,10 @@ contract DPPFactory is Ownable { address public _VALUE_SOURCE_; address public _DODO_SMART_APPROVE_; - //TODO: 平台修改tag的权限 && 池子标签类型 - struct DPPInfo { - address creator; - uint256 createTimeStamp; - } - // base -> quote -> DPP address list mapping(address => mapping(address => address[])) public _REGISTRY_; - // token0 -> token1 -> DPP address list - mapping(address => mapping(address => address[])) public _SORT_REGISTRY_; // creator -> DPP address list mapping(address => address[]) public _USER_REGISTRY_; - // DPP address -> info - mapping(address => DPPInfo) public _DPP_INFO_; constructor( address cloneFactory, @@ -61,13 +51,13 @@ contract DPPFactory is Ownable { _DEFAULT_GAS_PRICE_SOURCE_ = defaultGasPriceSource; } - function createDODOPrivatePool() external returns(address newPrivatePool) { + function createDODOPrivatePool() external returns (address newPrivatePool) { newPrivatePool = ICloneFactory(_CLONE_FACTORY_).clone(_DPP_TEMPLATE_); } function initDODOPrivatePool( address dppAddress, - address from, + address creator, address baseToken, address quoteToken, uint256 lpFeeRate, @@ -75,38 +65,36 @@ contract DPPFactory is Ownable { uint256 k, uint256 i ) external { - { - address _dppAddress = dppAddress; - address adminModel = _createDPPAdminModel(from,_dppAddress,from,_DODO_SMART_APPROVE_); - IDPP(_dppAddress).init( - adminModel, - from, - baseToken, - quoteToken, - _createFeeRateModel(_dppAddress, lpFeeRate), - _createFeeRateModel(_dppAddress, mtFeeRate), - _createExternalValueModel(_dppAddress, k), - _createExternalValueModel(_dppAddress, i), - _DEFAULT_GAS_PRICE_SOURCE_, - _createPermissionManager(adminModel) - ); + { + address _dppAddress = dppAddress; + address adminModel = _createDPPAdminModel( + creator, + _dppAddress, + creator, + _DODO_SMART_APPROVE_ + ); + IDPP(_dppAddress).init( + adminModel, + creator, + baseToken, + quoteToken, + _createFeeRateModel(_dppAddress, lpFeeRate), + _createFeeRateModel(_dppAddress, mtFeeRate), + _createExternalValueModel(_dppAddress, k), + _createExternalValueModel(_dppAddress, i), + _DEFAULT_GAS_PRICE_SOURCE_, + _createPermissionManager(adminModel) + ); } - { - (address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken); - _SORT_REGISTRY_[token0][token1].push(dppAddress); - } _REGISTRY_[baseToken][quoteToken].push(dppAddress); - _USER_REGISTRY_[from].push(dppAddress); - _DPP_INFO_[dppAddress] = ( - DPPInfo({ - creator: from, - createTimeStamp: block.timestamp - }) - ); + _USER_REGISTRY_[creator].push(dppAddress); } - function _createFeeRateModel(address owner, uint256 feeRate) internal returns (address feeRateModel){ + function _createFeeRateModel(address owner, uint256 feeRate) + internal + returns (address feeRateModel) + { feeRateModel = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_RATE_MODEL_TEMPLATE_); IFeeRateModel(feeRateModel).init(owner, feeRate); } @@ -116,14 +104,22 @@ contract DPPFactory is Ownable { IPermissionManager(permissionManager).initOwner(owner); } - function _createExternalValueModel(address owner, uint256 value) internal returns (address valueModel) { + function _createExternalValueModel(address owner, uint256 value) + internal + returns (address valueModel) + { valueModel = ICloneFactory(_CLONE_FACTORY_).clone(_VALUE_SOURCE_); IExternalValue(valueModel).init(owner, value); } - function _createDPPAdminModel(address owner, address dpp,address operator, address dodoSmartApprove) internal returns (address adminModel) { + function _createDPPAdminModel( + address owner, + address dpp, + address operator, + address dodoSmartApprove + ) internal returns (address adminModel) { adminModel = ICloneFactory(_CLONE_FACTORY_).clone(_DPP_ADMIN_TEMPLATE_); - IDPPAdmin(adminModel).init(owner,dpp,operator,dodoSmartApprove); + IDPPAdmin(adminModel).init(owner, dpp, operator, dodoSmartApprove); } function updateAdminTemplate(address _newDPPAdminTemplate) external onlyOwner { @@ -137,4 +133,12 @@ contract DPPFactory is Ownable { { return _REGISTRY_[baseToken][quoteToken]; } + + function getPrivatePoolBidirection(address token0, address token1) + external + view + returns (address[] memory baseToken0Pool, address[] memory baseToken1Pool) + { + return (_REGISTRY_[token0][token1], _REGISTRY_[token1][token0]); + } } diff --git a/contracts/Factory/DVMFactory.sol b/contracts/Factory/DVMFactory.sol index d01da4e..f0cf9c9 100644 --- a/contracts/Factory/DVMFactory.sol +++ b/contracts/Factory/DVMFactory.sol @@ -23,20 +23,10 @@ contract DVMFactory is Ownable { address public _PERMISSION_MANAGER_TEMPLATE_; address public _DEFAULT_GAS_PRICE_SOURCE_; - //TODO: 平台修改tag的权限 && 池子标签类型 - struct DVMInfo { - address creator; - uint256 createTimeStamp; - } - // base -> quote -> DVM address list mapping(address => mapping(address => address[])) public _REGISTRY_; - // token0 -> token1 -> DVM address list - mapping(address => mapping(address => address[])) public _SORT_REGISTRY_; // creator -> DVM address list mapping(address => address[]) public _USER_REGISTRY_; - // DVM address -> info - mapping(address => DVMInfo) public _DVM_INFO_; constructor( address cloneFactory, @@ -55,7 +45,7 @@ contract DVMFactory is Ownable { } function createDODOVendingMachine( - address from, + address creator, address baseToken, address quoteToken, uint256 lpFeeRate, @@ -65,35 +55,28 @@ contract DVMFactory is Ownable { ) external returns (address newVendingMachine) { newVendingMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_); { - address adminModel = _createDVMAdminModel(from,newVendingMachine); - IDVM(newVendingMachine).init( - adminModel, - from, - baseToken, - quoteToken, - _createFeeRateModel(newVendingMachine, lpFeeRate), - _createFeeRateModel(newVendingMachine, mtFeeRate), - _createPermissionManager(adminModel), - _DEFAULT_GAS_PRICE_SOURCE_, - i, - k - ); + address adminModel = _createDVMAdminModel(creator, newVendingMachine); + IDVM(newVendingMachine).init( + adminModel, + creator, + baseToken, + quoteToken, + _createFeeRateModel(adminModel, lpFeeRate), + _createFeeRateModel(adminModel, mtFeeRate), + _createPermissionManager(adminModel), + _DEFAULT_GAS_PRICE_SOURCE_, + i, + k + ); } _REGISTRY_[baseToken][quoteToken].push(newVendingMachine); - { - (address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken); - _SORT_REGISTRY_[token0][token1].push(newVendingMachine); - } - _USER_REGISTRY_[from].push(newVendingMachine); - _DVM_INFO_[newVendingMachine] = ( - DVMInfo({ - creator: from, - createTimeStamp: block.timestamp - }) - ); + _USER_REGISTRY_[creator].push(newVendingMachine); } - function _createFeeRateModel(address owner, uint256 feeRate) internal returns (address feeRateModel) { + function _createFeeRateModel(address owner, uint256 feeRate) + internal + returns (address feeRateModel) + { feeRateModel = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_RATE_MODEL_TEMPLATE_); IConstFeeRateModel(feeRateModel).init(owner, feeRate); } @@ -103,9 +86,12 @@ contract DVMFactory is Ownable { IPermissionManager(permissionManager).initOwner(owner); } - function _createDVMAdminModel(address owner, address dvm) internal returns (address adminModel) { + function _createDVMAdminModel(address owner, address dvm) + internal + returns (address adminModel) + { adminModel = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_ADMIN_TEMPLATE_); - IDVMAdmin(adminModel).init(owner,dvm); + IDVMAdmin(adminModel).init(owner, dvm); } function updateAdminTemplate(address _newDVMAdminTemplate) external onlyOwner { @@ -119,4 +105,12 @@ contract DVMFactory is Ownable { { return _REGISTRY_[baseToken][quoteToken]; } + + function getVendingMachineBidirection(address token0, address token1) + external + view + returns (address[] memory baseToken0Machines, address[] memory baseToken1Machines) + { + return (_REGISTRY_[token0][token1], _REGISTRY_[token1][token0]); + } } diff --git a/contracts/SmartRoute/DODOApprove.sol b/contracts/SmartRoute/DODOApprove.sol index cbf7aa7..4c0e02c 100644 --- a/contracts/SmartRoute/DODOApprove.sol +++ b/contracts/SmartRoute/DODOApprove.sol @@ -29,7 +29,9 @@ contract DODOApprove is Ownable { address dest, uint256 amount ) external { - require(msg.sender == dodoProxy, 'DODOApprove:Access restricted'); - IERC20(token).safeTransferFrom(who, dest, amount); + require(msg.sender == dodoProxy, "DODOApprove:Access restricted"); + if (amount > 0) { + IERC20(token).safeTransferFrom(who, dest, amount); + } } } diff --git a/contracts/SmartRoute/DODOV1Proxy01.sol b/contracts/SmartRoute/DODOV1Proxy01.sol index 678de37..a421842 100644 --- a/contracts/SmartRoute/DODOV1Proxy01.sol +++ b/contracts/SmartRoute/DODOV1Proxy01.sol @@ -9,14 +9,13 @@ pragma solidity 0.6.9; import {Ownable} from "../lib/Ownable.sol"; import {IERC20} from "../intf/IERC20.sol"; -import {UniversalERC20} from "../lib/UniversalERC20.sol"; +import {UniversalERC20} from "./UniversalERC20.sol"; import {SafeMath} from "../lib/SafeMath.sol"; import {IDODOSellHelper} from "../intf/IDODOSellHelper.sol"; import {IDODOApprove} from "../intf/IDODOApprove.sol"; import {IDODO} from "../intf/IDODO.sol"; import {IWETH} from "../intf/IWETH.sol"; - contract DODOV1Proxy01 is Ownable { using SafeMath for uint256; using UniversalERC20 for IERC20; @@ -27,7 +26,7 @@ contract DODOV1Proxy01 is Ownable { address payable public _WETH_; modifier judgeExpired(uint256 deadline) { - require(deadline >= block.timestamp, 'DODOV1Proxy01: EXPIRED'); + require(deadline >= block.timestamp, "DODOV1Proxy01: EXPIRED"); _; } @@ -63,12 +62,15 @@ contract DODOV1Proxy01 is Ownable { uint256[] memory directions, uint256 deadline ) public payable judgeExpired(deadline) returns (uint256 returnAmount) { - require(minReturnAmount > 0, 'DODOV1Proxy01: Min return should be bigger then 0.'); - if (fromToken != ETH_ADDRESS) { - IDODOApprove(dodoApprove).claimTokens(fromToken, msg.sender, address(this), fromTokenAmount); + IDODOApprove(dodoApprove).claimTokens( + fromToken, + msg.sender, + address(this), + fromTokenAmount + ); } else { - require(msg.value == fromTokenAmount, 'DODOV1Proxy01: ETH_AMOUNT_NOT_MATCH'); + require(msg.value == fromTokenAmount, "DODOV1Proxy01: ETH_AMOUNT_NOT_MATCH"); IWETH(_WETH_).deposit{value: fromTokenAmount}(); } @@ -98,9 +100,16 @@ contract DODOV1Proxy01 is Ownable { returnAmount = IERC20(toToken).universalBalanceOf(address(this)); - require(returnAmount >= minReturnAmount, 'DODOV1Proxy01: Return amount is not enough'); + require(returnAmount >= minReturnAmount, "DODOV1Proxy01: Return amount is not enough"); IERC20(toToken).universalTransfer(msg.sender, returnAmount); - emit OrderHistory(fromToken, toToken, msg.sender, fromTokenAmount, returnAmount, block.timestamp); + emit OrderHistory( + fromToken, + toToken, + msg.sender, + fromTokenAmount, + returnAmount, + block.timestamp + ); } function externalSwap( @@ -112,24 +121,37 @@ contract DODOV1Proxy01 is Ownable { uint256 minReturnAmount, bytes memory callDataConcat, uint256 deadline - ) public payable judgeExpired(deadline) returns (uint256 returnAmount) { - require(minReturnAmount > 0, 'DODOV1Proxy01: Min return should be bigger then 0.'); - + ) public payable judgeExpired(deadline) returns (uint256 returnAmount) { if (fromToken != ETH_ADDRESS) { - IDODOApprove(dodoApprove).claimTokens(fromToken, msg.sender, address(this), fromTokenAmount); - IERC20(fromToken).universalApprove(approveTarget, fromTokenAmount); + IDODOApprove(dodoApprove).claimTokens( + fromToken, + msg.sender, + address(this), + fromTokenAmount + ); + IERC20(fromToken).universalApproveMax(approveTarget, fromTokenAmount); } - (bool success, ) = to.call{value: fromToken == ETH_ADDRESS ? msg.value : 0}( - callDataConcat + (bool success, ) = to.call{value: fromToken == ETH_ADDRESS ? msg.value : 0}(callDataConcat); + + require(success, "DODOV1Proxy01: Contract Swap execution Failed"); + + IERC20(fromToken).universalTransfer( + msg.sender, + IERC20(fromToken).universalBalanceOf(address(this)) ); - require(success, 'DODOV1Proxy01: Contract Swap execution Failed'); - returnAmount = IERC20(toToken).universalBalanceOf(address(this)); - - require(returnAmount >= minReturnAmount, 'DODOV1Proxy01: Return amount is not enough'); + require(returnAmount >= minReturnAmount, "DODOV1Proxy01: Return amount is not enough"); IERC20(toToken).universalTransfer(msg.sender, returnAmount); - emit OrderHistory(fromToken, toToken, msg.sender, fromTokenAmount, returnAmount, block.timestamp); + + emit OrderHistory( + fromToken, + toToken, + msg.sender, + fromTokenAmount, + returnAmount, + block.timestamp + ); } } diff --git a/contracts/SmartRoute/DODOV2Proxy01.sol b/contracts/SmartRoute/DODOV2Proxy01.sol index d19506b..fca680b 100644 --- a/contracts/SmartRoute/DODOV2Proxy01.sol +++ b/contracts/SmartRoute/DODOV2Proxy01.sol @@ -12,7 +12,8 @@ import {IDODOV2} from "../intf/IDODOV2.sol"; import {IERC20} from "../intf/IERC20.sol"; import {IWETH} from "../intf/IWETH.sol"; import {SafeMath} from "../lib/SafeMath.sol"; -import {UniversalERC20} from "../lib/UniversalERC20.sol"; +import {UniversalERC20} from "./UniversalERC20.sol"; +import {SafeERC20} from "../lib/SafeERC20.sol"; import {DecimalMath} from "../lib/DecimalMath.sol"; contract DODOV2Proxy01 is IDODOV2Proxy01 { @@ -22,12 +23,11 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address payable public _WETH_; address public dodoApprove; - address public dodoSellHelper; address public dvmFactory; address public dppFactory; modifier judgeExpired(uint256 deadline) { - require(deadline >= block.timestamp, 'DODOV2Proxy01: EXPIRED'); + require(deadline >= block.timestamp, "DODOV2Proxy01: EXPIRED"); _; } @@ -44,22 +44,21 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256 returnAmount, uint256 timeStamp ); + //======================================================================== constructor( address _dvmFactory, address _dppFactory, address payable _weth, - address _dodoApprove, - address _dodoSellHelper + address _dodoApprove ) public { dvmFactory = _dvmFactory; dppFactory = _dppFactory; _WETH_ = _weth; dodoApprove = _dodoApprove; - dodoSellHelper = _dodoSellHelper; } - + function createDODOVendingMachine( address assetTo, address baseToken, @@ -71,39 +70,55 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256 i, uint256 k, uint256 deadline - ) external virtual override payable judgeExpired(deadline) returns (address newVendingMachine,uint256 shares) { + ) + external + virtual + override + payable + judgeExpired(deadline) + returns (address newVendingMachine, uint256 shares) + { { - address _baseToken = baseToken == ETH_ADDRESS ? _WETH_ : baseToken; - address _quoteToken = quoteToken == ETH_ADDRESS ? _WETH_ : quoteToken; - newVendingMachine = IDODOV2(dvmFactory).createDODOVendingMachine(msg.sender, _baseToken, _quoteToken, lpFeeRate, mtFeeRate, i, k); + address _baseToken = baseToken == ETH_ADDRESS ? _WETH_ : baseToken; + address _quoteToken = quoteToken == ETH_ADDRESS ? _WETH_ : quoteToken; + newVendingMachine = IDODOV2(dvmFactory).createDODOVendingMachine( + msg.sender, + _baseToken, + _quoteToken, + lpFeeRate, + mtFeeRate, + i, + k + ); } - if(baseInAmount > 0){ - if(baseToken != ETH_ADDRESS){ - IDODOV2(dodoApprove).claimTokens(baseToken, msg.sender, newVendingMachine, baseInAmount); - }else { - require(msg.value == baseInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: baseInAmount}(); - assert(IWETH(_WETH_).transfer(newVendingMachine, baseInAmount)); - } - } - if(quoteInAmount > 0){ - if(quoteToken != ETH_ADDRESS){ - IDODOV2(dodoApprove).claimTokens(quoteToken, msg.sender, newVendingMachine, quoteInAmount); - }else { - require(msg.value == quoteInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: quoteInAmount}(); - assert(IWETH(_WETH_).transfer(newVendingMachine, quoteInAmount)); - } - } - (shares,,) = IDODOV2(newVendingMachine).buyShares(assetTo); - } + { + address _baseToken = baseToken; + address _quoteToken = quoteToken; + _deposit( + msg.sender, + newVendingMachine, + _baseToken, + baseInAmount, + _baseToken == ETH_ADDRESS + ); + _deposit( + msg.sender, + newVendingMachine, + _quoteToken, + quoteInAmount, + _quoteToken == ETH_ADDRESS + ); + } + + (shares, , ) = IDODOV2(newVendingMachine).buyShares(assetTo); + } function _addDVMLiquidity( address DVMAddress, uint256 baseInAmount, uint256 quoteInAmount - ) internal virtual view returns (uint baseAdjustedInAmount, uint quoteAdjustedInAmount) { + ) internal virtual view returns (uint256 baseAdjustedInAmount, uint256 quoteAdjustedInAmount) { (uint256 baseReserve, uint256 quoteReserve) = IDODOV2(DVMAddress).getVaultReserve(); if (quoteReserve == 0 && baseReserve == 0) { baseAdjustedInAmount = baseInAmount; @@ -133,59 +148,35 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256 quoteInAmount, uint256 baseMinAmount, uint256 quoteMinAmount, + uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH uint256 deadline - ) external virtual override judgeExpired(deadline) returns (uint256 shares,uint256 baseAdjustedInAmount,uint256 quoteAdjustedInAmount) { - (baseAdjustedInAmount, quoteAdjustedInAmount) = _addDVMLiquidity(DVMAddress,baseInAmount,quoteInAmount); - require(baseAdjustedInAmount >= baseMinAmount && quoteAdjustedInAmount >= quoteMinAmount, 'DODOV2Proxy01: deposit amount is not enough'); + ) + external + virtual + override + payable + judgeExpired(deadline) + returns ( + uint256 shares, + uint256 baseAdjustedInAmount, + uint256 quoteAdjustedInAmount + ) + { + (baseAdjustedInAmount, quoteAdjustedInAmount) = _addDVMLiquidity( + DVMAddress, + baseInAmount, + quoteInAmount + ); + require( + baseAdjustedInAmount >= baseMinAmount && quoteAdjustedInAmount >= quoteMinAmount, + "DODOV2Proxy01: deposit amount is not enough" + ); address _dvm = DVMAddress; - if(baseAdjustedInAmount > 0) { - IDODOV2(dodoApprove).claimTokens(IDODOV2(_dvm)._BASE_TOKEN_(), msg.sender, _dvm, baseAdjustedInAmount); - } - if(quoteAdjustedInAmount > 0) - IDODOV2(dodoApprove).claimTokens(IDODOV2(_dvm)._QUOTE_TOKEN_(), msg.sender, _dvm, quoteAdjustedInAmount); - (shares,,) = IDODOV2(_dvm).buyShares(to); - } - function addDVMLiquidityETH( - address DVMAddress, - address to, - uint256 baseInAmount, - uint256 quoteInAmount, - uint256 baseMinAmount, - uint256 quoteMinAmount, - uint8 flag, // 1 - baseInETH, 2 - quoteInETH - uint256 deadline - ) external virtual override payable judgeExpired(deadline) returns (uint256 shares,uint256 baseAdjustedInAmount,uint256 quoteAdjustedInAmount) { - (baseAdjustedInAmount, quoteAdjustedInAmount) = _addDVMLiquidity(DVMAddress,baseInAmount,quoteInAmount); - require(baseAdjustedInAmount >= baseMinAmount && quoteAdjustedInAmount >= quoteMinAmount, 'DODOV2Proxy01: deposit amount is not enough'); - address _dvm = DVMAddress; - if(baseAdjustedInAmount > 0) { - if(flag == 1) { - require(msg.value >= baseAdjustedInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: baseAdjustedInAmount}(); - assert(IWETH(_WETH_).transfer(_dvm, baseAdjustedInAmount)); - if (msg.value > baseAdjustedInAmount) { - (bool success,) = msg.sender.call{value:msg.value - baseAdjustedInAmount}(new bytes(0)); - require(success, 'DODOV2Proxy01: ETH_TRANSFER_FAILED'); - } - }else { - IDODOV2(dodoApprove).claimTokens(IDODOV2(_dvm)._BASE_TOKEN_(), msg.sender, _dvm, baseAdjustedInAmount); - } - } - if(quoteAdjustedInAmount > 0){ - if(flag == 2) { - require(msg.value >= quoteAdjustedInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: quoteAdjustedInAmount}(); - assert(IWETH(_WETH_).transfer(_dvm, quoteAdjustedInAmount)); - if (msg.value > quoteAdjustedInAmount) { - (bool success,) = msg.sender.call{value:msg.value - quoteAdjustedInAmount}(new bytes(0)); - require(success, 'DODOV2Proxy01: ETH_TRANSFER_FAILED'); - } - }else { - IDODOV2(dodoApprove).claimTokens(IDODOV2(_dvm)._QUOTE_TOKEN_(), msg.sender, _dvm, quoteAdjustedInAmount); - } - } - (shares,,) = IDODOV2(_dvm).buyShares(to); + _deposit(msg.sender, _dvm, IDODOV2(_dvm)._BASE_TOKEN_(), baseAdjustedInAmount, flag == 1); + _deposit(msg.sender, _dvm, IDODOV2(_dvm)._QUOTE_TOKEN_(), quoteAdjustedInAmount, flag == 2); + + (shares, , ) = IDODOV2(_dvm).buyShares(to); } function createDODOPrivatePool( @@ -200,31 +191,26 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256 deadline ) external virtual override payable judgeExpired(deadline) returns (address newPrivatePool) { newPrivatePool = IDODOV2(dppFactory).createDODOPrivatePool(); - if(baseInAmount > 0){ - if(baseToken != ETH_ADDRESS){ - IDODOV2(dodoApprove).claimTokens(baseToken, msg.sender, newPrivatePool, baseInAmount); - }else { - require(msg.value == baseInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: baseInAmount}(); - assert(IWETH(_WETH_).transfer(newPrivatePool, baseInAmount)); - baseToken = _WETH_; - } - } - if(quoteInAmount > 0){ - if(quoteToken != ETH_ADDRESS){ - IDODOV2(dodoApprove).claimTokens(quoteToken, msg.sender, newPrivatePool, quoteInAmount); - }else { - require(msg.value == quoteInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: quoteInAmount}(); - assert(IWETH(_WETH_).transfer(newPrivatePool, quoteInAmount)); - quoteToken = _WETH_; - } - } + + address _baseToken = baseToken; + address _quoteToken = quoteToken; + _deposit(msg.sender, newPrivatePool, _baseToken, baseInAmount, _baseToken == ETH_ADDRESS); + _deposit( + msg.sender, + newPrivatePool, + _quoteToken, + quoteInAmount, + _quoteToken == ETH_ADDRESS + ); + + if (_baseToken == ETH_ADDRESS) _baseToken = _WETH_; + if (_quoteToken == ETH_ADDRESS) _quoteToken = _WETH_; + IDODOV2(dppFactory).initDODOPrivatePool( newPrivatePool, msg.sender, - baseToken, - quoteToken, + _baseToken, + _quoteToken, lpFeeRate, mtFeeRate, k, @@ -242,12 +228,24 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256 quoteInAmount, uint256 baseOutAmount, uint256 quoteOutAmount, + uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH uint256 deadline - ) external virtual override judgeExpired(deadline) { - if(baseInAmount > 0) - IDODOV2(dodoApprove).claimTokens(IDODOV2(DPPAddress)._BASE_TOKEN_(), msg.sender, DPPAddress, baseInAmount); - if(quoteInAmount > 0) - IDODOV2(dodoApprove).claimTokens(IDODOV2(DPPAddress)._QUOTE_TOKEN_(), msg.sender, DPPAddress, quoteInAmount); + ) external virtual override payable judgeExpired(deadline) { + _deposit( + msg.sender, + DPPAddress, + IDODOV2(DPPAddress)._BASE_TOKEN_(), + baseInAmount, + flag == 1 + ); + _deposit( + msg.sender, + DPPAddress, + IDODOV2(DPPAddress)._QUOTE_TOKEN_(), + quoteInAmount, + flag == 2 + ); + IDODOV2(IDODOV2(DPPAddress)._OWNER_()).reset( msg.sender, newLpFeeRate, @@ -257,81 +255,9 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { baseOutAmount, quoteOutAmount ); - } - function resetDODOPrivatePoolETH( - address DPPAddress, - uint256 newLpFeeRate, - uint256 newMtFeeRate, - uint256 newI, - uint256 newK, - uint256 baseInAmount, - uint256 quoteInAmount, - uint256 baseOutAmount, - uint256 quoteOutAmount, - uint8 flag, // 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH - uint256 deadline - ) external virtual override payable judgeExpired(deadline) { - if(baseInAmount > 0){ - if(flag == 1){ - require(msg.value == baseInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: baseInAmount}(); - assert(IWETH(_WETH_).transfer(DPPAddress, baseInAmount)); - }else { - IDODOV2(dodoApprove).claimTokens(IDODOV2(DPPAddress)._BASE_TOKEN_(), msg.sender, DPPAddress, baseInAmount); - } - } - if(quoteInAmount > 0){ - if(flag == 2){ - require(msg.value == quoteInAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); - IWETH(_WETH_).deposit{value: quoteInAmount}(); - assert(IWETH(_WETH_).transfer(DPPAddress, quoteInAmount)); - }else { - IDODOV2(dodoApprove).claimTokens(IDODOV2(DPPAddress)._QUOTE_TOKEN_(), msg.sender, DPPAddress, quoteInAmount); - } - } - if( (flag == 3 && baseOutAmount > 0) || (flag == 4 && quoteOutAmount > 0) ) { - IDODOV2(IDODOV2(DPPAddress)._OWNER_()).resetETH( - msg.sender, - newLpFeeRate, - newMtFeeRate, - newI, - newK, - baseOutAmount, - quoteOutAmount - ); - if(baseOutAmount > 0) { - if(flag == 3) { - uint256 wethAmount = IWETH(_WETH_).balanceOf(address(this)); - IWETH(_WETH_).withdraw(wethAmount); - (bool success,) = msg.sender.call{value:wethAmount}(new bytes(0)); - require(success, 'DODOV2Proxy01: ETH_TRANSFER_FAILED'); - }else { - IERC20(IDODOV2(DPPAddress)._BASE_TOKEN_()).universalTransfer(msg.sender, baseOutAmount); - } - } - - if(quoteOutAmount > 0) { - if(flag == 4) { - uint256 wethAmount = IWETH(_WETH_).balanceOf(address(this)); - IWETH(_WETH_).withdraw(wethAmount); - (bool success,) = msg.sender.call{value:wethAmount}(new bytes(0)); - require(success, 'DODOV2Proxy01: ETH_TRANSFER_FAILED'); - }else { - IERC20(IDODOV2(DPPAddress)._QUOTE_TOKEN_()).universalTransfer(msg.sender, quoteOutAmount); - } - } - }else { - IDODOV2(IDODOV2(DPPAddress)._OWNER_()).reset( - msg.sender, - newLpFeeRate, - newMtFeeRate, - newI, - newK, - baseOutAmount, - quoteOutAmount - ); - } + _withdraw(msg.sender, IDODOV2(DPPAddress)._BASE_TOKEN_(), baseOutAmount, flag == 3); + _withdraw(msg.sender, IDODOV2(DPPAddress)._QUOTE_TOKEN_(), quoteOutAmount, flag == 4); } function dodoSwapETHToToken( @@ -343,28 +269,38 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256[] memory directions, uint256 deadline ) external virtual override payable judgeExpired(deadline) returns (uint256 returnAmount) { - require(minReturnAmount > 0, 'DODOV2Proxy01: Min return should be bigger than 0.'); - require(msg.value == fromTokenAmount, 'DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH'); + uint256 originToTokenBalance = IERC20(toToken).balanceOf(msg.sender); + + require(msg.value == fromTokenAmount, "DODOV2Proxy01: ETH_AMOUNT_NOT_MATCH"); IWETH(_WETH_).deposit{value: fromTokenAmount}(); - IWETH(_WETH_).transfer(dodoPairs[0],IWETH(_WETH_).balanceOf(address(this))); + IWETH(_WETH_).transfer(dodoPairs[0], fromTokenAmount); for (uint256 i = 0; i < dodoPairs.length; i++) { - if(i == dodoPairs.length - 1){ + if (i == dodoPairs.length - 1) { if (directions[i] == 0) { - returnAmount = IDODOV2(dodoPairs[i]).sellBase(assetTo); + IDODOV2(dodoPairs[i]).sellBase(assetTo); } else { - returnAmount = IDODOV2(dodoPairs[i]).sellQuote(assetTo); + IDODOV2(dodoPairs[i]).sellQuote(assetTo); } } else { if (directions[i] == 0) { - IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i+1]); + IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i + 1]); } else { - IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i+1]); + IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i + 1]); } } } - require(returnAmount >= minReturnAmount, 'DODOV2Proxy01: Return amount is not enough'); - emit OrderHistory(ETH_ADDRESS, toToken, assetTo, fromTokenAmount, returnAmount, block.timestamp); + + returnAmount = IERC20(toToken).balanceOf(msg.sender).sub(originToTokenBalance); + require(returnAmount >= minReturnAmount, "DODOV2Proxy01: Return amount is not enough"); + emit OrderHistory( + ETH_ADDRESS, + toToken, + assetTo, + fromTokenAmount, + returnAmount, + block.timestamp + ); } function dodoSwapTokenToETH( @@ -376,11 +312,10 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256[] memory directions, uint256 deadline ) external virtual override judgeExpired(deadline) returns (uint256 returnAmount) { - require(minReturnAmount > 0, 'DODOV2Proxy01: Min return should be bigger than 0.'); IDODOV2(dodoApprove).claimTokens(fromToken, msg.sender, dodoPairs[0], fromTokenAmount); for (uint256 i = 0; i < dodoPairs.length; i++) { - if(i == dodoPairs.length - 1){ + if (i == dodoPairs.length - 1) { if (directions[i] == 0) { IDODOV2(dodoPairs[i]).sellBase(address(this)); } else { @@ -388,20 +323,26 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { } } else { if (directions[i] == 0) { - IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i+1]); + IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i + 1]); } else { - IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i+1]); + IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i + 1]); } } } returnAmount = IWETH(_WETH_).balanceOf(address(this)); + require(returnAmount >= minReturnAmount, "DODOV2Proxy01: Return amount is not enough"); IWETH(_WETH_).withdraw(returnAmount); - require(returnAmount >= minReturnAmount, 'DODOV2Proxy01: Return amount is not enough'); - IERC20(ETH_ADDRESS).universalTransfer(assetTo, returnAmount); - emit OrderHistory(fromToken, ETH_ADDRESS, assetTo, fromTokenAmount, returnAmount, block.timestamp); + assetTo.transfer(returnAmount); + emit OrderHistory( + fromToken, + ETH_ADDRESS, + assetTo, + fromTokenAmount, + returnAmount, + block.timestamp + ); } - function dodoSwapTokenToToken( address payable assetTo, address fromToken, @@ -412,26 +353,34 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { uint256[] memory directions, uint256 deadline ) external virtual override judgeExpired(deadline) returns (uint256 returnAmount) { - require(minReturnAmount > 0, 'DODOV2Proxy01: Min return should be bigger than 0.'); + uint256 originToTokenBalance = IERC20(toToken).balanceOf(msg.sender); IDODOV2(dodoApprove).claimTokens(fromToken, msg.sender, dodoPairs[0], fromTokenAmount); for (uint256 i = 0; i < dodoPairs.length; i++) { - if(i == dodoPairs.length - 1){ + if (i == dodoPairs.length - 1) { if (directions[i] == 0) { - returnAmount = IDODOV2(dodoPairs[i]).sellBase(assetTo); + IDODOV2(dodoPairs[i]).sellBase(assetTo); } else { - returnAmount = IDODOV2(dodoPairs[i]).sellQuote(assetTo); + IDODOV2(dodoPairs[i]).sellQuote(assetTo); } } else { if (directions[i] == 0) { - IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i+1]); + IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i + 1]); } else { - IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i+1]); + IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i + 1]); } } } - require(returnAmount >= minReturnAmount, 'DODOV2Proxy01: Return amount is not enough'); - emit OrderHistory(fromToken, toToken, assetTo, fromTokenAmount, returnAmount, block.timestamp); + returnAmount = IERC20(toToken).balanceOf(msg.sender).sub(originToTokenBalance); + require(returnAmount >= minReturnAmount, "DODOV2Proxy01: Return amount is not enough"); + emit OrderHistory( + fromToken, + toToken, + assetTo, + fromTokenAmount, + returnAmount, + block.timestamp + ); } function externalSwap( @@ -444,21 +393,64 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { bytes memory callDataConcat, uint256 deadline ) external virtual override payable judgeExpired(deadline) returns (uint256 returnAmount) { - require(minReturnAmount > 0, 'DODOV2Proxy01: Min return should be bigger then 0.'); if (fromToken != ETH_ADDRESS) { IDODOV2(dodoApprove).claimTokens(fromToken, msg.sender, address(this), fromTokenAmount); - IERC20(fromToken).universalApprove(approveTarget, fromTokenAmount); + IERC20(fromToken).universalApproveMax(approveTarget, fromTokenAmount); } (bool success, ) = to.call{value: fromToken == ETH_ADDRESS ? msg.value : 0}(callDataConcat); - require(success, 'DODOV2Proxy01: Contract Swap execution Failed'); + require(success, "DODOV2Proxy01: Contract Swap execution Failed"); + + IERC20(fromToken).universalTransfer( + msg.sender, + IERC20(fromToken).universalBalanceOf(address(this)) + ); - IERC20(fromToken).universalTransfer(msg.sender, IERC20(fromToken).universalBalanceOf(address(this))); returnAmount = IERC20(toToken).universalBalanceOf(address(this)); - - require(returnAmount >= minReturnAmount, 'DODOV2Proxy01: Return amount is not enough'); + require(returnAmount >= minReturnAmount, "DODOV2Proxy01: Return amount is not enough"); IERC20(toToken).universalTransfer(msg.sender, returnAmount); - emit OrderHistory(fromToken, toToken, msg.sender, fromTokenAmount, returnAmount, block.timestamp); + + emit OrderHistory( + fromToken, + toToken, + msg.sender, + fromTokenAmount, + returnAmount, + block.timestamp + ); + } + + function _deposit( + address from, + address to, + address token, + uint256 amount, + bool isETH + ) internal { + if (isETH) { + if (amount > 0) { + IWETH(_WETH_).deposit{value: amount}(); + SafeERC20.safeTransfer(IERC20(_WETH_), to, amount); + } + } else { + IDODOV2(dodoApprove).claimTokens(token, from, to, amount); + } + } + + function _withdraw( + address to, + address token, + uint256 amount, + bool isETH + ) internal { + if (isETH) { + if (amount > 0) { + IWETH(_WETH_).withdraw(amount); + msg.sender.transfer(amount); + } + } else { + SafeERC20.safeTransfer(IERC20(token), to, amount); + } } } diff --git a/contracts/lib/UniversalERC20.sol b/contracts/SmartRoute/UniversalERC20.sol similarity index 51% rename from contracts/lib/UniversalERC20.sol rename to contracts/SmartRoute/UniversalERC20.sol index 583f826..33f9d27 100644 --- a/contracts/lib/UniversalERC20.sol +++ b/contracts/SmartRoute/UniversalERC20.sol @@ -7,23 +7,25 @@ pragma solidity 0.6.9; -import {SafeMath} from "./SafeMath.sol"; +import {SafeMath} from "../lib/SafeMath.sol"; import {IERC20} from "../intf/IERC20.sol"; -import {SafeERC20} from "./SafeERC20.sol"; +import {SafeERC20} from "../lib/SafeERC20.sol"; library UniversalERC20 { using SafeMath for uint256; using SafeERC20 for IERC20; - IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000); IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); function isETH(IERC20 token) internal pure returns (bool) { - return (token == ZERO_ADDRESS || token == ETH_ADDRESS); + return token == ETH_ADDRESS; } - - function universalTransfer(IERC20 token, address payable to, uint256 amount) internal { + function universalTransfer( + IERC20 token, + address payable to, + uint256 amount + ) internal { if (amount > 0) { if (isETH(token)) { to.transfer(amount); @@ -33,32 +35,20 @@ library UniversalERC20 { } } - function universalApprove(IERC20 token, address to, uint256 amount) internal { - require(!isETH(token), "ETH Don't need approve"); - if (amount == 0) { - token.safeApprove(to, 0); - } else { - uint256 allowance = token.allowance(address(this), to); - if (allowance < amount) { - if (allowance > 0) { - token.safeApprove(to, 0); - } - token.safeApprove(to, amount); - } - } - } - - function universalApproveMax(IERC20 token, address to, uint256 amount) internal { + function universalApproveMax( + IERC20 token, + address to, + uint256 amount + ) internal { uint256 allowance = token.allowance(address(this), to); if (allowance < amount) { if (allowance > 0) { token.safeApprove(to, 0); } - token.safeApprove(to, uint(-1)); + token.safeApprove(to, uint256(-1)); } } - function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) { if (isETH(token)) { return who.balance; diff --git a/contracts/helper/DODOSellHelper.sol b/contracts/helper/DODOSellHelper.sol index 2a41e92..6b94b19 100644 --- a/contracts/helper/DODOSellHelper.sol +++ b/contracts/helper/DODOSellHelper.sol @@ -1,6 +1,6 @@ /** *Submitted for verification at Etherscan.io on 2020-10-10 -*/ + */ // File: contracts/intf/IDODO.sol @@ -17,8 +17,8 @@ pragma experimental ABIEncoderV2; import {IDODO} from "../intf/IDODO.sol"; import {SafeMath} from "../lib/SafeMath.sol"; import {DecimalMath} from "../lib/DecimalMath.sol"; -// import {DODOMath} from "../lib/DODOMath.sol"; +// import {DODOMath} from "../lib/DODOMath.sol"; library DODOMath { using SafeMath for uint256; @@ -37,10 +37,10 @@ library DODOMath { uint256 i, uint256 k ) internal pure returns (uint256) { - uint256 fairAmount = DecimalMath.mul(i, V1.sub(V2)); // i*delta + uint256 fairAmount = DecimalMath.mulFloor(i, V1.sub(V2)); // i*delta uint256 V0V0V1V2 = DecimalMath.divCeil(V0.mul(V0).div(V1), V2); - uint256 penalty = DecimalMath.mul(k, V0V0V1V2); // k(V0^2/V1/V2) - return DecimalMath.mul(fairAmount, DecimalMath.ONE.sub(k).add(penalty)); + uint256 penalty = DecimalMath.mulFloor(k, V0V0V1V2); // k(V0^2/V1/V2) + return DecimalMath.mulFloor(fairAmount, DecimalMath.ONE.sub(k).add(penalty)); } /* @@ -66,8 +66,8 @@ library DODOMath { ) internal pure returns (uint256) { // calculate -b value and sig // -b = (1-k)Q1-kQ0^2/Q1+i*deltaB - uint256 kQ02Q1 = DecimalMath.mul(k, Q0).mul(Q0).div(Q1); // kQ0^2/Q1 - uint256 b = DecimalMath.mul(DecimalMath.ONE.sub(k), Q1); // (1-k)Q1 + uint256 kQ02Q1 = DecimalMath.mulFloor(k, Q0).mul(Q0).div(Q1); // kQ0^2/Q1 + uint256 b = DecimalMath.mulFloor(DecimalMath.ONE.sub(k), Q1); // (1-k)Q1 bool minusbSig = true; if (deltaBSig) { b = b.add(ideltaB); // (1-k)Q1+i*deltaB @@ -83,9 +83,9 @@ library DODOMath { } // calculate sqrt - uint256 squareRoot = DecimalMath.mul( + uint256 squareRoot = DecimalMath.mulFloor( DecimalMath.ONE.sub(k).mul(4), - DecimalMath.mul(k, Q0).mul(Q0) + DecimalMath.mulFloor(k, Q0).mul(Q0) ); // 4(1-k)kQ0^2 squareRoot = b.mul(b).add(squareRoot).sqrt(); // sqrt(b*b+4(1-k)kQ0*Q0) @@ -117,15 +117,14 @@ library DODOMath { uint256 fairAmount ) internal pure returns (uint256 V0) { // V0 = V1+V1*(sqrt-1)/2k - uint256 sqrt = DecimalMath.divCeil(DecimalMath.mul(k, fairAmount).mul(4), V1); + uint256 sqrt = DecimalMath.divCeil(DecimalMath.mulFloor(k, fairAmount).mul(4), V1); sqrt = sqrt.add(DecimalMath.ONE).mul(DecimalMath.ONE).sqrt(); uint256 premium = DecimalMath.divCeil(sqrt.sub(DecimalMath.ONE), k.mul(2)); // V0 is greater than or equal to V1 according to the solution - return DecimalMath.mul(V1, DecimalMath.ONE.add(premium)); + return DecimalMath.mulFloor(V1, DecimalMath.ONE.add(premium)); } } - contract DODOSellHelper { using SafeMath for uint256; @@ -191,7 +190,7 @@ contract DODOSellHelper { uint256 B2 = DODOMath._SolveQuadraticFunctionForTrade( state.baseTarget, state.baseTarget, - DecimalMath.mul(i, amount), + DecimalMath.mulFloor(i, amount), false, state.K ); @@ -207,7 +206,7 @@ contract DODOSellHelper { uint256 B2 = DODOMath._SolveQuadraticFunctionForTrade( state.baseTarget, state.B, - DecimalMath.mul(i, amount), + DecimalMath.mulFloor(i, amount), false, state.K ); @@ -223,4 +222,4 @@ contract DODOSellHelper { uint256 i = DecimalMath.divFloor(ONE, state.oraclePrice); return DODOMath._GeneralIntegrate(state.quoteTarget, Q1, state.Q, i, state.K); } -} \ No newline at end of file +} diff --git a/contracts/intf/IDODOV2Proxy01.sol b/contracts/intf/IDODOV2Proxy01.sol index 03ffd67..6c62168 100644 --- a/contracts/intf/IDODOV2Proxy01.sol +++ b/contracts/intf/IDODOV2Proxy01.sol @@ -9,7 +9,7 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IDODOV2Proxy01 { - function dodoSwapETHToToken( + function dodoSwapETHToToken( address payable assetTo, address toToken, uint256 fromTokenAmount, @@ -51,7 +51,6 @@ interface IDODOV2Proxy01 { uint256 deadline ) external payable returns (uint256 returnAmount); - function createDODOVendingMachine( address assetTo, address baseToken, @@ -63,29 +62,25 @@ interface IDODOV2Proxy01 { uint256 i, uint256 k, uint256 deadline - ) external payable returns (address newVendingMachine,uint256 shares); + ) external payable returns (address newVendingMachine, uint256 shares); - function addDVMLiquidity( - address DVMAddress, - address to, - uint256 baseInAmount, - uint256 quoteInAmount, - uint256 baseMinAmount, - uint256 quoteMinAmount, - uint256 deadline - ) external returns (uint256 shares,uint256 baseAdjustedInAmount,uint256 quoteAdjustedInAmount); - - function addDVMLiquidityETH( address DVMAddress, address to, uint256 baseInAmount, uint256 quoteInAmount, uint256 baseMinAmount, uint256 quoteMinAmount, - uint8 flag, // 1 - baseInETH, 2 - quoteInETH + uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH uint256 deadline - ) external payable returns (uint256 shares,uint256 baseAdjustedInAmount,uint256 quoteAdjustedInAmount); + ) + external + payable + returns ( + uint256 shares, + uint256 baseAdjustedInAmount, + uint256 quoteAdjustedInAmount + ); function createDODOPrivatePool( address baseToken, @@ -100,20 +95,6 @@ interface IDODOV2Proxy01 { ) external payable returns (address newPrivatePool); function resetDODOPrivatePool( - address DPPAddress, - uint256 newLpFeeRate, - uint256 newMtFeeRate, - uint256 newI, - uint256 newK, - uint256 baseInAmount, - uint256 quoteInAmount, - uint256 baseOutAmount, - uint256 quoteOutAmount, - uint256 deadline - ) external; - - - function resetDODOPrivatePoolETH( address DPPAddress, uint256 newLpFeeRate, uint256 newMtFeeRate, @@ -123,12 +104,11 @@ interface IDODOV2Proxy01 { uint256 quoteInAmount, uint256 baseOutAmount, uint256 quoteOutAmount, - uint8 flag, // 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH + uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH uint256 deadline ) external payable; //TODO: addLiquidityToClassical //TODO: removeLiquidityToClassical - } diff --git a/contracts/lib/DODOMath.sol b/contracts/lib/DODOMath.sol index f15caaa..34c5fab 100644 --- a/contracts/lib/DODOMath.sol +++ b/contracts/lib/DODOMath.sol @@ -69,7 +69,7 @@ library DODOMath { DecimalMath.ONE ); // V0 is greater than or equal to V1 according to the solution - return DecimalMath.mul(V1, premium); + return DecimalMath.mulFloor(V1, premium); } /* @@ -103,6 +103,10 @@ library DODOMath { uint256 k ) internal pure returns (uint256) { require(V0 > 0, "TARGET_IS_ZERO"); + if (delta == 0) { + return 0; + } + if (k == DecimalMath.ONE) { // if k==1 // Q2=Q1/(1+ideltaBQ1/Q0/Q0) @@ -133,9 +137,9 @@ library DODOMath { bAbs = bAbs.div(DecimalMath.ONE); // calculate sqrt - uint256 squareRoot = DecimalMath.mul( + uint256 squareRoot = DecimalMath.mulFloor( DecimalMath.ONE.sub(k).mul(4), - DecimalMath.mul(k, V0).mul(V0) + DecimalMath.mulFloor(k, V0).mul(V0) ); // 4(1-k)kQ0^2 squareRoot = bAbs.mul(bAbs).add(squareRoot).sqrt(); // sqrt(b*b+4(1-k)kQ0*Q0) diff --git a/contracts/lib/DecimalMath.sol b/contracts/lib/DecimalMath.sol index 6218b17..c92c242 100644 --- a/contracts/lib/DecimalMath.sol +++ b/contracts/lib/DecimalMath.sol @@ -22,10 +22,6 @@ library DecimalMath { uint256 constant ONE = 10**18; uint256 constant ONE2 = 10**36; - function mul(uint256 target, uint256 d) internal pure returns (uint256) { - return target.mul(d) / (10**18); - } - function mulFloor(uint256 target, uint256 d) internal pure returns (uint256) { return target.mul(d) / (10**18); } diff --git a/contracts/lib/ExternalCall.sol b/contracts/lib/ExternalCall.sol deleted file mode 100644 index ce8d0b9..0000000 --- a/contracts/lib/ExternalCall.sol +++ /dev/null @@ -1,34 +0,0 @@ -/* - - Copyright 2020 DODO ZOO. - SPDX-License-Identifier: Apache-2.0 - -*/ - -pragma solidity 0.6.9; -pragma experimental ABIEncoderV2; - -library ExternalCall { - // Source: https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol - // call has been separated into its own function in order to take advantage - // of the Solidity's code generator to produce a loop that copies tx.data into memory. - function externalCall(address destination, uint value, bytes memory data, uint dataOffset, uint dataLength, uint gasLimit) internal returns(bool result) { - // solium-disable-next-line security/no-inline-assembly - if (gasLimit == 0) { - gasLimit = gasleft() - 40000; - } - assembly { - let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention) - let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that - result := call( - gasLimit, - destination, - value, - add(d, dataOffset), - dataLength, // Size of the input (in bytes) - this is what fixes the padding problem - x, - 0 // Output is ignored, therefore the output size is zero - ) - } - } -} diff --git a/contracts/lib/PMMPricing.sol b/contracts/lib/PMMPricing.sol index 82039fb..5487c83 100644 --- a/contracts/lib/PMMPricing.sol +++ b/contracts/lib/PMMPricing.sol @@ -234,12 +234,12 @@ library PMMPricing { function getMidPrice(PMMState memory state) internal pure returns (uint256 midPrice) { if (state.R == RState.BELOW_ONE) { uint256 R = DecimalMath.divFloor(state.Q0.mul(state.Q0).div(state.Q), state.Q); - R = DecimalMath.ONE.sub(state.K).add(DecimalMath.mul(state.K, R)); + R = DecimalMath.ONE.sub(state.K).add(DecimalMath.mulFloor(state.K, R)); return DecimalMath.divFloor(state.i, R); } else { uint256 R = DecimalMath.divFloor(state.B0.mul(state.B0).div(state.B), state.B); - R = DecimalMath.ONE.sub(state.K).add(DecimalMath.mul(state.K, R)); - return DecimalMath.mul(state.i, R); + R = DecimalMath.ONE.sub(state.K).add(DecimalMath.mulFloor(state.K, R)); + return DecimalMath.mulFloor(state.i, R); } } } diff --git a/migrations/2_deploy.js b/migrations/2_deploy.js index 8c8c622..c55dbb9 100644 --- a/migrations/2_deploy.js +++ b/migrations/2_deploy.js @@ -2,155 +2,155 @@ const fs = require("fs"); const file = fs.createWriteStream("../deploy-detail.txt"); let logger = new console.Console(file, file); -const SmartApprove = artifacts.require("SmartApprove"); -const SmartSwap = artifacts.require("SmartSwap"); -const DODOSellHelper = artifacts.require("DODOSellHelper"); -const TestERC20 = artifacts.require("TestERC20"); -const NaiveOracle = artifacts.require("NaiveOracle"); -const DODOZoo = artifacts.require("DODOZoo"); +// const SmartApprove = artifacts.require("DODOApprove"); +// const SmartSwap = artifacts.require("SmartSwap"); +// const DODOSellHelper = artifacts.require("DODOSellHelper"); +// const TestERC20 = artifacts.require("TestERC20"); +// const NaiveOracle = artifacts.require("NaiveOracle"); +// const DODOZoo = artifacts.require("DODOZoo"); -const DEPLOY_ROUTE = true; +const DEPLOY_ROUTE = false; const DEPLOY_KOVAN_TOKEN = false; module.exports = async (deployer, network, accounts) => { - let DODOSellHelperAddress = ""; - let DODOZooAddress = ""; - let WETHAddress = ""; - let SmartApproveAddress = ""; - if (network == "kovan") { - DODOSellHelperAddress = "0xbdEae617F2616b45DCB69B287D52940a76035Fe3"; - DODOZooAddress = "0x92230e929a2226b29ed3441ae5524886347c60c8"; - WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b"; - SmartApproveAddress = "0x5627b7DEb3055e1e899003FDca0716b32C382084"; - } else if (network == "live") { - DODOSellHelperAddress = "0x533da777aedce766ceae696bf90f8541a4ba80eb"; - DODOZooAddress = "0x3a97247df274a17c59a3bd12735ea3fcdfb49950"; - WETHAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"; - SmartApproveAddress = "0xe380Ad3181A69BF92133D2feb609867c4adC61eA"; - } else return; + // let DODOSellHelperAddress = ""; + // let DODOZooAddress = ""; + // let WETHAddress = ""; + // let SmartApproveAddress = ""; + // if (network == "kovan") { + // DODOSellHelperAddress = "0xbdEae617F2616b45DCB69B287D52940a76035Fe3"; + // DODOZooAddress = "0x92230e929a2226b29ed3441ae5524886347c60c8"; + // WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b"; + // SmartApproveAddress = "0x5627b7DEb3055e1e899003FDca0716b32C382084"; + // } else if (network == "live") { + // DODOSellHelperAddress = "0x533da777aedce766ceae696bf90f8541a4ba80eb"; + // DODOZooAddress = "0x3a97247df274a17c59a3bd12735ea3fcdfb49950"; + // WETHAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"; + // SmartApproveAddress = "0xe380Ad3181A69BF92133D2feb609867c4adC61eA"; + // } else return; - logger.log("===================================================="); - logger.log("network type: " + network); - logger.log("Deploy time: " + new Date().toLocaleString()); + // logger.log("===================================================="); + // logger.log("network type: " + network); + // logger.log("Deploy time: " + new Date().toLocaleString()); - if (DEPLOY_ROUTE) { - logger.log("Deploy type: Smart Route"); - if (SmartApproveAddress == "") { - await deployer.deploy(SmartApprove); - SmartApproveAddress = SmartApprove.address; - } - if (DODOSellHelperAddress == "") { - await deployer.deploy(DODOSellHelper); - DODOSellHelperAddress = DODOSellHelper.address; - } - logger.log("SmartApprove Address: ", SmartApproveAddress); - logger.log("DODOSellHelper Address: ", DODOSellHelperAddress); - await deployer.deploy( - SmartSwap, - SmartApproveAddress, - DODOSellHelperAddress, - WETHAddress - ); - logger.log("SmartSwap Address: ", SmartSwap.address); + // if (DEPLOY_ROUTE) { + // logger.log("Deploy type: Smart Route"); + // if (SmartApproveAddress == "") { + // await deployer.deploy(SmartApprove); + // SmartApproveAddress = SmartApprove.address; + // } + // if (DODOSellHelperAddress == "") { + // await deployer.deploy(DODOSellHelper); + // DODOSellHelperAddress = DODOSellHelper.address; + // } + // logger.log("SmartApprove Address: ", SmartApproveAddress); + // logger.log("DODOSellHelper Address: ", DODOSellHelperAddress); + // await deployer.deploy( + // SmartSwap, + // SmartApproveAddress, + // DODOSellHelperAddress, + // WETHAddress + // ); + // logger.log("SmartSwap Address: ", SmartSwap.address); - // const SmartApproveInstance = await SmartApprove.at(SmartApproveAddress); - // var tx = await SmartApproveInstance.setSmartSwap(SmartSwap.address); - // logger.log("SmartApprovce setSmartSwap tx: ", tx.tx); - } + // // const SmartApproveInstance = await SmartApprove.at(SmartApproveAddress); + // // var tx = await SmartApproveInstance.setSmartSwap(SmartSwap.address); + // // logger.log("SmartApprovce setSmartSwap tx: ", tx.tx); + // } - if (DEPLOY_KOVAN_TOKEN) { - logger.log("Deploy type: Create Tokens and Trading Pairs"); - await deployer.deploy(TestERC20, "USDC", 6, "USDC"); - const USDCAddr = TestERC20.address; - logger.log("USDC Addr: ", USDCAddr); - await deployer.deploy(TestERC20, "USDT", 6, "USDT"); - const USDTAddr = TestERC20.address; - logger.log("USDT Addr: ", USDTAddr); - await deployer.deploy(TestERC20, "DODO", 18, "DODO"); - const DODOAddr = TestERC20.address; - logger.log("DODO Addr: ", DODOAddr); - await deployer.deploy(TestERC20, "WOO", 18, "WOO"); - const WooAddr = TestERC20.address; - logger.log("WOO Addr: ", WooAddr); - const WETHAddr = WETHAddress; - logger.log("WETH Addr: ", WETHAddr); + // if (DEPLOY_KOVAN_TOKEN) { + // logger.log("Deploy type: Create Tokens and Trading Pairs"); + // await deployer.deploy(TestERC20, "USDC", 6, "USDC"); + // const USDCAddr = TestERC20.address; + // logger.log("USDC Addr: ", USDCAddr); + // await deployer.deploy(TestERC20, "USDT", 6, "USDT"); + // const USDTAddr = TestERC20.address; + // logger.log("USDT Addr: ", USDTAddr); + // await deployer.deploy(TestERC20, "DODO", 18, "DODO"); + // const DODOAddr = TestERC20.address; + // logger.log("DODO Addr: ", DODOAddr); + // await deployer.deploy(TestERC20, "WOO", 18, "WOO"); + // const WooAddr = TestERC20.address; + // logger.log("WOO Addr: ", WooAddr); + // const WETHAddr = WETHAddress; + // logger.log("WETH Addr: ", WETHAddr); - let config = { - lpFeeRate: "2000000000000000", - mtFeeRate: "1000000000000000", - k: "100000000000000000", - gasPriceLimit: "100000000000", - }; + // let config = { + // lpFeeRate: "2000000000000000", + // mtFeeRate: "1000000000000000", + // k: "100000000000000000", + // gasPriceLimit: "100000000000", + // }; - const DODOZooInstance = await DODOZoo.at(DODOZooAddress); + // const DODOZooInstance = await DODOZoo.at(DODOZooAddress); - //USDT-USDC - await deployer.deploy(NaiveOracle); - var USDT_USDC_Oracle = NaiveOracle.address; - await DODOZooInstance.breedDODO( - accounts[0], - USDTAddr, - USDCAddr, - USDT_USDC_Oracle, - config.lpFeeRate, - config.mtFeeRate, - config.k, - config.gasPriceLimit - ); - const USDT_USDC_Addr = await DODOZooInstance.getDODO(USDTAddr, USDCAddr); - logger.log("USDT_USDC_Addr:", USDT_USDC_Addr); + // //USDT-USDC + // await deployer.deploy(NaiveOracle); + // var USDT_USDC_Oracle = NaiveOracle.address; + // await DODOZooInstance.breedDODO( + // accounts[0], + // USDTAddr, + // USDCAddr, + // USDT_USDC_Oracle, + // config.lpFeeRate, + // config.mtFeeRate, + // config.k, + // config.gasPriceLimit + // ); + // const USDT_USDC_Addr = await DODOZooInstance.getDODO(USDTAddr, USDCAddr); + // logger.log("USDT_USDC_Addr:", USDT_USDC_Addr); - // DODO-USDT - await deployer.deploy(NaiveOracle); - var DODO_USDT_Oracle = NaiveOracle.address; - await DODOZooInstance.breedDODO( - accounts[0], - DODOAddr, - USDTAddr, - DODO_USDT_Oracle, - config.lpFeeRate, - config.mtFeeRate, - config.k, - config.gasPriceLimit - ); - const DODO_USDT_Addr = await DODOZooInstance.getDODO(DODOAddr, USDTAddr); - logger.log("DODO_USDT_Addr:", DODO_USDT_Addr); + // // DODO-USDT + // await deployer.deploy(NaiveOracle); + // var DODO_USDT_Oracle = NaiveOracle.address; + // await DODOZooInstance.breedDODO( + // accounts[0], + // DODOAddr, + // USDTAddr, + // DODO_USDT_Oracle, + // config.lpFeeRate, + // config.mtFeeRate, + // config.k, + // config.gasPriceLimit + // ); + // const DODO_USDT_Addr = await DODOZooInstance.getDODO(DODOAddr, USDTAddr); + // logger.log("DODO_USDT_Addr:", DODO_USDT_Addr); - // //WETH-USDC - await deployer.deploy(NaiveOracle); - var WETH_USDC_Oracle = NaiveOracle.address; - await DODOZooInstance.breedDODO( - accounts[0], - WETHAddr, - USDCAddr, - WETH_USDC_Oracle, - config.lpFeeRate, - config.mtFeeRate, - config.k, - config.gasPriceLimit - ); - const WETH_USDC_Addr = await DODOZooInstance.getDODO(WETHAddr, USDCAddr); - logger.log("WETH_USDC_Addr:", WETH_USDC_Addr); + // // //WETH-USDC + // await deployer.deploy(NaiveOracle); + // var WETH_USDC_Oracle = NaiveOracle.address; + // await DODOZooInstance.breedDODO( + // accounts[0], + // WETHAddr, + // USDCAddr, + // WETH_USDC_Oracle, + // config.lpFeeRate, + // config.mtFeeRate, + // config.k, + // config.gasPriceLimit + // ); + // const WETH_USDC_Addr = await DODOZooInstance.getDODO(WETHAddr, USDCAddr); + // logger.log("WETH_USDC_Addr:", WETH_USDC_Addr); - //WOO-USDT - await deployer.deploy(NaiveOracle); - var WOO_USDT_Oracle = NaiveOracle.address; - await DODOZooInstance.breedDODO( - accounts[0], - WooAddr, - USDTAddr, - WOO_USDT_Oracle, - config.lpFeeRate, - config.mtFeeRate, - config.k, - config.gasPriceLimit - ); - const WOO_USDT_Addr = await DODOZooInstance.getDODO(WooAddr, USDTAddr); - logger.log("WOO_USDT_Addr:", WOO_USDT_Addr); + // //WOO-USDT + // await deployer.deploy(NaiveOracle); + // var WOO_USDT_Oracle = NaiveOracle.address; + // await DODOZooInstance.breedDODO( + // accounts[0], + // WooAddr, + // USDTAddr, + // WOO_USDT_Oracle, + // config.lpFeeRate, + // config.mtFeeRate, + // config.k, + // config.gasPriceLimit + // ); + // const WOO_USDT_Addr = await DODOZooInstance.getDODO(WooAddr, USDTAddr); + // logger.log("WOO_USDT_Addr:", WOO_USDT_Addr); - //TODO:ing enableBaseDeposit enableQuoteDeposit enableTrading - //TODO:ing apporve pair to token - //TODO:ing mint to lp - //TODO:ing deposit to Base && quote pool - } + // //TODO:ing enableBaseDeposit enableQuoteDeposit enableTrading + // //TODO:ing apporve pair to token + // //TODO:ing mint to lp + // //TODO:ing deposit to Base && quote pool + // } }; diff --git a/test/DVM/trader.test.ts b/test/DVM/trader.test.ts index 81de2ce..dc19452 100644 --- a/test/DVM/trader.test.ts +++ b/test/DVM/trader.test.ts @@ -48,16 +48,19 @@ describe("Trader", () => { }); describe("trade", () => { - // it.only("basic check", async () => { - // console.log(await ctx.DVM.methods.getVaultReserve().call()) - // console.log(await ctx.DVM.methods.getPMMState().call()) - // console.log(await ctx.DVM.methods.getMidPrice().call()) - // console.log(await ctx.DVM.methods.querySellQuote(ctx.Deployer, decimalStr("200")).call()) - // console.log(ctx.BASE.options.address) - // console.log(await ctx.DVM.methods._BASE_TOKEN_().call()) - // console.log(ctx.QUOTE.options.address) - // console.log(await ctx.DVM.methods._QUOTE_TOKEN_().call()) - // }) + it.only("basic check", async () => { + console.log(await ctx.DVM.methods.symbol().call()) + console.log(await ctx.DVM.methods.decimals().call()) + console.log(await ctx.DVM.methods.name().call()) + // console.log(await ctx.DVM.methods.getVaultReserve().call()) + // console.log(await ctx.DVM.methods.getPMMState().call()) + // console.log(await ctx.DVM.methods.getMidPrice().call()) + // console.log(await ctx.DVM.methods.querySellQuote(ctx.Deployer, decimalStr("200")).call()) + // console.log(ctx.BASE.options.address) + // console.log(await ctx.DVM.methods._BASE_TOKEN_().call()) + // console.log(ctx.QUOTE.options.address) + // console.log(await ctx.DVM.methods._QUOTE_TOKEN_().call()) + }) // it.only("mannually buy", async () => { // await ctx.QUOTE.methods.transfer(ctx.DVM.options.address, decimalStr("100")).send(ctx.sendParam(lp))