From 83c8bbaa8541e4296f5c77431b0f40b781b72e13 Mon Sep 17 00:00:00 2001 From: owen05 Date: Fri, 18 Dec 2020 01:11:33 +0800 Subject: [PATCH] cp audit-fix && update event --- contracts/CrowdPooling/impl/CPFunding.sol | 14 +++++------ contracts/DODOPrivatePool/impl/DPPTrader.sol | 17 ++++++++++--- contracts/DODOPrivatePool/impl/DPPVault.sol | 17 +++++++++++-- .../DODOVendingMachine/impl/DVMFunding.sol | 6 ++--- .../DODOVendingMachine/impl/DVMTrader.sol | 17 ++++++++++--- .../DODOVendingMachine/impl/DVMVault.sol | 10 ++++++++ contracts/Factory/CrowdPoolingFactory.sol | 6 ++--- contracts/Factory/DPPFactory.sol | 12 +++++---- contracts/Factory/DVMFactory.sol | 16 ++++++------ contracts/Factory/ERC20Factory.sol | 6 +---- contracts/Factory/UnownedDVMFactory.sol | 17 +++++++------ contracts/SmartRoute/DODOV2Proxy01.sol | 25 +++++++++++-------- contracts/lib/PermissionManager.sol | 2 +- deploy-detail-v1.5.txt | 8 ++++++ migrations/2_deploy_v1.5.js | 5 ++-- 15 files changed, 116 insertions(+), 62 deletions(-) diff --git a/contracts/CrowdPooling/impl/CPFunding.sol b/contracts/CrowdPooling/impl/CPFunding.sol index 6d5e723..4284a37 100644 --- a/contracts/CrowdPooling/impl/CPFunding.sol +++ b/contracts/CrowdPooling/impl/CPFunding.sol @@ -74,22 +74,22 @@ contract CPFunding is CPStorage { address _poolBaseToken; address _poolQuoteToken; uint256 _poolI; - if (poolQuote == baseDepth) { + if (poolQuote.mul(_UNUSED_BASE_) == poolQuote.add(ownerQuote).mul(poolBase)) { _poolBaseToken = address(_BASE_TOKEN_); _poolQuoteToken = address(_QUOTE_TOKEN_); _poolI = 1; - } else if (poolQuote < baseDepth) { + } else if (poolQuote.mul(_UNUSED_BASE_) < poolQuote.add(ownerQuote).mul(poolBase)) { // poolI up round _poolBaseToken = address(_BASE_TOKEN_); _poolQuoteToken = address(_QUOTE_TOKEN_); - uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divCeil(poolQuote, baseDepth)); + uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divFloor(poolQuote, baseDepth)); _poolI = avgPrice.mul(ratio).mul(ratio).divCeil(DecimalMath.ONE2); - } else if (poolQuote > baseDepth) { + } else if (poolQuote.mul(_UNUSED_BASE_) > poolQuote.add(ownerQuote).mul(poolBase)) { // poolI down round _poolBaseToken = address(_QUOTE_TOKEN_); _poolQuoteToken = address(_BASE_TOKEN_); - uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divFloor(baseDepth, poolQuote)); - _poolI = DecimalMath.reciprocalFloor(avgPrice).mul(ratio).mul(ratio).div( + uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divCeil(baseDepth, poolQuote)); + _poolI = ratio.mul(ratio).div(avgPrice).div( DecimalMath.ONE2 ); } @@ -113,7 +113,7 @@ contract CPFunding is CPStorage { // in case something wrong with base token contract function emergencySettle() external phaseSettlement preventReentrant { - require(block.timestamp > _PHASE_CALM_ENDTIME_.add(_SETTLEMENT_EXPIRE_), "NOT_EMERGENCY"); + require(block.timestamp >= _PHASE_CALM_ENDTIME_.add(_SETTLEMENT_EXPIRE_), "NOT_EMERGENCY"); _settle(); _UNUSED_QUOTE_ = _QUOTE_TOKEN_.balanceOf(address(this)); _UNUSED_BASE_ = _BASE_TOKEN_.balanceOf(address(this)); diff --git a/contracts/DODOPrivatePool/impl/DPPTrader.sol b/contracts/DODOPrivatePool/impl/DPPTrader.sol index deab4e5..009a4e4 100644 --- a/contracts/DODOPrivatePool/impl/DPPTrader.sol +++ b/contracts/DODOPrivatePool/impl/DPPTrader.sol @@ -27,6 +27,13 @@ contract DPPTrader is DPPVault { address trader ); + event DODOFlashLoan( + address borrower, + address assetTo, + uint256 baseAmount, + uint256 quoteAmount + ); + // ============ Modifiers ============ modifier isBuyAllow(address trader) { @@ -77,7 +84,7 @@ contract DPPTrader is DPPVault { address(_QUOTE_TOKEN_), baseInput, receiveQuoteAmount, - tx.origin + msg.sender ); } @@ -113,7 +120,7 @@ contract DPPTrader is DPPVault { address(_BASE_TOKEN_), quoteInput, receiveBaseAmount, - tx.origin + msg.sender ); } @@ -160,7 +167,7 @@ contract DPPTrader is DPPVault { address(_BASE_TOKEN_), quoteInput, receiveBaseAmount, - tx.origin + msg.sender ); } @@ -186,11 +193,13 @@ contract DPPTrader is DPPVault { address(_QUOTE_TOKEN_), baseInput, receiveQuoteAmount, - tx.origin + msg.sender ); } _sync(); + + emit DODOFlashLoan(msg.sender, assetTo, baseAmount, quoteAmount); } // ============ Query Functions ============ diff --git a/contracts/DODOPrivatePool/impl/DPPVault.sol b/contracts/DODOPrivatePool/impl/DPPVault.sol index 330548f..5576a79 100644 --- a/contracts/DODOPrivatePool/impl/DPPVault.sol +++ b/contracts/DODOPrivatePool/impl/DPPVault.sol @@ -23,7 +23,10 @@ contract DPPVault is DPPStorage { // ============ Events ============ - event Reset(); + event Reset( + uint256 newLpFeeRate, + uint256 newMtFeeRate + ); // ============ View Functions ============ @@ -32,6 +35,16 @@ contract DPPVault is DPPStorage { quoteReserve = _QUOTE_RESERVE_; } + function getUserFeeRate(address user) external view returns (uint256 lpFeeRate, uint256 mtFeeRate) { + lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(user); + mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(user); + } + + function getUserTradePermission(address user) external view returns (bool isBuyAllow, bool isSellAllow) { + isBuyAllow = (!_BUYING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(user)); + isSellAllow = (!_SELLING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(user)); + } + // ============ Get Input ============ function getBaseInput() public view returns (uint256 input) { @@ -75,7 +88,7 @@ contract DPPVault is DPPStorage { _transferQuoteOut(assetTo, quoteOutAmount); _resetTargetAndReserve(); _checkIK(); - emit Reset(); + emit Reset(newLpFeeRate, newMtFeeRate); } function _setRState() internal { diff --git a/contracts/DODOVendingMachine/impl/DVMFunding.sol b/contracts/DODOVendingMachine/impl/DVMFunding.sol index de3262e..f3f6509 100644 --- a/contracts/DODOVendingMachine/impl/DVMFunding.sol +++ b/contracts/DODOVendingMachine/impl/DVMFunding.sol @@ -15,11 +15,11 @@ import {IDODOCallee} from "../../intf/IDODOCallee.sol"; contract DVMFunding is DVMVault { // ============ Events ============ - event BuyShares(address indexed to, uint256 increaseShares, uint256 totalShares); + event BuyShares(address to, uint256 increaseShares, uint256 totalShares); event SellShares( - address indexed payer, - address indexed to, + address payer, + address to, uint256 decreaseShares, uint256 totalShares ); diff --git a/contracts/DODOVendingMachine/impl/DVMTrader.sol b/contracts/DODOVendingMachine/impl/DVMTrader.sol index e5f6e2d..07a2f0b 100644 --- a/contracts/DODOVendingMachine/impl/DVMTrader.sol +++ b/contracts/DODOVendingMachine/impl/DVMTrader.sol @@ -28,6 +28,13 @@ contract DVMTrader is DVMVault { address trader ); + event DODOFlashLoan( + address borrower, + address assetTo, + uint256 baseAmount, + uint256 quoteAmount + ); + // ============ Modifiers ============ modifier isBuyAllow(address trader) { @@ -70,7 +77,7 @@ contract DVMTrader is DVMVault { address(_QUOTE_TOKEN_), baseInput, receiveQuoteAmount, - tx.origin + msg.sender ); } @@ -94,7 +101,7 @@ contract DVMTrader is DVMVault { address(_BASE_TOKEN_), quoteInput, receiveBaseAmount, - tx.origin + msg.sender ); } @@ -112,7 +119,7 @@ contract DVMTrader is DVMVault { uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this)); uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this)); - + // no input -> pure loss require( baseBalance >= _BASE_RESERVE_ || quoteBalance >= _QUOTE_RESERVE_, @@ -147,11 +154,13 @@ contract DVMTrader is DVMVault { address(_QUOTE_TOKEN_), baseInput, receiveQuoteAmount, - tx.origin + msg.sender ); } _sync(); + + emit DODOFlashLoan(msg.sender, assetTo, baseAmount, quoteAmount); } // ============ Query Functions ============ diff --git a/contracts/DODOVendingMachine/impl/DVMVault.sol b/contracts/DODOVendingMachine/impl/DVMVault.sol index 26f6abf..5157c85 100644 --- a/contracts/DODOVendingMachine/impl/DVMVault.sol +++ b/contracts/DODOVendingMachine/impl/DVMVault.sol @@ -35,6 +35,16 @@ contract DVMVault is DVMStorage { quoteReserve = _QUOTE_RESERVE_; } + function getUserFeeRate(address user) external view returns (uint256 lpFeeRate, uint256 mtFeeRate) { + lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(user); + mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(user); + } + + function getUserTradePermission(address user) external view returns (bool isBuyAllow, bool isSellAllow) { + isBuyAllow = (!_BUYING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(user)); + isSellAllow = (!_SELLING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(user)); + } + // ============ Asset In ============ function getBaseInput() public view returns (uint256 input) { diff --git a/contracts/Factory/CrowdPoolingFactory.sol b/contracts/Factory/CrowdPoolingFactory.sol index c043994..37b5dba 100644 --- a/contracts/Factory/CrowdPoolingFactory.sol +++ b/contracts/Factory/CrowdPoolingFactory.sol @@ -35,9 +35,9 @@ contract CrowdPoolingFactory { // ============ Events ============ event NewCP( - address indexed baseToken, - address indexed quoteToken, - address indexed creator, + address baseToken, + address quoteToken, + address creator, address cp ); diff --git a/contracts/Factory/DPPFactory.sol b/contracts/Factory/DPPFactory.sol index 4e5e73a..34291f9 100644 --- a/contracts/Factory/DPPFactory.sol +++ b/contracts/Factory/DPPFactory.sol @@ -38,10 +38,12 @@ contract DPPFactory is InitializableOwnable { // ============ Events ============ event NewDPP( - address indexed baseToken, - address indexed quoteToken, - address indexed creator, - address dpp + address baseToken, + address quoteToken, + address creator, + address dpp, + uint256 lpFeeRate, + uint256 mtFeeRate ); // ============ Functions ============ @@ -104,7 +106,7 @@ contract DPPFactory is InitializableOwnable { _REGISTRY_[baseToken][quoteToken].push(dppAddress); _USER_REGISTRY_[creator].push(dppAddress); - emit NewDPP(baseToken, quoteToken, creator, dppAddress); + emit NewDPP(baseToken, quoteToken, creator, dppAddress, lpFeeRate, mtFeeRate); } function _createFeeRateModel(address owner, uint256 feeRate) diff --git a/contracts/Factory/DVMFactory.sol b/contracts/Factory/DVMFactory.sol index 7f2302a..1ef98d6 100644 --- a/contracts/Factory/DVMFactory.sol +++ b/contracts/Factory/DVMFactory.sol @@ -10,7 +10,7 @@ pragma experimental ABIEncoderV2; import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; import {ICloneFactory} from "../lib/CloneFactory.sol"; -import {IConstFeeRateModel} from "../lib/ConstFeeRateModel.sol"; +import {IFeeRateModel} from "../lib/FeeRateModel.sol"; import {IDVM} from "../DODOVendingMachine/intf/IDVM.sol"; import {IDVMAdmin} from "../DODOVendingMachine/intf/IDVMAdmin.sol"; import {IPermissionManager} from "../lib/PermissionManager.sol"; @@ -47,10 +47,12 @@ contract DVMFactory is InitializableOwnable { // ============ Events ============ event NewDVM( - address indexed baseToken, - address indexed quoteToken, - address indexed creator, - address dvm + address baseToken, + address quoteToken, + address creator, + address dvm, + uint256 lpFeeRate, + uint256 mtFeeRate ); // ============ Functions ============ @@ -98,7 +100,7 @@ contract DVMFactory is InitializableOwnable { } _REGISTRY_[baseToken][quoteToken].push(newVendingMachine); _USER_REGISTRY_[creator].push(newVendingMachine); - emit NewDVM(baseToken, quoteToken, creator, newVendingMachine); + emit NewDVM(baseToken, quoteToken, creator, newVendingMachine, lpFeeRate, mtFeeRate); } function _createFeeRateModel(address owner, uint256 feeRate) @@ -106,7 +108,7 @@ contract DVMFactory is InitializableOwnable { returns (address feeRateModel) { feeRateModel = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_RATE_MODEL_TEMPLATE_); - IConstFeeRateModel(feeRateModel).init(owner, feeRate); + IFeeRateModel(feeRateModel).init(owner, feeRate); } function _createPermissionManager(address owner) internal returns (address permissionManager) { diff --git a/contracts/Factory/ERC20Factory.sol b/contracts/Factory/ERC20Factory.sol index 2a18905..7d409ef 100644 --- a/contracts/Factory/ERC20Factory.sol +++ b/contracts/Factory/ERC20Factory.sol @@ -9,10 +9,6 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; import {ICloneFactory} from "../lib/CloneFactory.sol"; -import {IConstFeeRateModel} from "../lib/ConstFeeRateModel.sol"; -import {IDVM} from "../DODOVendingMachine/intf/IDVM.sol"; -import {IDVMAdmin} from "../DODOVendingMachine/intf/IDVMAdmin.sol"; -import {IPermissionManager} from "../lib/PermissionManager.sol"; import {InitializableERC20} from "../external/ERC20/InitializableERC20.sol"; import {InitializableMintableERC20} from "../external/ERC20/InitializableMintableERC20.sol"; @@ -25,7 +21,7 @@ contract ERC20Factory { // ============ Events ============ - event NewERC20(address indexed erc20, address indexed creator, bool isMintable); + event NewERC20(address erc20, address creator, bool isMintable); // ============ Functions ============ diff --git a/contracts/Factory/UnownedDVMFactory.sol b/contracts/Factory/UnownedDVMFactory.sol index d99e82a..5ff04ac 100644 --- a/contracts/Factory/UnownedDVMFactory.sol +++ b/contracts/Factory/UnownedDVMFactory.sol @@ -10,7 +10,7 @@ pragma experimental ABIEncoderV2; import {Ownable} from "../lib/Ownable.sol"; import {ICloneFactory} from "../lib/CloneFactory.sol"; -import {IConstFeeRateModel} from "../lib/ConstFeeRateModel.sol"; +import {IFeeRateModel} from "../lib/FeeRateModel.sol"; import {IDVM} from "../DODOVendingMachine/intf/IDVM.sol"; import {IDVMAdmin} from "../DODOVendingMachine/intf/IDVMAdmin.sol"; import {IPermissionManager} from "../lib/PermissionManager.sol"; @@ -49,11 +49,12 @@ contract UnownedDVMFactory { // ============ Events ============ - event NewDVM( - address indexed baseToken, - address indexed quoteToken, - address indexed creator, - address dvm + event NewUnOwnedDVM( + address baseToken, + address quoteToken, + address creator, + address dvm, + uint256 lpFeeRate ); // ============ Functions ============ @@ -102,7 +103,7 @@ contract UnownedDVMFactory { } _REGISTRY_[baseToken][quoteToken].push(newVendingMachine); _USER_REGISTRY_[creator].push(newVendingMachine); - emit NewDVM(baseToken, quoteToken, creator, newVendingMachine); + emit NewUnOwnedDVM(baseToken, quoteToken, creator, newVendingMachine, lpFeeRate); } function _createFeeRateModel(address owner, uint256 feeRate) @@ -110,7 +111,7 @@ contract UnownedDVMFactory { returns (address feeRateModel) { feeRateModel = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_RATE_MODEL_TEMPLATE_); - IConstFeeRateModel(feeRateModel).init(owner, feeRate); + IFeeRateModel(feeRateModel).init(owner, feeRate); } // ============ View Functions ============ diff --git a/contracts/SmartRoute/DODOV2Proxy01.sol b/contracts/SmartRoute/DODOV2Proxy01.sol index dcb0b05..015ddb9 100644 --- a/contracts/SmartRoute/DODOV2Proxy01.sol +++ b/contracts/SmartRoute/DODOV2Proxy01.sol @@ -40,11 +40,12 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable // ============ Events ============ event OrderHistory( - address indexed fromToken, - address indexed toToken, - address indexed sender, + address fromToken, + address toToken, + address sender, uint256 fromAmount, - uint256 returnAmount + uint256 returnAmount, + uint8 sourceFlag ); // ============ Modifiers ============ @@ -342,7 +343,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable toToken, assetTo, msg.value, - returnAmount + returnAmount, + 0 ); } @@ -387,7 +389,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable _ETH_ADDRESS_, assetTo, fromTokenAmount, - returnAmount + returnAmount, + 0 ); } @@ -432,7 +435,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable toToken, assetTo, fromTokenAmount, - returnAmount + returnAmount, + 0 ); } @@ -487,7 +491,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable toToken, msg.sender, fromTokenAmount, - returnAmount + returnAmount, + 3 ); } @@ -538,7 +543,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable require(returnAmount >= minReturnAmount, "DODOV2Proxy01: Return amount is not enough"); IERC20(toToken).universalTransfer(msg.sender, returnAmount); - emit OrderHistory(fromToken, toToken, msg.sender, fromTokenAmount, returnAmount); + emit OrderHistory(fromToken, toToken, msg.sender, fromTokenAmount, returnAmount, 1); } function mixSwapV1( @@ -594,7 +599,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable returnAmount = IERC20(_toToken).universalBalanceOf(msg.sender).sub(toTokenOriginBalance); require(returnAmount >= minReturnAmount, "DODOV2Proxy01: Return amount is not enough"); - emit OrderHistory(_fromToken, _toToken, msg.sender, fromTokenAmount, returnAmount); + emit OrderHistory(_fromToken, _toToken, msg.sender, fromTokenAmount, returnAmount, 2); } //============ CrowdPooling Functions (create & bid) ============ diff --git a/contracts/lib/PermissionManager.sol b/contracts/lib/PermissionManager.sol index aa92415..aace02f 100644 --- a/contracts/lib/PermissionManager.sol +++ b/contracts/lib/PermissionManager.sol @@ -13,7 +13,7 @@ import {InitializableOwnable} from "./InitializableOwnable.sol"; interface IPermissionManager { function initOwner(address) external; - function isAllowed(address) external returns (bool); + function isAllowed(address) external view returns (bool); } contract PermissionManager is InitializableOwnable { diff --git a/deploy-detail-v1.5.txt b/deploy-detail-v1.5.txt index 753d137..3501322 100644 --- a/deploy-detail-v1.5.txt +++ b/deploy-detail-v1.5.txt @@ -66,3 +66,11 @@ network type: bsclive Deploy time: 2020/12/15 下午6:45:35 Deploy type: Proxy DODOSwapCalcHelperAddress: 0xb0199C2c8ADF1E6c1e41De60A62E993406Cb8C02 +==================================================== +network type: bsclive +Deploy time: 2020/12/16 上午10:40:39 +Deploy type: Proxy +DODOApprove Address: 0xa128Ba44B2738A558A1fdC06d6303d52D3Cef8c1 +DODOProxyV1 Address: 0x0cA2d4BC266B1ad7a0787409AD7a0331D78Eea90 +Set DODOProxyV1 Owner tx: 0x35c8405b4b4dfbac83971c622f4e086dc0f850ade69da408792eb9a835a683f4 +Set DODOApprove Owner And Init Set Proxy tx: 0xb381ac8a87a834a6ab8cc63064153dd2c65261e7c43e5d1a504bcae11fb42a10 diff --git a/migrations/2_deploy_v1.5.js b/migrations/2_deploy_v1.5.js index 276d1c2..2a503d5 100644 --- a/migrations/2_deploy_v1.5.js +++ b/migrations/2_deploy_v1.5.js @@ -36,8 +36,7 @@ module.exports = async (deployer, network, accounts) => { DODOApproveAddress = ""; chiAddress = "0x0000000000000000000000000000000000000000"; DODOSwapCalcHelperAddress = "0xb0199C2c8ADF1E6c1e41De60A62E993406Cb8C02"; - //TODO:待生成替换 - ownerAddress = accounts[0]; + ownerAddress = "0x4073f2b9bB95774531b9e23d206a308c614A943a"; } else return; if (DEPLOY_ROUTE) { @@ -80,7 +79,7 @@ module.exports = async (deployer, network, accounts) => { logger.log("Set DODOApprove Owner And Init Set Proxy tx: ", tx.tx); // var tx1 = await DODOProxyV1Instance.addWhiteList("0x111111125434b319222cdbf8c261674adb56f3ae"); - // var tx2 = await DODOProxyV1Instance.addWhiteList("0xf740b67da229f2f10bcbd38a7979992fcc71b8eb"); + // var tx2 = await DODOProxyV1Instance.addWhiteList("0xdef1c0ded9bec7f1a1670819833240f027b25eff"); // logger.log("AddWhiteList tx1: ", tx1.tx); // logger.log("AddWhiteList tx2: ", tx2.tx); }