fix admin control && update proxy test framework

This commit is contained in:
owen05
2020-11-25 17:08:28 +08:00
parent 8a4da4b525
commit 8da583d5a8
25 changed files with 383 additions and 177 deletions

View File

@@ -15,13 +15,10 @@ import {IERC20} from "../../intf/IERC20.sol";
import {DPPTrader} from "./DPPTrader.sol"; import {DPPTrader} from "./DPPTrader.sol";
contract DPP is DPPTrader { contract DPP is DPPTrader {
constructor() public {
_FACTORY_ = msg.sender;
}
function init( function init(
address owner, address owner,
address maintainer, address maintainer,
address operator,
address baseTokenAddress, address baseTokenAddress,
address quoteTokenAddress, address quoteTokenAddress,
address lpFeeRateModel, address lpFeeRateModel,
@@ -29,12 +26,13 @@ contract DPP is DPPTrader {
address kSource, address kSource,
address iSource, address iSource,
address gasPriceSource, address gasPriceSource,
address dodoSmartApprove,
address tradePermissionManager address tradePermissionManager
) external { ) external {
require(msg.sender == _FACTORY_, 'INIT FORBIDDEN');
initOwner(owner); initOwner(owner);
_ADMIN_ = owner; _ADMIN_ = owner;
_MAINTAINER_ = maintainer; _MAINTAINER_ = maintainer;
_OPERATOR_ = operator;
_BASE_TOKEN_ = IERC20(baseTokenAddress); _BASE_TOKEN_ = IERC20(baseTokenAddress);
_QUOTE_TOKEN_ = IERC20(quoteTokenAddress); _QUOTE_TOKEN_ = IERC20(quoteTokenAddress);
_LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel); _LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel);
@@ -43,6 +41,8 @@ contract DPP is DPPTrader {
_K_ = IExternalValue(kSource); _K_ = IExternalValue(kSource);
_GAS_PRICE_LIMIT_ = IExternalValue(gasPriceSource); _GAS_PRICE_LIMIT_ = IExternalValue(gasPriceSource);
_TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager); _TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager);
_DODO_SMART_APPROVE_ = dodoSmartApprove;
_resetTargetAndReserve();
} }
// ============ Version Control ============ // ============ Version Control ============

View File

@@ -36,6 +36,10 @@ contract DPPAdmin is InitializableOwnable {
IDPP(dpp).setMaintainer(newMaintainer); IDPP(dpp).setMaintainer(newMaintainer);
} }
function setOperator(address newOperator) external onlyOwner {
IDPP(dpp).setOperator(newOperator);
}
function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner { function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner {
IDPP(dpp).setGasPriceSource(newGasPriceLimitSource); IDPP(dpp).setGasPriceSource(newGasPriceLimitSource);
} }
@@ -55,4 +59,13 @@ contract DPPAdmin is InitializableOwnable {
function setSell(bool open) external onlyOwner { function setSell(bool open) external onlyOwner {
IDPP(dpp).setSell(open); IDPP(dpp).setSell(open);
} }
function retrieve(address payable to,address token,uint256 amount) external onlyOwner {
IDPP(dpp).retrieve(to,token,amount);
}
// ============ Admin Version Control ============
function version() external pure returns (uint256) {
return 100; // 1.0.0
}
} }

View File

@@ -27,8 +27,8 @@ import {PMMPricing} from "../../lib/PMMPricing.sol";
contract DPPStorage is InitializableOwnable, ReentrancyGuard { contract DPPStorage is InitializableOwnable, ReentrancyGuard {
using SafeMath for uint256; using SafeMath for uint256;
address public _FACTORY_;
address public _ADMIN_; address public _ADMIN_;
address public _DODO_SMART_APPROVE_;
// ============ Variables for Control ============ // ============ Variables for Control ============
@@ -44,6 +44,7 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard {
// ============ Core Address ============ // ============ Core Address ============
address public _MAINTAINER_; // collect maintainer fee address public _MAINTAINER_; // collect maintainer fee
address public _OPERATOR_;
IERC20 public _BASE_TOKEN_; IERC20 public _BASE_TOKEN_;
IERC20 public _QUOTE_TOKEN_; IERC20 public _QUOTE_TOKEN_;
@@ -79,6 +80,10 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard {
_MAINTAINER_ = newMaintainer; _MAINTAINER_ = newMaintainer;
} }
function setOperator(address newOperator) external onlyOwner {
_OPERATOR_ = newOperator;
}
function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner { function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner {
_GAS_PRICE_LIMIT_ = IExternalValue(newGasPriceLimitSource); _GAS_PRICE_LIMIT_ = IExternalValue(newGasPriceLimitSource);
} }

View File

@@ -15,6 +15,7 @@ import {SafeMath} from "../../lib/SafeMath.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol"; import {SafeERC20} from "../../lib/SafeERC20.sol";
import {Ownable} from "../../lib/Ownable.sol"; import {Ownable} from "../../lib/Ownable.sol";
import {ISmartApprove} from '../../intf/ISmartApprove.sol';
contract DPPVault is DPPStorage { contract DPPVault is DPPStorage {
using SafeMath for uint256; using SafeMath for uint256;
@@ -55,12 +56,6 @@ contract DPPVault is DPPStorage {
_QUOTE_RESERVE_ = _QUOTE_TOKEN_.balanceOf(address(this)); _QUOTE_RESERVE_ = _QUOTE_TOKEN_.balanceOf(address(this));
} }
//TODO:
function initTargetAndReserve() public {
require(tx.origin == _OWNER_, "INIT FORBIDDEN");
_resetTargetAndReserve();
}
function _resetTargetAndReserve() internal { function _resetTargetAndReserve() internal {
_BASE_TARGET_ = _BASE_TOKEN_.balanceOf(address(this)); _BASE_TARGET_ = _BASE_TOKEN_.balanceOf(address(this));
_QUOTE_TARGET_ = _QUOTE_TOKEN_.balanceOf(address(this)); _QUOTE_TARGET_ = _QUOTE_TOKEN_.balanceOf(address(this));
@@ -69,6 +64,7 @@ contract DPPVault is DPPStorage {
} }
function reset( function reset(
address from,
uint256 newLpFeeRate, uint256 newLpFeeRate,
uint256 newMtFeeRate, uint256 newMtFeeRate,
uint256 newI, uint256 newI,
@@ -76,11 +72,10 @@ contract DPPVault is DPPStorage {
uint256 baseOutAmount, uint256 baseOutAmount,
uint256 quoteOutAmount uint256 quoteOutAmount
) public { ) public {
//TODO: owner 权限可以是operator require(msg.sender == ISmartApprove(_DODO_SMART_APPROVE_).getSmartSwap() && from == _OPERATOR_, "RESET FORBIDDEN");
require(tx.origin == _OWNER_, "RESET FORBIDDEN");
require(newK > 0 && newK <= 10**18, "K OUT OF RANGE!"); require(newK > 0 && newK <= 10**18, "K OUT OF RANGE!");
if(baseOutAmount > 0) _transferBaseOut(tx.origin, baseOutAmount); if(baseOutAmount > 0) _transferBaseOut(from, baseOutAmount);
if(quoteOutAmount > 0) _transferQuoteOut(tx.origin, quoteOutAmount); if(quoteOutAmount > 0) _transferQuoteOut(from, quoteOutAmount);
_resetTargetAndReserve(); _resetTargetAndReserve();
_LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate); _LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate);
_MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate); _MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate);
@@ -115,7 +110,7 @@ contract DPPVault is DPPStorage {
uint256 amount uint256 amount
) external onlyOwner { ) external onlyOwner {
require(to != address(_BASE_TOKEN_) && to != address(_QUOTE_TOKEN_), "USE_WITHDRAW"); require(to != address(_BASE_TOKEN_) && to != address(_QUOTE_TOKEN_), "USE_WITHDRAW");
if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { if (token == 0x000000000000000000000000000000000000000E) {
to.transfer(amount); to.transfer(amount);
} else { } else {
IERC20(token).safeTransfer(msg.sender, amount); IERC20(token).safeTransfer(msg.sender, amount);

View File

@@ -12,6 +12,7 @@ interface IDPP {
function init( function init(
address owner, address owner,
address maintainer, address maintainer,
address operator,
address baseTokenAddress, address baseTokenAddress,
address quoteTokenAddress, address quoteTokenAddress,
address lpFeeRateModel, address lpFeeRateModel,
@@ -19,6 +20,7 @@ interface IDPP {
address kSource, address kSource,
address iSource, address iSource,
address gasPriceSource, address gasPriceSource,
address dodoSmartApprove,
address tradePermissionManager address tradePermissionManager
) external; ) external;
@@ -31,6 +33,8 @@ interface IDPP {
function setMaintainer(address newMaintainer) external; function setMaintainer(address newMaintainer) external;
function setOperator(address newOperator) external;
function setGasPriceSource(address newGasPriceLimitSource) external; function setGasPriceSource(address newGasPriceLimitSource) external;
function setISource(address newISource) external; function setISource(address newISource) external;
@@ -42,4 +46,6 @@ interface IDPP {
function setSell(bool open) external; function setSell(bool open) external;
//============================== //==============================
function retrieve(address payable to,address token,uint256 amount) external;
} }

View File

@@ -17,10 +17,6 @@ import {DVMFunding} from "./DVMFunding.sol";
import {DVMVault} from "./DVMVault.sol"; import {DVMVault} from "./DVMVault.sol";
contract DVM is DVMTrader, DVMFunding { contract DVM is DVMTrader, DVMFunding {
constructor() public {
_FACTORY_ = msg.sender;
}
function init( function init(
address owner, address owner,
address maintainer, address maintainer,
@@ -33,7 +29,6 @@ contract DVM is DVMTrader, DVMFunding {
uint256 i, uint256 i,
uint256 k uint256 k
) external { ) external {
require(msg.sender == _FACTORY_, 'INIT FORBIDDEN');
initOwner(owner); initOwner(owner);
_ADMIN_ = owner; _ADMIN_ = owner;
_BASE_TOKEN_ = IERC20(baseTokenAddress); _BASE_TOKEN_ = IERC20(baseTokenAddress);

View File

@@ -47,4 +47,9 @@ contract DVMAdmin is InitializableOwnable {
function setSell(bool open) external onlyOwner { function setSell(bool open) external onlyOwner {
IDVM(dvm).setSell(open); IDVM(dvm).setSell(open);
} }
// ============ Admin Version Control ============
function version() external pure returns (uint256) {
return 100; // 1.0.0
}
} }

View File

@@ -21,7 +21,6 @@ import {IERC20} from "../../intf/IERC20.sol";
contract DVMStorage is InitializableOwnable, ReentrancyGuard { contract DVMStorage is InitializableOwnable, ReentrancyGuard {
using SafeMath for uint256; using SafeMath for uint256;
address public _FACTORY_;
address public _ADMIN_; address public _ADMIN_;
// ============ Variables for Control ============ // ============ Variables for Control ============
@@ -63,8 +62,6 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
uint256 public _I_; uint256 public _I_;
// ============ Setting Functions ============ // ============ Setting Functions ============
//TODO: owner权限问题论证
function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner { function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner {
_LP_FEE_RATE_MODEL_ = IFeeRateModel(newLpFeeRateModel); _LP_FEE_RATE_MODEL_ = IFeeRateModel(newLpFeeRateModel);
} }

View File

@@ -22,7 +22,9 @@ contract DPPFactory is Ownable {
address public _DPP_ADMIN_TEMPLATE_; address public _DPP_ADMIN_TEMPLATE_;
address public _FEE_RATE_MODEL_TEMPLATE_; address public _FEE_RATE_MODEL_TEMPLATE_;
address public _PERMISSION_MANAGER_TEMPLATE_; address public _PERMISSION_MANAGER_TEMPLATE_;
address public _DEFAULT_GAS_PRICE_SOURCE_;
address public _VALUE_SOURCE_; address public _VALUE_SOURCE_;
address public _DODO_SMART_APPROVE_;
//TODO: 平台修改tag的权限 && 池子标签类型 //TODO: 平台修改tag的权限 && 池子标签类型
struct DPPInfo { struct DPPInfo {
@@ -31,13 +33,13 @@ contract DPPFactory is Ownable {
} }
// base -> quote -> DPP address list // base -> quote -> DPP address list
mapping(address => mapping(address => address[])) _REGISTRY_; mapping(address => mapping(address => address[])) public _REGISTRY_;
// token0 -> token1 -> DPP address list // token0 -> token1 -> DPP address list
mapping(address => mapping(address => address[])) _SORT_REGISTRY_; mapping(address => mapping(address => address[])) public _SORT_REGISTRY_;
// creator -> DPP address list // creator -> DPP address list
mapping(address => address[]) _USER_REGISTRY_; mapping(address => address[]) public _USER_REGISTRY_;
// DPP address -> info // DPP address -> info
mapping(address => DPPInfo) _DPP_INFO_; mapping(address => DPPInfo) public _DPP_INFO_;
constructor( constructor(
address cloneFactory, address cloneFactory,
@@ -45,7 +47,9 @@ contract DPPFactory is Ownable {
address dppAdminTemplate, address dppAdminTemplate,
address defautFeeRateModelTemplate, address defautFeeRateModelTemplate,
address defaultPermissionManagerTemplate, address defaultPermissionManagerTemplate,
address defaultExternalValueTemplate address defaultExternalValueTemplate,
address defaultGasPriceSource,
address dodoSmartApprove
) public { ) public {
_CLONE_FACTORY_ = cloneFactory; _CLONE_FACTORY_ = cloneFactory;
_DPP_TEMPLATE_ = dppTemplate; _DPP_TEMPLATE_ = dppTemplate;
@@ -53,40 +57,52 @@ contract DPPFactory is Ownable {
_FEE_RATE_MODEL_TEMPLATE_ = defautFeeRateModelTemplate; _FEE_RATE_MODEL_TEMPLATE_ = defautFeeRateModelTemplate;
_PERMISSION_MANAGER_TEMPLATE_ = defaultPermissionManagerTemplate; _PERMISSION_MANAGER_TEMPLATE_ = defaultPermissionManagerTemplate;
_VALUE_SOURCE_ = defaultExternalValueTemplate; _VALUE_SOURCE_ = defaultExternalValueTemplate;
_DEFAULT_GAS_PRICE_SOURCE_ = defaultGasPriceSource;
_DODO_SMART_APPROVE_ = dodoSmartApprove;
} }
function createDODOPrivatePool( function createDODOPrivatePool() external returns(address newPrivatePool) {
newPrivatePool = ICloneFactory(_CLONE_FACTORY_).clone(_DPP_TEMPLATE_);
}
function initDODOPrivatePool(
address dppAddress,
address from,
address baseToken, address baseToken,
address quoteToken, address quoteToken,
uint256 lpFeeRate, uint256 lpFeeRate,
uint256 mtFeeRate, uint256 mtFeeRate,
uint256 i, uint256 k,
uint256 k uint256 i
) external returns (address newPrivatePool) { ) external {
(address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken); {
newPrivatePool = ICloneFactory(_CLONE_FACTORY_).clone(_DPP_TEMPLATE_); address _dppAddress = dppAddress;
address adminModel = _createDPPAdminModel(from,_dppAddress);
IDPP(newPrivatePool).init( IDPP(_dppAddress).init(
_createDPPAdminModel(msg.sender,newPrivatePool), adminModel,
msg.sender, from,
from,
baseToken, baseToken,
quoteToken, quoteToken,
_createFeeRateModel(newPrivatePool, lpFeeRate), _createFeeRateModel(_dppAddress, lpFeeRate),
_createFeeRateModel(newPrivatePool, mtFeeRate), _createFeeRateModel(_dppAddress, mtFeeRate),
_createExternalValueModel(newPrivatePool, k), _createExternalValueModel(_dppAddress, k),
_createExternalValueModel(newPrivatePool, i), _createExternalValueModel(_dppAddress, i),
//TODO:hardcode _DEFAULT_GAS_PRICE_SOURCE_,
_createExternalValueModel(msg.sender, 10**22), _DODO_SMART_APPROVE_,
//TODO:讨论 _createPermissionManager(adminModel)
_createPermissionManager(msg.sender)
); );
}
_REGISTRY_[baseToken][quoteToken].push(newPrivatePool); {
_SORT_REGISTRY_[token0][token1].push(newPrivatePool); (address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken);
_USER_REGISTRY_[msg.sender].push(newPrivatePool); _SORT_REGISTRY_[token0][token1].push(dppAddress);
_DPP_INFO_[newPrivatePool] = ( }
_REGISTRY_[baseToken][quoteToken].push(dppAddress);
_USER_REGISTRY_[from].push(dppAddress);
_DPP_INFO_[dppAddress] = (
DPPInfo({ DPPInfo({
creator: msg.sender, creator: from,
createTimeStamp: block.timestamp createTimeStamp: block.timestamp
}) })
); );
@@ -112,8 +128,16 @@ contract DPPFactory is Ownable {
IDPPAdmin(adminModel).init(owner,dpp); IDPPAdmin(adminModel).init(owner,dpp);
} }
//TODO: 讨论 or 升级整个Factory
function updateAdminTemplate(address _newDPPAdminTemplate) external onlyOwner { function updateAdminTemplate(address _newDPPAdminTemplate) external onlyOwner {
_DPP_ADMIN_TEMPLATE_ = _newDPPAdminTemplate; _DPP_ADMIN_TEMPLATE_ = _newDPPAdminTemplate;
} }
function getPrivatePool(address baseToken, address quoteToken)
external
view
returns (address[] memory pools)
{
return _REGISTRY_[baseToken][quoteToken];
}
} }

View File

@@ -30,13 +30,13 @@ contract DVMFactory is Ownable {
} }
// base -> quote -> DVM address list // base -> quote -> DVM address list
mapping(address => mapping(address => address[])) _REGISTRY_; mapping(address => mapping(address => address[])) public _REGISTRY_;
// token0 -> token1 -> DVM address list // token0 -> token1 -> DVM address list
mapping(address => mapping(address => address[])) _SORT_REGISTRY_; mapping(address => mapping(address => address[])) public _SORT_REGISTRY_;
// creator -> DVM address list // creator -> DVM address list
mapping(address => address[]) _USER_REGISTRY_; mapping(address => address[]) public _USER_REGISTRY_;
// DVM address -> info // DVM address -> info
mapping(address => DVMInfo) _DVM_INFO_; mapping(address => DVMInfo) public _DVM_INFO_;
constructor( constructor(
address cloneFactory, address cloneFactory,
@@ -55,6 +55,7 @@ contract DVMFactory is Ownable {
} }
function createDODOVendingMachine( function createDODOVendingMachine(
address from,
address baseToken, address baseToken,
address quoteToken, address quoteToken,
uint256 lpFeeRate, uint256 lpFeeRate,
@@ -62,32 +63,34 @@ contract DVMFactory is Ownable {
uint256 i, uint256 i,
uint256 k uint256 k
) external returns (address newVendingMachine) { ) external returns (address newVendingMachine) {
(address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken);
newVendingMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_); newVendingMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_);
{
address adminModel = _createDVMAdminModel(from,newVendingMachine);
IDVM(newVendingMachine).init( IDVM(newVendingMachine).init(
_createDVMAdminModel(msg.sender,newVendingMachine), adminModel,
msg.sender, from,
baseToken, baseToken,
quoteToken, quoteToken,
_createFeeRateModel(newVendingMachine, lpFeeRate), _createFeeRateModel(newVendingMachine, lpFeeRate),
_createFeeRateModel(newVendingMachine, mtFeeRate), _createFeeRateModel(newVendingMachine, mtFeeRate),
_createPermissionManager(msg.sender), _createPermissionManager(adminModel),
_DEFAULT_GAS_PRICE_SOURCE_, _DEFAULT_GAS_PRICE_SOURCE_,
i, i,
k k
); );
}
_REGISTRY_[baseToken][quoteToken].push(newVendingMachine); _REGISTRY_[baseToken][quoteToken].push(newVendingMachine);
{
(address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken);
_SORT_REGISTRY_[token0][token1].push(newVendingMachine); _SORT_REGISTRY_[token0][token1].push(newVendingMachine);
_USER_REGISTRY_[msg.sender].push(newVendingMachine); }
_USER_REGISTRY_[from].push(newVendingMachine);
_DVM_INFO_[newVendingMachine] = ( _DVM_INFO_[newVendingMachine] = (
DVMInfo({ DVMInfo({
creator: msg.sender, creator: from,
createTimeStamp: block.timestamp createTimeStamp: block.timestamp
}) })
); );
return newVendingMachine;
} }
function _createFeeRateModel(address owner, uint256 feeRate) internal returns (address feeRateModel) { function _createFeeRateModel(address owner, uint256 feeRate) internal returns (address feeRateModel) {
@@ -105,7 +108,6 @@ contract DVMFactory is Ownable {
IDVMAdmin(adminModel).init(owner,dvm); IDVMAdmin(adminModel).init(owner,dvm);
} }
//TODO: 讨论 or 升级整个Factory
function updateAdminTemplate(address _newDVMAdminTemplate) external onlyOwner { function updateAdminTemplate(address _newDVMAdminTemplate) external onlyOwner {
_DVM_ADMIN_TEMPLATE_ = _newDVMAdminTemplate; _DVM_ADMIN_TEMPLATE_ = _newDVMAdminTemplate;
} }

View File

@@ -19,7 +19,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 {
using SafeMath for uint256; using SafeMath for uint256;
using UniversalERC20 for IERC20; using UniversalERC20 for IERC20;
address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address constant ETH_ADDRESS = 0x000000000000000000000000000000000000000E;
address payable public _WETH_; address payable public _WETH_;
address public smartApprove; address public smartApprove;
address public dodoSellHelper; address public dodoSellHelper;
@@ -44,8 +44,6 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 {
event ExternalRecord(address indexed to, address indexed sender); event ExternalRecord(address indexed to, address indexed sender);
//======================================================================== //========================================================================
constructor( constructor(
address _dvmFactory, address _dvmFactory,
address _dppFactory, address _dppFactory,
@@ -73,7 +71,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 {
uint256 deadline uint256 deadline
) external virtual override payable judgeExpired(deadline) returns (address newVendingMachine,uint256 shares) { ) external virtual override payable judgeExpired(deadline) returns (address newVendingMachine,uint256 shares) {
require(k > 0 && k<= 10**18, "DODOV2Proxy01: K OUT OF RANGE"); require(k > 0 && k<= 10**18, "DODOV2Proxy01: K OUT OF RANGE");
newVendingMachine = IDODOV2(dvmFactory).createDODOVendingMachine(baseToken,quoteToken,lpFeeRate,mtFeeRate,i,k); newVendingMachine = IDODOV2(dvmFactory).createDODOVendingMachine(msg.sender, baseToken,quoteToken,lpFeeRate,mtFeeRate,i,k);
if(baseInAmount > 0) if(baseInAmount > 0)
IDODOV2(smartApprove).claimTokens(baseToken, msg.sender, newVendingMachine, baseInAmount); IDODOV2(smartApprove).claimTokens(baseToken, msg.sender, newVendingMachine, baseInAmount);
if(quoteInAmount > 0) if(quoteInAmount > 0)
@@ -156,12 +154,21 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 {
uint256 k, uint256 k,
uint256 deadline uint256 deadline
) external virtual override payable judgeExpired(deadline) returns (address newPrivatePool) { ) external virtual override payable judgeExpired(deadline) returns (address newPrivatePool) {
newPrivatePool = IDODOV2(dppFactory).createDODOPrivatePool(baseToken, quoteToken, lpFeeRate, mtFeeRate, i, k); newPrivatePool = IDODOV2(dppFactory).createDODOPrivatePool();
if(baseInAmount > 0) if(baseInAmount > 0)
IDODOV2(smartApprove).claimTokens(baseToken, msg.sender, newPrivatePool, baseInAmount); IDODOV2(smartApprove).claimTokens(baseToken, msg.sender, newPrivatePool, baseInAmount);
if(quoteInAmount > 0) if(quoteInAmount > 0)
IDODOV2(smartApprove).claimTokens(quoteToken, msg.sender, newPrivatePool, quoteInAmount); IDODOV2(smartApprove).claimTokens(quoteToken, msg.sender, newPrivatePool, quoteInAmount);
IDODOV2(newPrivatePool).initTargetAndReserve(); IDODOV2(dppFactory).initDODOPrivatePool(
newPrivatePool,
msg.sender,
baseToken,
quoteToken,
lpFeeRate,
mtFeeRate,
k,
i
);
} }
//TODO:ETH //TODO:ETH

View File

@@ -12,17 +12,22 @@ import {IERC20} from "../intf/IERC20.sol";
import {UniversalERC20} from "../lib/UniversalERC20.sol"; import {UniversalERC20} from "../lib/UniversalERC20.sol";
import {SafeMath} from "../lib/SafeMath.sol"; import {SafeMath} from "../lib/SafeMath.sol";
import {IDODOSellHelper} from "../intf/IDODOSellHelper.sol"; import {IDODOSellHelper} from "../intf/IDODOSellHelper.sol";
import {ISmartApprove} from "../intf/ISmartApprove.sol";
import {IDODO} from "../intf/IDODO.sol"; import {IDODO} from "../intf/IDODO.sol";
import {IWETH} from "../intf/IWETH.sol"; import {IWETH} from "../intf/IWETH.sol";
interface ISmartApprove {
function claimTokens(IERC20 token,address who,address dest,uint256 amount) external;
function getSmartSwap() external view returns (address);
}
contract SmartSwap is Ownable { contract SmartSwap is Ownable {
using SafeMath for uint256; using SafeMath for uint256;
using UniversalERC20 for IERC20; using UniversalERC20 for IERC20;
address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; IERC20 constant ETH_ADDRESS = IERC20(0x000000000000000000000000000000000000000E);
address public smartApprove; ISmartApprove public smartApprove;
address public dodoSellHelper; IDODOSellHelper public dodoSellHelper;
address payable public _WETH_; address payable public _WETH_;
@@ -32,8 +37,8 @@ contract SmartSwap is Ownable {
} }
event OrderHistory( event OrderHistory(
address indexed fromToken, IERC20 indexed fromToken,
address indexed toToken, IERC20 indexed toToken,
address indexed sender, address indexed sender,
uint256 fromAmount, uint256 fromAmount,
uint256 returnAmount, uint256 returnAmount,
@@ -45,8 +50,8 @@ contract SmartSwap is Ownable {
address _dodoSellHelper, address _dodoSellHelper,
address payable _weth address payable _weth
) public { ) public {
smartApprove = _smartApprove; smartApprove = ISmartApprove(_smartApprove);
dodoSellHelper = _dodoSellHelper; dodoSellHelper = IDODOSellHelper(_dodoSellHelper);
_WETH_ = _weth; _WETH_ = _weth;
} }
@@ -55,8 +60,8 @@ contract SmartSwap is Ownable {
receive() external payable {} receive() external payable {}
function dodoSwap( function dodoSwap(
address fromToken, IERC20 fromToken,
address toToken, IERC20 toToken,
uint256 fromTokenAmount, uint256 fromTokenAmount,
uint256 minReturnAmount, uint256 minReturnAmount,
address[] memory dodoPairs, address[] memory dodoPairs,
@@ -67,7 +72,7 @@ contract SmartSwap is Ownable {
require(dodoPairs.length > 0, "DODO SmartSwap: pairs should exists."); require(dodoPairs.length > 0, "DODO SmartSwap: pairs should exists.");
if (fromToken != ETH_ADDRESS) { if (fromToken != ETH_ADDRESS) {
ISmartApprove(smartApprove).claimTokens(fromToken, msg.sender, address(this),fromTokenAmount); smartApprove.claimTokens(fromToken, msg.sender, address(this),fromTokenAmount);
} else { } else {
require(msg.value == fromTokenAmount, "DODO SmartSwap: ETH_AMOUNT_NOT_MATCH"); require(msg.value == fromTokenAmount, "DODO SmartSwap: ETH_AMOUNT_NOT_MATCH");
IWETH(_WETH_).deposit{value: fromTokenAmount}(); IWETH(_WETH_).deposit{value: fromTokenAmount}();
@@ -84,33 +89,32 @@ contract SmartSwap is Ownable {
address curDodoQuote = IDODO(curDodoPair)._QUOTE_TOKEN_(); address curDodoQuote = IDODO(curDodoPair)._QUOTE_TOKEN_();
uint256 curAmountIn = IERC20(curDodoQuote).balanceOf(address(this)); uint256 curAmountIn = IERC20(curDodoQuote).balanceOf(address(this));
IERC20(curDodoQuote).universalApprove(curDodoPair, curAmountIn); IERC20(curDodoQuote).universalApprove(curDodoPair, curAmountIn);
uint256 canBuyBaseAmount = IDODOSellHelper(dodoSellHelper).querySellQuoteToken( uint256 canBuyBaseAmount = dodoSellHelper.querySellQuoteToken(
curDodoPair, curDodoPair,
curAmountIn curAmountIn
); );
IDODO(curDodoPair).buyBaseToken(canBuyBaseAmount, curAmountIn, ""); IDODO(curDodoPair).buyBaseToken(canBuyBaseAmount, curAmountIn, "");
} }
} }
IERC20(fromToken).universalTransfer(msg.sender, IERC20(fromToken).universalBalanceOf(address(this))); fromToken.universalTransfer(msg.sender, fromToken.universalBalanceOf(address(this)));
if (toToken == ETH_ADDRESS) { if (toToken == ETH_ADDRESS) {
uint256 wethAmount = IWETH(_WETH_).balanceOf(address(this)); uint256 wethAmount = IWETH(_WETH_).balanceOf(address(this));
IWETH(_WETH_).withdraw(wethAmount); IWETH(_WETH_).withdraw(wethAmount);
} }
returnAmount = IERC20(toToken).universalBalanceOf(address(this)); returnAmount = toToken.universalBalanceOf(address(this));
require(returnAmount >= minReturnAmount, "DODO SmartSwap: Return amount is not enough"); require(returnAmount >= minReturnAmount, "DODO SmartSwap: Return amount is not enough");
IERC20(toToken).universalTransfer(msg.sender, returnAmount); 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( function externalSwap(
address fromToken, IERC20 fromToken,
address toToken, IERC20 toToken,
address approveTarget, address approveTarget,
address to, address to,
uint256 gasSwap,
uint256 fromTokenAmount, uint256 fromTokenAmount,
uint256 minReturnAmount, uint256 minReturnAmount,
bytes memory callDataConcat, bytes memory callDataConcat,
@@ -120,21 +124,21 @@ contract SmartSwap is Ownable {
require(minReturnAmount > 0, "DODO SmartSwap: Min return should be bigger then 0."); require(minReturnAmount > 0, "DODO SmartSwap: Min return should be bigger then 0.");
if (fromToken != ETH_ADDRESS) { if (fromToken != ETH_ADDRESS) {
ISmartApprove(smartApprove).claimTokens(fromToken, msg.sender, address(this), fromTokenAmount); smartApprove.claimTokens(fromToken, msg.sender, address(this), fromTokenAmount);
IERC20(fromToken).universalApprove(approveTarget, fromTokenAmount); fromToken.universalApprove(approveTarget, fromTokenAmount);
} }
(bool success, ) = to.call{value: fromToken == ETH_ADDRESS ? msg.value : 0, gas: gasSwap}( (bool success, ) = to.call{value: fromToken == ETH_ADDRESS ? msg.value : 0}(
callDataConcat callDataConcat
); );
require(success, "DODO SmartSwap: Contract Swap execution Failed"); require(success, "DODO SmartSwap: Contract Swap execution Failed");
IERC20(fromToken).universalTransfer(msg.sender, IERC20(fromToken).universalBalanceOf(address(this))); fromToken.universalTransfer(msg.sender, fromToken.universalBalanceOf(address(this)));
returnAmount = IERC20(toToken).universalBalanceOf(address(this)); returnAmount = toToken.universalBalanceOf(address(this));
require(returnAmount >= minReturnAmount, "DODO SmartSwap: Return amount is not enough"); require(returnAmount >= minReturnAmount, "DODO SmartSwap: Return amount is not enough");
IERC20(toToken).universalTransfer(msg.sender, returnAmount); 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);
} }
} }

View File

@@ -27,6 +27,7 @@ interface IDODOV2 {
//========== DODOVendingMachine ======== //========== DODOVendingMachine ========
function createDODOVendingMachine( function createDODOVendingMachine(
address from,
address baseToken, address baseToken,
address quoteToken, address quoteToken,
uint256 lpFeeRate, uint256 lpFeeRate,
@@ -41,16 +42,18 @@ interface IDODOV2 {
//========== DODOPrivatePool =========== //========== DODOPrivatePool ===========
function initTargetAndReserve() external; function createDODOPrivatePool() external returns (address newPrivatePool);
function createDODOPrivatePool( function initDODOPrivatePool(
address dppAddress,
address from,
address baseToken, address baseToken,
address quoteToken, address quoteToken,
uint256 lpFeeRate, uint256 lpFeeRate,
uint256 mtFeeRate, uint256 mtFeeRate,
uint256 i, uint256 k,
uint256 k uint256 i
) external returns (address newPrivatePool); ) external;
function reset( function reset(
uint256 newLpFeeRate, uint256 newLpFeeRate,

View File

@@ -16,7 +16,7 @@ library UniversalERC20 {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000); IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000);
IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); IERC20 private constant ETH_ADDRESS = IERC20(0x000000000000000000000000000000000000000E);
function isETH(IERC20 token) internal pure returns (bool) { function isETH(IERC20 token) internal pure returns (bool) {
return (token == ZERO_ADDRESS || token == ETH_ADDRESS); return (token == ZERO_ADDRESS || token == ETH_ADDRESS);

View File

@@ -1,5 +1,5 @@
const Migrations = artifacts.require("Migrations"); const Migrations = artifacts.require("Migrations");
module.exports = function (deployer) { module.exports = function (deployer) {
deployer.deploy(Migrations); // deployer.deploy(Migrations);
}; };

View File

@@ -21,7 +21,7 @@ module.exports = async (deployer, network, accounts) => {
DODOSellHelperAddress = "0xbdEae617F2616b45DCB69B287D52940a76035Fe3"; DODOSellHelperAddress = "0xbdEae617F2616b45DCB69B287D52940a76035Fe3";
DODOZooAddress = "0x92230e929a2226b29ed3441ae5524886347c60c8"; DODOZooAddress = "0x92230e929a2226b29ed3441ae5524886347c60c8";
WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b"; WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b";
SmartApproveAddress = ""; SmartApproveAddress = "0x5627b7DEb3055e1e899003FDca0716b32C382084";
} else if (network == "live") { } else if (network == "live") {
DODOSellHelperAddress = "0x533da777aedce766ceae696bf90f8541a4ba80eb"; DODOSellHelperAddress = "0x533da777aedce766ceae696bf90f8541a4ba80eb";
DODOZooAddress = "0x3a97247df274a17c59a3bd12735ea3fcdfb49950"; DODOZooAddress = "0x3a97247df274a17c59a3bd12735ea3fcdfb49950";
@@ -53,9 +53,9 @@ module.exports = async (deployer, network, accounts) => {
); );
logger.log("SmartSwap Address: ", SmartSwap.address); logger.log("SmartSwap Address: ", SmartSwap.address);
const SmartApproveInstance = await SmartApprove.at(SmartApproveAddress); // const SmartApproveInstance = await SmartApprove.at(SmartApproveAddress);
var tx = await SmartApproveInstance.setSmartSwap(SmartSwap.address); // var tx = await SmartApproveInstance.setSmartSwap(SmartSwap.address);
logger.log("SmartApprovce setSmartSwap tx: ", tx.tx); // logger.log("SmartApprovce setSmartSwap tx: ", tx.tx);
} }
if (DEPLOY_KOVAN_TOKEN) { if (DEPLOY_KOVAN_TOKEN) {

View File

@@ -1,2 +0,0 @@
truffle compile --all
truffle test ./test/Route/Route.test.ts

View File

@@ -0,0 +1,161 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
// import * as assert from 'assert';
import { decimalStr, mweiStr} from '../utils/Converter';
import { logGas } from '../utils/Log';
import { ProxyContext, getProxyContext } from '../utils/ProxyContext';
import { assert } from 'chai';
let lp: string;
let project: string;
let trader: string;
let config = {
lpFeeRate: decimalStr("0.002"),
mtFeeRate: decimalStr("0.001"),
k: decimalStr("0.1"),
i: decimalStr("100"),
};
async function init(ctx: ProxyContext): Promise<void> {
lp = ctx.SpareAccounts[0];
project = ctx.SpareAccounts[1];
trader = ctx.SpareAccounts[2];
await ctx.approveProxy(lp);
await ctx.approveProxy(project);
await ctx.approveProxy(trader);
await ctx.mintTestToken(lp, ctx.DODO, decimalStr("100000"));
await ctx.mintTestToken(project, ctx.DODO, decimalStr("100000"));
await ctx.mintTestToken(trader, ctx.DODO, decimalStr("100000"));
await ctx.mintTestToken(lp, ctx.USDT, mweiStr("100000"));
await ctx.mintTestToken(project, ctx.USDT, mweiStr("100000"));
// await ctx.WETH.methods.deposit().send(ctx.sendParam(lp, '80'));
// await ctx.WETH.methods.deposit().send(ctx.sendParam(project, '80'));
}
async function initCreateDPP(ctx: ProxyContext, token0: any, token1:any, token0Amount: string, token1Amount: string): Promise<void> {
let PROXY = ctx.DODOProxy;
await PROXY.methods.createDODOPrivatePool(
token0.options.address,
token1.options.address,
token0Amount,
token1Amount,
config.lpFeeRate,
config.mtFeeRate,
config.i,
config.k,
Math.floor(new Date().getTime()/1000 + 60 * 10)
).send(ctx.sendParam(project));
}
describe("DODOProxyV2.0", () => {
let snapshotId: string;
let ctx: ProxyContext;
before(async () => {
ctx = await getProxyContext();
await init(ctx);
// await initCreateDPP(ctx,ctx.DODO,ctx.USDT,decimalStr("10000"),decimalStr("10000"));
// await initCreateDPP(ctx,ctx.WETH,ctx.USDT,decimalStr("50"),decimalStr("10000"));
});
beforeEach(async () => {
snapshotId = await ctx.EVM.snapshot();
});
afterEach(async () => {
await ctx.EVM.reset(snapshotId);
});
describe("DODOProxy", () => {
/**
* 1. 创建空池子
* 2. 创建ERC20 DPP
* 3. 创建ETH && ERC20 Token
*/
it("createDPP - empty", async () => {
var baseToken = ctx.DODO.options.address;
var quoteToken = ctx.USDT.options.address;
await ctx.DODOProxy.methods.createDODOPrivatePool(
baseToken,
quoteToken,
decimalStr("0"),
decimalStr("0"),
config.lpFeeRate,
config.mtFeeRate,
config.i,
config.k,
Math.floor(new Date().getTime()/1000 + 60 * 10)
).send(ctx.sendParam(project));
var addrs = await ctx.DPPFactory.methods.getPrivatePool(baseToken,quoteToken).call();
var dppInfo = await ctx.DPPFactory.methods._DPP_INFO_(addrs[0]).call();
console.log("dppInfo:",dppInfo);
assert.equal(
dppInfo[0],
project
);
});
it("resetDPP", async () => {
//需要存钱
//需要退钱
});
/**
* trade
*/
it("trade-sellQuote-R=1", async () => {
//R变号与不变号
});
it("trade-sellQuote-R>1", async () => {
//R变号与不变号
});
it("trade-sellQuote-R<1", async () => {
//R变号与不变号
});
it("trade-sellBase-R=1", async () => {
//R变号与不变号
});
it("trade-sellBase-R>1", async () => {
//R变号与不变号
});
it("trade-sellBase-R<1", async () => {
//R变号与不变号
});
it("retrieve", async () => {
//eth允许
//控制无法提取base && quote
});
/**
* 直接底层dpp操作测试
*/
});
});

View File

@@ -38,15 +38,13 @@ async function init(ctx: ProxyContext): Promise<void> {
await ctx.mintTestToken(lp, ctx.USDT, mweiStr("100000")); await ctx.mintTestToken(lp, ctx.USDT, mweiStr("100000"));
await ctx.mintTestToken(project, ctx.USDT, mweiStr("100000")); await ctx.mintTestToken(project, ctx.USDT, mweiStr("100000"));
await ctx.mintTestToken(lp, ctx.WETH, decimalStr("70")); // await ctx.WETH.methods.deposit().send(ctx.sendParam(lp, '80'));
await ctx.mintTestToken(project, ctx.WETH, decimalStr("70")); // await ctx.WETH.methods.deposit().send(ctx.sendParam(project, '80'));
} }
async function initCreateDVM(ctx: ProxyContext, token0: any, token1:any, token0Amount: string, token1Amount: string): Promise<void> { async function initCreateDVM(ctx: ProxyContext, token0: any, token1:any, token0Amount: string, token1Amount: string): Promise<void> {
let PROXY = ctx.DODOProxy; let PROXY = ctx.DODOProxy;
let dvmAddress; await PROXY.methods.createDODOVendingMachine(
let shares;
(dvmAddress, shares) = await PROXY.methods.createDODOVendingMachine(
token0.options.address, token0.options.address,
token1.options.address, token1.options.address,
token0Amount, token0Amount,
@@ -57,26 +55,8 @@ async function initCreateDVM(ctx: ProxyContext, token0: any, token1:any, token0A
config.k, config.k,
Math.floor(new Date().getTime()/1000 + 60 * 10); Math.floor(new Date().getTime()/1000 + 60 * 10);
).send(ctx.sendParam(project)); ).send(ctx.sendParam(project));
console.log("create dvmAddress: ", dvmAddress);
console.log("create shares: ", shares);
} }
async function initCreateDPP(ctx: ProxyContext, token0: any, token1:any, token0Amount: string, token1Amount: string): Promise<void> {
let PROXY = ctx.DODOProxy;
let dppAddress = await PROXY.methods.createDODOPrivatePool(
token0.options.address,
token1.options.address,
token0Amount,
token1Amount,
config.lpFeeRate,
config.mtFeeRate,
config.i,
config.k,
Math.floor(new Date().getTime()/1000 + 60 * 10);
).send(ctx.sendParam(project));
console.log("create dppAddress: ", dppAddress);
console.log("create shares: ", shares);
}
describe("DODOProxyV2.0", () => { describe("DODOProxyV2.0", () => {
let snapshotId: string; let snapshotId: string;
@@ -85,10 +65,8 @@ describe("DODOProxyV2.0", () => {
before(async () => { before(async () => {
ctx = await getProxyContext(); ctx = await getProxyContext();
await init(ctx); await init(ctx);
await initCreateDVM(ctx,ctx.DODO,ctx.USDT,decimalStr("10000"),decimalStr("10000")); // await initCreateDVM(ctx,ctx.DODO,ctx.USDT,decimalStr("10000"),decimalStr("10000"));
await initCreateDVM(ctx,ctx.WETH,ctx.USDT,decimalStr("50"),decimalStr("10000")); // await initCreateDVM(ctx,ctx.WETH,ctx.USDT,decimalStr("50"),decimalStr("10000"));
await initCreateDPP(ctx,ctx.DODO,ctx.USDT,decimalStr("10000"),decimalStr("10000"));
await initCreateDPP(ctx,ctx.WETH,ctx.USDT,decimalStr("50"),decimalStr("10000"));
}); });
beforeEach(async () => { beforeEach(async () => {
@@ -126,24 +104,6 @@ describe("DODOProxyV2.0", () => {
}); });
/**
* 1.
* 2. ERC20 DPP
* 3. ETH && ERC20 Token
*/
it("createDPP", async () => {
});
/**
*
*/
it("resetDPP", async () => {
});
/** /**
* *
*/ */
@@ -151,5 +111,11 @@ describe("DODOProxyV2.0", () => {
}); });
/**
* dvm操作测试
*/
}); });
}); });

View File

@@ -90,7 +90,7 @@ async function calcRoute(ctx: DODOContext, fromTokenAmount: string, slippage: nu
let curPair = pairs[i] let curPair = pairs[i]
dodoPairs.push(curPair.pair) dodoPairs.push(curPair.pair)
let curContact = pairs[i].pairContract let curContact = pairs[i].pairContract
if (routes[i].address == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') { if (routes[i].address == '0x000000000000000000000000000000000000000E') {
directions[i] = 0; directions[i] = 0;
swapAmount = await curContact.methods.querySellBaseToken(swapAmount).call(); swapAmount = await curContact.methods.querySellBaseToken(swapAmount).call();
console.log(i + "-swapAmount:", swapAmount); console.log(i + "-swapAmount:", swapAmount);
@@ -273,7 +273,7 @@ describe("Trader", () => {
console.log("weth contract Before:" + fromWei(b_w_eth, 'ether')) console.log("weth contract Before:" + fromWei(b_w_eth, 'ether'))
//set route path //set route path
var routes = [{ var routes = [{
address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", address: "0x000000000000000000000000000000000000000E",
decimals: 18 decimals: 18
}, { }, {
address: ctx.USDC.options.address, address: ctx.USDC.options.address,
@@ -311,7 +311,7 @@ describe("Trader", () => {
console.log("weth contract Before:" + fromWei(b_w_eth, 'ether')) console.log("weth contract Before:" + fromWei(b_w_eth, 'ether'))
//set route path //set route path
var routes = [{ var routes = [{
address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", address: "0x000000000000000000000000000000000000000E",
decimals: 18 decimals: 18
}, { }, {
address: ctx.USDC.options.address, address: ctx.USDC.options.address,
@@ -368,7 +368,7 @@ describe("Trader", () => {
address: ctx.USDC.options.address, address: ctx.USDC.options.address,
decimals: 6 decimals: 6
}, { }, {
address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", address: "0x000000000000000000000000000000000000000E",
decimals: 18 decimals: 18
}]; }];

View File

@@ -21,7 +21,7 @@ export const DODO_LP_TOKEN_CONTRACT_NAME = "DODOLpToken"
export const DODO_ZOO_CONTRACT_NAME = "DOOZoo" export const DODO_ZOO_CONTRACT_NAME = "DOOZoo"
export const DODO_WILD_CONTRACT_NAME = "DOOWild" export const DODO_WILD_CONTRACT_NAME = "DOOWild"
export const DODO_ETH_PROXY_CONTRACT_NAME = "DODOEthProxy" export const DODO_ETH_PROXY_CONTRACT_NAME = "DODOEthProxy"
export const WETH_CONTRACT_NAME = "WETH" export const WETH_CONTRACT_NAME = "WETH9"
export const UNISWAP_CONTRACT_NAME = "Uniswap" export const UNISWAP_CONTRACT_NAME = "Uniswap"
export const UNISWAP_ARBITRAGEUR_CONTRACT_NAME = "UniswapArbitrageur" export const UNISWAP_ARBITRAGEUR_CONTRACT_NAME = "UniswapArbitrageur"
export const DODO_TOKEN_CONTRACT_NAME = "DODOToken" export const DODO_TOKEN_CONTRACT_NAME = "DODOToken"

View File

@@ -12,4 +12,4 @@ export function gweiStr(gwei: string): string {
export function mweiStr(gwei: string): string { export function mweiStr(gwei: string): string {
return new BigNumber(gwei).multipliedBy(10 ** 6).toFixed(0, BigNumber.ROUND_DOWN) return new BigNumber(gwei).multipliedBy(10 ** 6).toFixed(0, BigNumber.ROUND_DOWN)
}s }

View File

@@ -43,6 +43,11 @@ export class ProxyContext {
this.EVM = new EVM(); this.EVM = new EVM();
this.Web3 = getDefaultWeb3(); this.Web3 = getDefaultWeb3();
const allAccounts = await this.Web3.eth.getAccounts();
this.Deployer = allAccounts[0];
this.Maintainer = allAccounts[1];
this.SpareAccounts = allAccounts.slice(2, 10);
var WETH = await contracts.newContract( var WETH = await contracts.newContract(
contracts.WETH_CONTRACT_NAME contracts.WETH_CONTRACT_NAME
); );
@@ -57,6 +62,8 @@ export class ProxyContext {
var feeRateModelTemplate = await contracts.newContract(contracts.FEE_RATE_MODEL_NAME) var feeRateModelTemplate = await contracts.newContract(contracts.FEE_RATE_MODEL_NAME)
var permissionManagerTemplate = await contracts.newContract(contracts.PERMISSION_MANAGER_NAME) var permissionManagerTemplate = await contracts.newContract(contracts.PERMISSION_MANAGER_NAME)
var vauleSource = await contracts.newContract(contracts.EXTERNAL_VALUE_NAME) var vauleSource = await contracts.newContract(contracts.EXTERNAL_VALUE_NAME)
var defaultGasSource = await contracts.newContract(contracts.EXTERNAL_VALUE_NAME)
await defaultGasSource.methods.init(this.Deployer,decimalStr("1000000"));
this.DVMFactory = await contracts.newContract(contracts.DVM_FACTORY_NAME, this.DVMFactory = await contracts.newContract(contracts.DVM_FACTORY_NAME,
[ [
@@ -65,10 +72,14 @@ export class ProxyContext {
dvmAdminTemplate.options.address, dvmAdminTemplate.options.address,
feeRateModelTemplate.options.address, feeRateModelTemplate.options.address,
permissionManagerTemplate.options.address, permissionManagerTemplate.options.address,
vauleSource.options.address defaultGasSource.options.address
] ]
) )
this.SmartApprove = await contracts.newContract(
contracts.SMART_APPROVE
);
this.DPPFactory = await contracts.newContract(contracts.DPP_FACTORY_NAME, this.DPPFactory = await contracts.newContract(contracts.DPP_FACTORY_NAME,
[ [
cloneFactory.options.address, cloneFactory.options.address,
@@ -76,28 +87,28 @@ export class ProxyContext {
dppAdminTemplate.options.address, dppAdminTemplate.options.address,
feeRateModelTemplate.options.address, feeRateModelTemplate.options.address,
permissionManagerTemplate.options.address, permissionManagerTemplate.options.address,
vauleSource.options.address vauleSource.options.address,
defaultGasSource.options.address,
this.SmartApprove.options.address
] ]
) )
this.SmartApprove = await contracts.newContract(
contracts.SMART_APPROVE
);
var dodoSellHelper = await contracts.newContract( var dodoSellHelper = await contracts.newContract(
contracts.DODO_SELL_HELPER contracts.DODO_SELL_HELPER
); );
this.DODOProxy = await contracts.newContract(contracts.DODO_PROXY_NAME, this.DODOProxy = await contracts.newContract(contracts.DODO_PROXY_NAME,
[ [
dvmFactory.options.address, this.DVMFactory.options.address,
dppFactory.options.address, this.DPPFactory.options.address,
WETH.options.address, WETH.options.address,
smartApprove.options.address, this.SmartApprove.options.address,
dodoSellHelper.options.address dodoSellHelper.options.address
] ]
); );
await this.SmartApprove.methods.setSmartSwap(this.DODOProxy.options.address).send(this.sendParam(this.Deployer));
this.DODO = await contracts.newContract( this.DODO = await contracts.newContract(
contracts.MINTABLE_ERC20_CONTRACT_NAME, contracts.MINTABLE_ERC20_CONTRACT_NAME,
["DODO Token", "DODO", 18] ["DODO Token", "DODO", 18]
@@ -110,11 +121,6 @@ export class ProxyContext {
contracts.WETH_CONTRACT_NAME contracts.WETH_CONTRACT_NAME
); );
const allAccounts = await this.Web3.eth.getAccounts();
this.Deployer = allAccounts[0];
this.Maintainer = allAccounts[1];
this.SpareAccounts = allAccounts.slice(2, 10);
console.log(log.blueText("[Init DVM context]")); console.log(log.blueText("[Init DVM context]"));
} }

View File

@@ -68,7 +68,7 @@ module.exports = {
return new HDWalletProvider(privKey, "https://mainnet.infura.io/v3/" + infuraId); return new HDWalletProvider(privKey, "https://mainnet.infura.io/v3/" + infuraId);
}, },
gas: 3000000, gas: 3000000,
gasPrice: 60000000000, gasPrice: 120000000000,
network_id: 1, network_id: 1,
skipDryRun: true skipDryRun: true
}, },

19
truffle-test.sh Normal file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
truffle compile --all
if [ "$1"x = "proxy-dpp"x ]
then
truffle test ./test/Proxy/proxy.dpp.test.ts
fi
if [ "$1"x = "proxy-dvm"x ]
then
truffle test ./test/Proxy/proxy.dvm.test.ts
fi
if [ "$1"x = "route"x ]
then
truffle test ./test/Route/route.test.ts
fi