From e8d83b947ba1b52fc0d4f38269128d75f01f2cf5 Mon Sep 17 00:00:00 2001 From: owen05 Date: Tue, 8 Dec 2020 22:52:10 +0800 Subject: [PATCH 1/3] add factory get view --- contracts/Factory/DPPFactory.sol | 8 ++++++++ contracts/Factory/DVMFactory.sol | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/contracts/Factory/DPPFactory.sol b/contracts/Factory/DPPFactory.sol index 7053668..17f9474 100644 --- a/contracts/Factory/DPPFactory.sol +++ b/contracts/Factory/DPPFactory.sol @@ -159,4 +159,12 @@ contract DPPFactory is Ownable { { return (_REGISTRY_[token0][token1], _REGISTRY_[token1][token0]); } + + function getPrivatePoolByUser(address user) + external + view + returns (address[] memory pools) + { + return _USER_REGISTRY_[user]; + } } diff --git a/contracts/Factory/DVMFactory.sol b/contracts/Factory/DVMFactory.sol index 3ab3fd0..8a0d76c 100644 --- a/contracts/Factory/DVMFactory.sol +++ b/contracts/Factory/DVMFactory.sol @@ -131,4 +131,12 @@ contract DVMFactory is Ownable { { return (_REGISTRY_[token0][token1], _REGISTRY_[token1][token0]); } + + function getVendingMachineByUser(address user) + external + view + returns (address[] memory machines) + { + return _USER_REGISTRY_[user]; + } } From ca692ee548fe99bd8f10b00b8f49692293a2719a Mon Sep 17 00:00:00 2001 From: owen05 Date: Wed, 9 Dec 2020 00:06:48 +0800 Subject: [PATCH 2/3] add minimum liquidity --- contracts/DODOVendingMachine/impl/DVMFunding.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contracts/DODOVendingMachine/impl/DVMFunding.sol b/contracts/DODOVendingMachine/impl/DVMFunding.sol index 7e992f4..d94893f 100644 --- a/contracts/DODOVendingMachine/impl/DVMFunding.sol +++ b/contracts/DODOVendingMachine/impl/DVMFunding.sol @@ -50,7 +50,8 @@ contract DVMFunding is DVMVault { // 在提币的时候向下取整。因此永远不会出现,balance为0但totalsupply不为0的情况 // 但有可能出现,reserve>0但totalSupply=0的场景 if (totalSupply == 0) { - shares = baseBalance; // 以免出现balance很大但shares很小的情况 + shares = baseBalance.sub(10**3); // 以免出现balance很大但shares很小的情况 + _mint(address(0), 10**3); } else if (baseReserve > 0 && quoteReserve == 0) { // case 2. supply when quote reserve is 0 shares = baseInput.mul(totalSupply).div(baseReserve); @@ -61,6 +62,7 @@ contract DVMFunding is DVMVault { uint256 mintRatio = quoteInputRatio < baseInputRatio ? quoteInputRatio : baseInputRatio; shares = DecimalMath.mulFloor(totalSupply, mintRatio); } + require(shares > 0, 'INSUFFICIENT_LIQUIDITY_MINED'); _mint(to, shares); _sync(); emit BuyShares(to, shares, _SHARES_[to]); From fc39f709f2ae94b8f738abd6254dcf538bb7dbec Mon Sep 17 00:00:00 2001 From: owen05 Date: Wed, 9 Dec 2020 11:20:27 +0800 Subject: [PATCH 3/3] audit fix02 --- contracts/DODOPrivatePool/impl/DPPTrader.sol | 7 ++++++- .../DODOVendingMachine/impl/DVMStorage.sol | 2 +- contracts/DODOVendingMachine/impl/DVMTrader.sol | 7 ++++++- contracts/SmartRoute/DODOV1Proxy01.sol | 11 +++++++++++ contracts/SmartRoute/DODOV2Proxy01.sol | 17 ++++++++++++++++- contracts/lib/DODOMath.sol | 2 +- 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/contracts/DODOPrivatePool/impl/DPPTrader.sol b/contracts/DODOPrivatePool/impl/DPPTrader.sol index 8b8eee0..8d79743 100644 --- a/contracts/DODOPrivatePool/impl/DPPTrader.sol +++ b/contracts/DODOPrivatePool/impl/DPPTrader.sol @@ -122,7 +122,12 @@ contract DPPTrader is DPPVault { uint256 quoteAmount, address assetTo, bytes calldata data - ) external preventReentrant { + ) + external + preventReentrant + isSellAllow(assetTo) + isBuyAllow(assetTo) + { _transferBaseOut(assetTo, baseAmount); _transferQuoteOut(assetTo, quoteAmount); diff --git a/contracts/DODOVendingMachine/impl/DVMStorage.sol b/contracts/DODOVendingMachine/impl/DVMStorage.sol index 075cc41..e484154 100644 --- a/contracts/DODOVendingMachine/impl/DVMStorage.sol +++ b/contracts/DODOVendingMachine/impl/DVMStorage.sol @@ -42,7 +42,7 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { // ============ Shares (ERC20) ============ string public symbol; - uint256 public decimals; + uint8 public decimals; string public name; uint256 public totalSupply; diff --git a/contracts/DODOVendingMachine/impl/DVMTrader.sol b/contracts/DODOVendingMachine/impl/DVMTrader.sol index bb60fb9..d082a1f 100644 --- a/contracts/DODOVendingMachine/impl/DVMTrader.sol +++ b/contracts/DODOVendingMachine/impl/DVMTrader.sol @@ -103,7 +103,12 @@ contract DVMTrader is DVMVault { uint256 quoteAmount, address assetTo, bytes calldata data - ) external preventReentrant { + ) + external + preventReentrant + isSellAllow(assetTo) + isBuyAllow(assetTo) + { _transferBaseOut(assetTo, baseAmount); _transferQuoteOut(assetTo, quoteAmount); diff --git a/contracts/SmartRoute/DODOV1Proxy01.sol b/contracts/SmartRoute/DODOV1Proxy01.sol index 89ae848..94a515a 100644 --- a/contracts/SmartRoute/DODOV1Proxy01.sol +++ b/contracts/SmartRoute/DODOV1Proxy01.sol @@ -32,6 +32,7 @@ contract DODOV1Proxy01 is IDODOV1Proxy01, ReentrancyGuard, Ownable { address public immutable _CHI_TOKEN_; uint8 public _GAS_DODO_MAX_RETURN_ = 0; uint8 public _GAS_EXTERNAL_RETURN_ = 0; + mapping (address => bool) public isWhiteListed; // ============ Events ============ @@ -71,6 +72,14 @@ contract DODOV1Proxy01 is IDODOV1Proxy01, ReentrancyGuard, Ownable { _GAS_EXTERNAL_RETURN_ = newExternalGasReturn; } + function addWhiteList (address contractAddr) public onlyOwner { + isWhiteListed[contractAddr] = true; + } + + function removeWhiteList (address contractAddr) public onlyOwner { + isWhiteListed[contractAddr] = false; + } + function dodoSwapV1( address fromToken, address toToken, @@ -80,6 +89,7 @@ contract DODOV1Proxy01 is IDODOV1Proxy01, ReentrancyGuard, Ownable { uint8[] memory directions, uint256 deadLine ) external override payable judgeExpired(deadLine) returns (uint256 returnAmount) { + require(dodoPairs.length == directions.length, "DODOV1Proxy01: PARAMS_LENGTH_NOT_MATCH"); uint256 originGas = gasleft(); if (fromToken != _ETH_ADDRESS_) { @@ -159,6 +169,7 @@ contract DODOV1Proxy01 is IDODOV1Proxy01, ReentrancyGuard, Ownable { IERC20(_fromToken).universalApproveMax(approveTarget, fromTokenAmount); } + require(isWhiteListed[to], "DODOV1Proxy01: Not Whitelist Contract"); (bool success, ) = to.call{value: _fromToken == _ETH_ADDRESS_ ? msg.value : 0}(callDataConcat); require(success, "DODOV1Proxy01: Contract Swap execution Failed"); diff --git a/contracts/SmartRoute/DODOV2Proxy01.sol b/contracts/SmartRoute/DODOV2Proxy01.sol index 87bd0eb..0d808b2 100644 --- a/contracts/SmartRoute/DODOV2Proxy01.sol +++ b/contracts/SmartRoute/DODOV2Proxy01.sol @@ -19,8 +19,9 @@ import {UniversalERC20} from "./lib/UniversalERC20.sol"; import {SafeERC20} from "../lib/SafeERC20.sol"; import {DecimalMath} from "../lib/DecimalMath.sol"; import {ReentrancyGuard} from "../lib/ReentrancyGuard.sol"; +import {Ownable} from "../lib/Ownable.sol"; -contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { +contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, Ownable { using SafeMath for uint256; using UniversalERC20 for IERC20; @@ -32,6 +33,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { address public immutable _DODO_SELL_HELPER_; address public immutable _DVM_FACTORY_; address public immutable _DPP_FACTORY_; + mapping (address => bool) public isWhiteListed; // ============ Events ============ @@ -68,6 +70,14 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { _DODO_SELL_HELPER_ = dodoSellHelper; } + function addWhiteList (address contractAddr) public onlyOwner { + isWhiteListed[contractAddr] = true; + } + + function removeWhiteList (address contractAddr) public onlyOwner { + isWhiteListed[contractAddr] = false; + } + // ============ DVM Functions (create & add liquidity) ============ function createDODOVendingMachine( @@ -299,6 +309,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { judgeExpired(deadLine) returns (uint256 returnAmount) { + require(dodoPairs.length == directions.length, "DODOV2Proxy01: PARAMS_LENGTH_NOT_MATCH"); uint256 originToTokenBalance = IERC20(toToken).balanceOf(msg.sender); IWETH(_WETH_).deposit{value: msg.value}(); @@ -345,6 +356,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { judgeExpired(deadLine) returns (uint256 returnAmount) { + require(dodoPairs.length == directions.length, "DODOV2Proxy01: PARAMS_LENGTH_NOT_MATCH"); IDODOApprove(_DODO_APPROVE_).claimTokens(fromToken, msg.sender, dodoPairs[0], fromTokenAmount); for (uint256 i = 0; i < dodoPairs.length; i++) { @@ -390,6 +402,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { judgeExpired(deadLine) returns (uint256 returnAmount) { + require(dodoPairs.length == directions.length, "DODOV2Proxy01: PARAMS_LENGTH_NOT_MATCH"); uint256 originToTokenBalance = IERC20(toToken).balanceOf(msg.sender); IDODOApprove(_DODO_APPROVE_).claimTokens(fromToken, msg.sender, dodoPairs[0], fromTokenAmount); @@ -447,6 +460,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { IERC20(fromToken).universalApproveMax(approveTarget, fromTokenAmount); } + require(isWhiteListed[to], "DODOV2Proxy01: Not Whitelist Contract"); (bool success, ) = to.call{value: fromToken == _ETH_ADDRESS_ ? msg.value : 0}(callDataConcat); require(success, "DODOV2Proxy01: Contract Swap execution Failed"); @@ -488,6 +502,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard { judgeExpired(deadLine) returns (uint256 returnAmount) { + require(dodoPairs.length == directions.length, "DODOV2Proxy01: PARAMS_LENGTH_NOT_MATCH"); _deposit(msg.sender, address(this), fromToken, fromTokenAmount, fromToken == _ETH_ADDRESS_); for (uint256 i = 0; i < dodoPairs.length; i++) { diff --git a/contracts/lib/DODOMath.sol b/contracts/lib/DODOMath.sol index ad62a41..0a7ac42 100644 --- a/contracts/lib/DODOMath.sol +++ b/contracts/lib/DODOMath.sol @@ -123,7 +123,7 @@ library DODOMath { if (k == DecimalMath.ONE) { // if k==1 // Q2=Q1/(1+ideltaBQ1/Q0/Q0) - // temp = (1+ideltaBQ1/Q0/Q0) + // temp = ideltaBQ1/Q0/Q0 // Q1-Q2 = Q1*(temp/(1+temp)) uint256 temp = i.mul(delta).mul(V1).div(V0.mul(V0)); return V1.mul(temp).div(temp.add(DecimalMath.ONE));