Merge branch 'feature/V2' of github.com:DODOEX/contractV2 into feature/V2
This commit is contained in:
@@ -74,24 +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) {
|
||||
// poolI round up
|
||||
} 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.divFloor(poolQuote, baseDepth));
|
||||
_poolI = avgPrice.mul(ratio).mul(ratio).divCeil(DecimalMath.ONE2);
|
||||
} else if (poolQuote > baseDepth) {
|
||||
// poolI round down
|
||||
} 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.divCeil(baseDepth, poolQuote));
|
||||
_poolI = DecimalMath.reciprocalFloor(avgPrice).mul(ratio).mul(ratio).div(
|
||||
DecimalMath.ONE2
|
||||
);
|
||||
_poolI = ratio.mul(ratio).div(avgPrice).div(DecimalMath.ONE2);
|
||||
}
|
||||
_POOL_ = IUnownedDVMFactory(_POOL_FACTORY_).createDODOVendingMachine(
|
||||
address(this),
|
||||
@@ -113,7 +111,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));
|
||||
|
||||
@@ -95,22 +95,26 @@ contract DPPAdmin is InitializableOwnable {
|
||||
uint256 newI,
|
||||
uint256 newK,
|
||||
uint256 baseOutAmount,
|
||||
uint256 quoteOutAmount
|
||||
) external notFreezed {
|
||||
uint256 quoteOutAmount,
|
||||
uint256 minBaseReserve,
|
||||
uint256 minQuoteReserve
|
||||
) external notFreezed returns (bool) {
|
||||
require(
|
||||
msg.sender == _OWNER_ ||
|
||||
(msg.sender == IDODOApprove(_DODO_APPROVE_).getDODOProxy() &&
|
||||
operator == _OPERATOR_),
|
||||
"RESET FORBIDDEN!"
|
||||
);
|
||||
IDPP(_DPP_).reset(
|
||||
return IDPP(_DPP_).reset(
|
||||
msg.sender,
|
||||
newLpFeeRate,
|
||||
newMtFeeRate,
|
||||
newI,
|
||||
newK,
|
||||
baseOutAmount,
|
||||
quoteOutAmount
|
||||
quoteOutAmount,
|
||||
minBaseReserve,
|
||||
minQuoteReserve
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,15 @@ contract DPPTrader is DPPVault {
|
||||
address trader
|
||||
);
|
||||
|
||||
event DODOFlashLoan(
|
||||
address borrower,
|
||||
address assetTo,
|
||||
uint256 baseAmount,
|
||||
uint256 quoteAmount
|
||||
);
|
||||
|
||||
event RChange(PMMPricing.RState newRState);
|
||||
|
||||
// ============ Modifiers ============
|
||||
|
||||
modifier isBuyAllow(address trader) {
|
||||
@@ -70,6 +79,7 @@ contract DPPTrader is DPPVault {
|
||||
if (_RState_ != newRState) {
|
||||
_RState_ = newRState;
|
||||
_BASE_TARGET_ = newBaseTarget;
|
||||
emit RChange(newRState);
|
||||
}
|
||||
|
||||
emit DODOSwap(
|
||||
@@ -77,7 +87,7 @@ contract DPPTrader is DPPVault {
|
||||
address(_QUOTE_TOKEN_),
|
||||
baseInput,
|
||||
receiveQuoteAmount,
|
||||
tx.origin
|
||||
msg.sender
|
||||
);
|
||||
}
|
||||
|
||||
@@ -106,6 +116,7 @@ contract DPPTrader is DPPVault {
|
||||
if (_RState_ != newRState) {
|
||||
_RState_ = newRState;
|
||||
_QUOTE_TARGET_ = newQuoteTarget;
|
||||
emit RChange(newRState);
|
||||
}
|
||||
|
||||
emit DODOSwap(
|
||||
@@ -113,7 +124,7 @@ contract DPPTrader is DPPVault {
|
||||
address(_BASE_TOKEN_),
|
||||
quoteInput,
|
||||
receiveBaseAmount,
|
||||
tx.origin
|
||||
msg.sender
|
||||
);
|
||||
}
|
||||
|
||||
@@ -154,13 +165,14 @@ contract DPPTrader is DPPVault {
|
||||
if (_RState_ != newRState) {
|
||||
_RState_ = newRState;
|
||||
_QUOTE_TARGET_ = newQuoteTarget;
|
||||
emit RChange(newRState);
|
||||
}
|
||||
emit DODOSwap(
|
||||
address(_QUOTE_TOKEN_),
|
||||
address(_BASE_TOKEN_),
|
||||
quoteInput,
|
||||
receiveBaseAmount,
|
||||
tx.origin
|
||||
msg.sender
|
||||
);
|
||||
}
|
||||
|
||||
@@ -180,17 +192,20 @@ contract DPPTrader is DPPVault {
|
||||
if (_RState_ != newRState) {
|
||||
_RState_ = newRState;
|
||||
_BASE_TARGET_ = newBaseTarget;
|
||||
emit RChange(newRState);
|
||||
}
|
||||
emit DODOSwap(
|
||||
address(_BASE_TOKEN_),
|
||||
address(_QUOTE_TOKEN_),
|
||||
baseInput,
|
||||
receiveQuoteAmount,
|
||||
tx.origin
|
||||
msg.sender
|
||||
);
|
||||
}
|
||||
|
||||
_sync();
|
||||
|
||||
emit DODOFlashLoan(msg.sender, assetTo, baseAmount, quoteAmount);
|
||||
}
|
||||
|
||||
// ============ Query Functions ============
|
||||
|
||||
@@ -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) {
|
||||
@@ -65,8 +78,11 @@ contract DPPVault is DPPStorage {
|
||||
uint256 newI,
|
||||
uint256 newK,
|
||||
uint256 baseOutAmount,
|
||||
uint256 quoteOutAmount
|
||||
) public preventReentrant onlyOwner {
|
||||
uint256 quoteOutAmount,
|
||||
uint256 minBaseReserve,
|
||||
uint256 minQuoteReserve
|
||||
) public preventReentrant onlyOwner returns (bool) {
|
||||
require(_BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve, "Reserve amount is not enough");
|
||||
_LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate);
|
||||
_MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate);
|
||||
_I_.set(newI);
|
||||
@@ -75,7 +91,8 @@ contract DPPVault is DPPStorage {
|
||||
_transferQuoteOut(assetTo, quoteOutAmount);
|
||||
_resetTargetAndReserve();
|
||||
_checkIK();
|
||||
emit Reset();
|
||||
emit Reset(newLpFeeRate, newMtFeeRate);
|
||||
return true;
|
||||
}
|
||||
|
||||
function _setRState() internal {
|
||||
|
||||
@@ -60,6 +60,8 @@ interface IDPP {
|
||||
uint256 newI,
|
||||
uint256 newK,
|
||||
uint256 baseOutAmount,
|
||||
uint256 quoteOutAmount
|
||||
) external;
|
||||
uint256 quoteOutAmount,
|
||||
uint256 minBaseReserve,
|
||||
uint256 minQuoteReserve
|
||||
) external returns (bool);
|
||||
}
|
||||
|
||||
@@ -15,12 +15,6 @@ import {IExternalValue} from "../../lib/ExternalValue.sol";
|
||||
contract DVMAdmin is InitializableOwnable {
|
||||
address public _DVM_;
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
event SetLpFeeRate(uint256 newLpFeeRate);
|
||||
|
||||
event SetMtFeeRate(uint256 newMtFeeRate);
|
||||
|
||||
function init(address owner, address dvm) external {
|
||||
initOwner(owner);
|
||||
_DVM_ = dvm;
|
||||
@@ -31,8 +25,7 @@ contract DVMAdmin is InitializableOwnable {
|
||||
// }
|
||||
|
||||
function setLpFeeRateValue(uint256 newLpFeeRate) external onlyOwner {
|
||||
IExternalValue(IDVM(_DVM_)._LP_FEE_RATE_MODEL_()).set(newLpFeeRate);
|
||||
emit SetLpFeeRate(newLpFeeRate);
|
||||
IDVM(_DVM_).setLpFeeRateValue(newLpFeeRate);
|
||||
}
|
||||
|
||||
// function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner {
|
||||
@@ -40,8 +33,7 @@ contract DVMAdmin is InitializableOwnable {
|
||||
// }
|
||||
|
||||
function setMtFeeRateValue(uint256 newMtFeeRate) external onlyOwner {
|
||||
IExternalValue(IDVM(_DVM_)._MT_FEE_RATE_MODEL_()).set(newMtFeeRate);
|
||||
emit SetMtFeeRate(newMtFeeRate);
|
||||
IDVM(_DVM_).setMtFeeRateValue(newMtFeeRate);
|
||||
}
|
||||
|
||||
// function setTradePermissionManager(address newTradePermissionManager) external onlyOwner {
|
||||
|
||||
@@ -15,14 +15,9 @@ 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,
|
||||
uint256 decreaseShares,
|
||||
uint256 totalShares
|
||||
);
|
||||
event SellShares(address payer, address to, uint256 decreaseShares, uint256 totalShares);
|
||||
|
||||
// ============ Buy & Sell Shares ============
|
||||
|
||||
@@ -50,8 +45,8 @@ contract DVMFunding is DVMVault {
|
||||
// 在提币的时候向下取整。因此永远不会出现,balance为0但totalsupply不为0的情况
|
||||
// 但有可能出现,reserve>0但totalSupply=0的场景
|
||||
if (totalSupply == 0) {
|
||||
require(baseBalance >= 10**3); // 以免出现balance很大但shares很小的情况
|
||||
shares = baseBalance;
|
||||
require(baseBalance >= 10**3, "INSUFFICIENT_LIQUIDITY_MINED");
|
||||
shares = baseBalance; // 以免出现balance很大但shares很小的情况
|
||||
} else if (baseReserve > 0 && quoteReserve == 0) {
|
||||
// case 2. supply when quote reserve is 0
|
||||
shares = baseInput.mul(totalSupply).div(baseReserve);
|
||||
@@ -62,7 +57,6 @@ 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]);
|
||||
|
||||
@@ -80,6 +80,10 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
|
||||
|
||||
event SetSell(bool allow);
|
||||
|
||||
event SetLpFeeRate(uint256 newValue);
|
||||
|
||||
event SetMtFeeRate(uint256 newValue);
|
||||
|
||||
// ============ Setting Functions ============
|
||||
|
||||
function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner {
|
||||
@@ -92,6 +96,16 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
|
||||
_MT_FEE_RATE_MODEL_ = IFeeRateModel(newMtFeeRateModel);
|
||||
}
|
||||
|
||||
function setLpFeeRateValue(uint256 newLpFeeRate) external onlyOwner {
|
||||
_LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate);
|
||||
emit SetLpFeeRate(newLpFeeRate);
|
||||
}
|
||||
|
||||
function setMtFeeRateValue(uint256 newMtFeeRate) external onlyOwner {
|
||||
_MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate);
|
||||
emit SetMtFeeRate(newMtFeeRate);
|
||||
}
|
||||
|
||||
function setTradePermissionManager(address newTradePermissionManager) external onlyOwner {
|
||||
emit SetTradePermissionManager(address(_TRADE_PERMISSION_), newTradePermissionManager);
|
||||
_TRADE_PERMISSION_ = IPermissionManager(newTradePermissionManager);
|
||||
|
||||
@@ -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 ============
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -41,7 +41,11 @@ interface IDVM {
|
||||
//=========== admin ==========
|
||||
function setLpFeeRateModel(address newLpFeeRateModel) external;
|
||||
|
||||
function setLpFeeRateValue(uint256 newLpFeeRate) external;
|
||||
|
||||
function setMtFeeRateModel(address newMtFeeRateModel) external;
|
||||
|
||||
function setMtFeeRateValue(uint256 newMtFeeRate) external;
|
||||
|
||||
function setTradePermissionManager(address newTradePermissionManager) external;
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
pragma solidity 0.6.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {Ownable} from "../lib/Ownable.sol";
|
||||
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
|
||||
import {ICloneFactory} from "../lib/CloneFactory.sol";
|
||||
import {IFeeRateModel} from "../lib/FeeRateModel.sol";
|
||||
import {IExternalValue} from "../lib/ExternalValue.sol";
|
||||
@@ -16,7 +16,7 @@ import {IDPP} from "../DODOPrivatePool/intf/IDPP.sol";
|
||||
import {IDPPAdmin} from "../DODOPrivatePool/intf/IDPPAdmin.sol";
|
||||
import {IPermissionManager} from "../lib/PermissionManager.sol";
|
||||
|
||||
contract DPPFactory is Ownable {
|
||||
contract DPPFactory is InitializableOwnable {
|
||||
// ============ Templates ============
|
||||
|
||||
address public immutable _CLONE_FACTORY_;
|
||||
@@ -38,9 +38,9 @@ contract DPPFactory is Ownable {
|
||||
// ============ Events ============
|
||||
|
||||
event NewDPP(
|
||||
address indexed baseToken,
|
||||
address indexed quoteToken,
|
||||
address indexed creator,
|
||||
address baseToken,
|
||||
address quoteToken,
|
||||
address creator,
|
||||
address dpp
|
||||
);
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
pragma solidity 0.6.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {Ownable} from "../lib/Ownable.sol";
|
||||
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";
|
||||
@@ -27,7 +27,7 @@ interface IDVMFactory {
|
||||
) external returns (address newVendingMachine);
|
||||
}
|
||||
|
||||
contract DVMFactory is Ownable {
|
||||
contract DVMFactory is InitializableOwnable {
|
||||
// ============ Templates ============
|
||||
|
||||
address public immutable _CLONE_FACTORY_;
|
||||
@@ -47,9 +47,9 @@ contract DVMFactory is Ownable {
|
||||
// ============ Events ============
|
||||
|
||||
event NewDVM(
|
||||
address indexed baseToken,
|
||||
address indexed quoteToken,
|
||||
address indexed creator,
|
||||
address baseToken,
|
||||
address quoteToken,
|
||||
address creator,
|
||||
address dvm
|
||||
);
|
||||
|
||||
@@ -106,7 +106,7 @@ contract DVMFactory is Ownable {
|
||||
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) {
|
||||
|
||||
@@ -8,16 +8,11 @@
|
||||
pragma solidity 0.6.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {Ownable} from "../lib/Ownable.sol";
|
||||
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";
|
||||
|
||||
contract ERC20Factory is Ownable {
|
||||
contract ERC20Factory {
|
||||
// ============ Templates ============
|
||||
|
||||
address public immutable _CLONE_FACTORY_;
|
||||
@@ -26,7 +21,7 @@ contract ERC20Factory is Ownable {
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
event NewERC20(address indexed erc20, address indexed creator, bool isMintable);
|
||||
event NewERC20(address erc20, address creator, bool isMintable);
|
||||
|
||||
// ============ Functions ============
|
||||
|
||||
|
||||
@@ -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,10 +49,10 @@ contract UnownedDVMFactory {
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
event NewDVM(
|
||||
address indexed baseToken,
|
||||
address indexed quoteToken,
|
||||
address indexed creator,
|
||||
event NewUnOwnedDVM(
|
||||
address baseToken,
|
||||
address quoteToken,
|
||||
address creator,
|
||||
address dvm
|
||||
);
|
||||
|
||||
@@ -102,7 +102,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);
|
||||
}
|
||||
|
||||
function _createFeeRateModel(address owner, uint256 feeRate)
|
||||
@@ -110,7 +110,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 ============
|
||||
|
||||
@@ -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 ============
|
||||
@@ -257,44 +258,42 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
|
||||
function resetDODOPrivatePool(
|
||||
address dppAddress,
|
||||
uint256 newLpFeeRate,
|
||||
uint256 newMtFeeRate,
|
||||
uint256 newI,
|
||||
uint256 newK,
|
||||
uint256 baseInAmount,
|
||||
uint256 quoteInAmount,
|
||||
uint256 baseOutAmount,
|
||||
uint256 quoteOutAmount,
|
||||
uint256[] memory paramList, //0 - newLpFeeRate, 1 - newMtFeeRate, 2 - newI, 3 - newK
|
||||
uint256[] memory amountList, //0 - baseInAmount, 1 - quoteInAmount, 2 - baseOutAmount, 3- quoteOutAmount
|
||||
uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH
|
||||
uint256 minBaseReserve,
|
||||
uint256 minQuoteReserve,
|
||||
uint256 deadLine
|
||||
) external override payable preventReentrant judgeExpired(deadLine) {
|
||||
_deposit(
|
||||
msg.sender,
|
||||
dppAddress,
|
||||
IDODOV2(dppAddress)._BASE_TOKEN_(),
|
||||
baseInAmount,
|
||||
amountList[0],
|
||||
flag == 1
|
||||
);
|
||||
_deposit(
|
||||
msg.sender,
|
||||
dppAddress,
|
||||
IDODOV2(dppAddress)._QUOTE_TOKEN_(),
|
||||
quoteInAmount,
|
||||
amountList[1],
|
||||
flag == 2
|
||||
);
|
||||
|
||||
IDODOV2(IDODOV2(dppAddress)._OWNER_()).reset(
|
||||
require(IDODOV2(IDODOV2(dppAddress)._OWNER_()).reset(
|
||||
msg.sender,
|
||||
newLpFeeRate,
|
||||
newMtFeeRate,
|
||||
newI,
|
||||
newK,
|
||||
baseOutAmount,
|
||||
quoteOutAmount
|
||||
);
|
||||
paramList[0],
|
||||
paramList[1],
|
||||
paramList[2],
|
||||
paramList[3],
|
||||
amountList[2],
|
||||
amountList[3],
|
||||
minBaseReserve,
|
||||
minQuoteReserve
|
||||
), "Reset Failed");
|
||||
|
||||
_withdraw(msg.sender, IDODOV2(dppAddress)._BASE_TOKEN_(), baseOutAmount, flag == 3);
|
||||
_withdraw(msg.sender, IDODOV2(dppAddress)._QUOTE_TOKEN_(), quoteOutAmount, flag == 4);
|
||||
_withdraw(msg.sender, IDODOV2(dppAddress)._BASE_TOKEN_(), amountList[2], flag == 3);
|
||||
_withdraw(msg.sender, IDODOV2(dppAddress)._QUOTE_TOKEN_(), amountList[3], flag == 4);
|
||||
}
|
||||
|
||||
// ============ Swap ============
|
||||
@@ -342,7 +341,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
toToken,
|
||||
assetTo,
|
||||
msg.value,
|
||||
returnAmount
|
||||
returnAmount,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -387,7 +387,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
_ETH_ADDRESS_,
|
||||
assetTo,
|
||||
fromTokenAmount,
|
||||
returnAmount
|
||||
returnAmount,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -432,7 +433,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
toToken,
|
||||
assetTo,
|
||||
fromTokenAmount,
|
||||
returnAmount
|
||||
returnAmount,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -487,7 +489,8 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable
|
||||
toToken,
|
||||
msg.sender,
|
||||
fromTokenAmount,
|
||||
returnAmount
|
||||
returnAmount,
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
@@ -538,7 +541,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 +597,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) ============
|
||||
|
||||
@@ -21,9 +21,10 @@ contract DODOSwapCalcHelper {
|
||||
uint256 fromTokenAmount,
|
||||
address[] memory dodoPairs,
|
||||
uint8[] memory directions
|
||||
) external view returns (uint256 returnAmount,uint256[] memory midPrices) {
|
||||
) external view returns (uint256 returnAmount,uint256[] memory midPrices,uint256[] memory feeRates) {
|
||||
returnAmount = fromTokenAmount;
|
||||
midPrices = new uint256[](dodoPairs.length);
|
||||
feeRates = new uint256[](dodoPairs.length);
|
||||
for (uint256 i = 0; i < dodoPairs.length; i++) {
|
||||
address curDodoPair = dodoPairs[i];
|
||||
if (directions[i] == 0) {
|
||||
@@ -35,6 +36,7 @@ contract DODOSwapCalcHelper {
|
||||
);
|
||||
}
|
||||
midPrices[i] = IDODOV1(curDodoPair).getMidPrice();
|
||||
feeRates[i] = IDODOV1(curDodoPair)._MT_FEE_RATE_() + IDODOV1(curDodoPair)._LP_FEE_RATE_();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,8 +61,10 @@ interface IDODOV2 {
|
||||
uint256 newI,
|
||||
uint256 newK,
|
||||
uint256 baseOutAmount,
|
||||
uint256 quoteOutAmount
|
||||
) external;
|
||||
uint256 quoteOutAmount,
|
||||
uint256 minBaseReserve,
|
||||
uint256 minQuoteReserve
|
||||
) external returns (bool);
|
||||
|
||||
//========== CrowdPooling ===========
|
||||
|
||||
|
||||
@@ -86,15 +86,11 @@ interface IDODOV2Proxy01 is IDODOV1Proxy01 {
|
||||
|
||||
function resetDODOPrivatePool(
|
||||
address dppAddress,
|
||||
uint256 newLpFeeRate,
|
||||
uint256 newMtFeeRate,
|
||||
uint256 newI,
|
||||
uint256 newK,
|
||||
uint256 baseInAmount,
|
||||
uint256 quoteInAmount,
|
||||
uint256 baseOutAmount,
|
||||
uint256 quoteOutAmount,
|
||||
uint256[] memory paramList, //0 - newLpFeeRate, 1 - newMtFeeRate, 2 - newI, 3 - newK
|
||||
uint256[] memory amountList, //0 - baseInAmount, 1 - quoteInAmount, 2 - baseOutAmount, 3 - quoteOutAmount
|
||||
uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH
|
||||
uint256 minBaseReserve,
|
||||
uint256 minQuoteReserve,
|
||||
uint256 deadLine
|
||||
) external payable;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -46,3 +46,31 @@ DODOApprove Address: 0xCB859eA579b28e02B87A1FDE08d087ab9dbE5149
|
||||
DODOProxyV1 Address: 0xd0678Ec59d1337e29D1E1B1b6338f3E85D311F5e
|
||||
Set DODOProxyV1 Owner tx: 0xb8bc4d84d39159c34c885b53fd345c935dc82214979e5885f9f9bc3ff59a3524
|
||||
Set DODOApprove Owner And Init Set Proxy tx: 0x2199c008304d2c2a7ddfd18b26dbe4dd480aa7cd064a5ff85b87a9679b078702
|
||||
====================================================
|
||||
network type: live
|
||||
Deploy time: 2020/12/15 下午6:05:56
|
||||
Deploy type: Proxy
|
||||
DODOSwapCalcHelperAddress: 0x7B9e97C4E3F008E854CF210E6948A0E40f70461B
|
||||
====================================================
|
||||
network type: live
|
||||
Deploy time: 2020/12/15 下午6:31:06
|
||||
Deploy type: Proxy
|
||||
DODOSwapCalcHelperAddress: 0x3C02477f1B3C70D692be95a6e3805E02bba71206
|
||||
====================================================
|
||||
network type: kovan
|
||||
Deploy time: 2020/12/15 下午6:44:08
|
||||
Deploy type: Proxy
|
||||
DODOSwapCalcHelperAddress: 0x0473FFd7039435F1FC794281F2a05830A1a0108a
|
||||
====================================================
|
||||
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
|
||||
|
||||
@@ -16,3 +16,27 @@ DvmFactoryAddress: 0xaeF2cce5678e6e29f7a7C2A6f5d2Ce26df600dc1
|
||||
DppFactoryAddress: 0x5935a606383Ba43C61FcE5E632357744a95e9dC3
|
||||
DODOProxyV2 Address: 0xD4b15Ab0e1F06373dA7ccd9f01D5e9776674DB9e
|
||||
DODOApprovce setProxy tx: 0x67c5c5b1883950baec753a99bff5e1c20bfb92f876cdcd03c90ae2aa0053d891
|
||||
====================================================
|
||||
network type: kovan
|
||||
Deploy time: 2020/12/15 上午11:11:05
|
||||
Deploy type: V2
|
||||
ConstFeeRateModelTemplateAddress: 0x2ec9579Cf7ae77B4e538F56274501f518ABFeA2e
|
||||
DefaultMtFeeRateAddress: 0xEfdE4225AC747136289979e29f1236527b2E4DB1
|
||||
Init DefaultMtFeeRate Tx: 0x8f2f522627c9e98a51ebaf7cadf66a88c79bcece4bfb96da538299fc811c291f
|
||||
DefaultPermissionAddress: 0xACc7E23368261e1E02103c4e5ae672E7D01f5797
|
||||
Init DefaultPermissionAddress Tx: 0x40115ee57da686fddadc635a9048af0ba139b5fdd93f34a5ba79399a01b50c60
|
||||
DvmTemplateAddress: 0x176a7DBbcC3Fb9EB1F04bfA806a6615A7C1De766
|
||||
DvmAdminTemplateAddress: 0x210eF5260E1AcF26526b9CFe40b6fc7CD3D8b6B3
|
||||
DppTemplateAddress: 0x6E3bF8eC796c52d6e25FBB3f116795397a239BA4
|
||||
DppAdminTemplateAddress: 0x86366913A4ee1F6f01022aD42554EEAf4c5AC490
|
||||
CpTemplateAddress: 0x967b6A116e882E3d2F940f3ae2f44fd842BbF189
|
||||
DODOApprove Address: 0xC38ad4314bb44EE84cC2D4B2B1BBa4644550f172
|
||||
DvmFactoryAddress: 0x545ba2178c5581f836D4d10BDa208288dD1a8Bf8
|
||||
Init DvmFactory Tx: 0xd9412acda8972cd589c6e16fcabc9ede61e2737bc0076bf6a1ada3f771b2b525
|
||||
UnownedDvmFactoryAddress: 0x564F5B6614Afa50BB61B9d0694f3326446Bd24EF
|
||||
DppFactoryAddress: 0x6F050dAc0CC28E2cD227536deFD40fe2A1505a13
|
||||
Init DppFactory Tx: 0xc7b27b3d0240a5938448ddf2be00df6f1ac93c1eaaf5bbb1eff28d188543ed83
|
||||
CpFactoryAddress: 0xCE0fD3600E9dD81A6fB7E1d5Eed0F93a90Da184D
|
||||
DODOProxyV2 Address: 0x7102A9AA2146557EA60a6319EB40e8C8d856e628
|
||||
Init DODOProxyV2 Tx: 0xfd80f2545d8cb0d102bd8a9064bbc802e44aa16e23128256745e2f305b6da64a
|
||||
DODOApprovce Init tx: 0x87e950811171b325701e0e94aae346614b5361ac0a0285f15383626709063e63
|
||||
|
||||
@@ -7,7 +7,7 @@ const DODOProxyV1 = artifacts.require("DODOV1Proxy01");
|
||||
const DODOSellHelper = artifacts.require("DODOSellHelper");
|
||||
const DODOSwapCalcHelper = artifacts.require("DODOSwapCalcHelper");
|
||||
|
||||
const DEPLOY_ROUTE = true;
|
||||
const DEPLOY_ROUTE = false;
|
||||
|
||||
module.exports = async (deployer, network, accounts) => {
|
||||
let DODOSellHelperAddress = "";
|
||||
@@ -19,26 +19,24 @@ module.exports = async (deployer, network, accounts) => {
|
||||
if (network == "kovan") {
|
||||
DODOSellHelperAddress = "0xbdEae617F2616b45DCB69B287D52940a76035Fe3";
|
||||
WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b";
|
||||
DODOSwapCalcHelperAddress = "";
|
||||
// DODOApproveAddress = "0x0C4a80B2e234448E5f6fD86e7eFA733d985004c8";
|
||||
DODOSwapCalcHelperAddress = "0x0473FFd7039435F1FC794281F2a05830A1a0108a";
|
||||
DODOApproveAddress = "";
|
||||
chiAddress = "0x0000000000004946c0e9f43f4dee607b0ef1fa1c";
|
||||
ownerAddress = accounts[0];
|
||||
} else if (network == "live") {
|
||||
DODOSellHelperAddress = "0x533da777aedce766ceae696bf90f8541a4ba80eb";
|
||||
WETHAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
|
||||
DODOApproveAddress = "";
|
||||
DODOApproveAddress = "0xCB859eA579b28e02B87A1FDE08d087ab9dbE5149";
|
||||
chiAddress = "0x0000000000004946c0e9F43F4Dee607b0eF1fA1c";
|
||||
DODOSwapCalcHelperAddress = "0x22C1a736DBE8200E6DF2f3D8F97c0D5749c1E257";
|
||||
DODOSwapCalcHelperAddress = "0x3C02477f1B3C70D692be95a6e3805E02bba71206";
|
||||
ownerAddress = "0x95C4F5b83aA70810D4f142d58e5F7242Bd891CB0";
|
||||
} else if (network == "bsclive") {
|
||||
DODOSellHelperAddress = "0x0F859706AeE7FcF61D5A8939E8CB9dBB6c1EDA33";
|
||||
WETHAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
|
||||
DODOApproveAddress = "";
|
||||
chiAddress = "0x0000000000000000000000000000000000000000";
|
||||
DODOSwapCalcHelperAddress = "";
|
||||
//TODO:待生成替换
|
||||
ownerAddress = accounts[0];
|
||||
DODOSwapCalcHelperAddress = "0xb0199C2c8ADF1E6c1e41De60A62E993406Cb8C02";
|
||||
ownerAddress = "0x4073f2b9bB95774531b9e23d206a308c614A943a";
|
||||
} else return;
|
||||
|
||||
if (DEPLOY_ROUTE) {
|
||||
@@ -61,6 +59,7 @@ module.exports = async (deployer, network, accounts) => {
|
||||
if (DODOSwapCalcHelperAddress == "") {
|
||||
await deployer.deploy(DODOSwapCalcHelper, DODOSellHelperAddress);
|
||||
DODOSwapCalcHelperAddress = DODOSwapCalcHelper.address;
|
||||
logger.log("DODOSwapCalcHelperAddress: ", DODOSwapCalcHelperAddress);
|
||||
}
|
||||
|
||||
await deployer.deploy(
|
||||
@@ -80,10 +79,8 @@ 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 tx3 = await DODOProxyV1Instance.addWhiteList("0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D");
|
||||
// var tx2 = await DODOProxyV1Instance.addWhiteList("0xdef1c0ded9bec7f1a1670819833240f027b25eff");
|
||||
// logger.log("AddWhiteList tx1: ", tx1.tx);
|
||||
// logger.log("AddWhiteList tx2: ", tx2.tx);
|
||||
// logger.log("AddWhiteList tx3: ", tx3.tx);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,16 +3,21 @@ const file = fs.createWriteStream("../deploy-detail-v2.0.txt", { 'flags': 'a' })
|
||||
let logger = new console.Console(file, file);
|
||||
|
||||
const CloneFactory = artifacts.require("CloneFactory");
|
||||
const FeeRateModelTemplate = artifacts.require("FeeRateModel");
|
||||
const ConstFeeRateModelTemplate = artifacts.require("ConstFeeRateModel");
|
||||
const PermissionManagerTemplate = artifacts.require("PermissionManager");
|
||||
const ExternalValueTemplate = artifacts.require("ExternalValue");
|
||||
|
||||
const DvmTemplate = artifacts.require("DVM");
|
||||
const DvmAdminTemplate = artifacts.require("DVMAdmin");
|
||||
const DppTemplate = artifacts.require("DPP");
|
||||
const DppAdminTemplate = artifacts.require("DPPAdmin");
|
||||
const FeeRateModelTemplate = artifacts.require("FeeRateModel");
|
||||
const PermissionManagerTemplate = artifacts.require("PermissionManager");
|
||||
const ExternalValueTemplate = artifacts.require("ExternalValue");
|
||||
const CpTemplate = artifacts.require("CP");
|
||||
|
||||
const DvmFactory = artifacts.require("DVMFactory");
|
||||
const UnownedDvmFactory = artifacts.require("UnownedDVMFactory");
|
||||
const DppFactory = artifacts.require("DPPFactory");
|
||||
const CpFactory = artifacts.require("CrowdPoolingFactory");
|
||||
|
||||
const DODOApprove = artifacts.require("DODOApprove");
|
||||
const DODOProxyV2 = artifacts.require("DODOV2Proxy01");
|
||||
@@ -22,54 +27,134 @@ const DODOCalleeHelper = artifacts.require("DODOCalleeHelper");
|
||||
const DEPLOY_V2 = false;
|
||||
|
||||
module.exports = async (deployer, network, accounts) => {
|
||||
//Helper And Common
|
||||
let DODOSellHelperAddress = "";
|
||||
let DODOCalleeHelperAddress = "";
|
||||
let WETHAddress = "";
|
||||
let DODOApproveAddress = "";
|
||||
let chiAddress = "";
|
||||
let DODOCalleeHelperAddress = "";
|
||||
//Template
|
||||
let CloneFactoryAddress = "";
|
||||
let FeeRateModelTemplateAddress = "";
|
||||
let ConstFeeRateModelTemplateAddress = "";
|
||||
let PermissionManagerTemplateAddress = "";
|
||||
let ExternalValueTemplateAddress = "";
|
||||
//Default Template
|
||||
let DefaultGasSourceAddress = "";
|
||||
let DefaultMtFeeRateAddress = "";
|
||||
let DefaultPermissionAddress = "";
|
||||
|
||||
let DvmTemplateAddress = "";
|
||||
let DvmAdminTemplateAddress = "";
|
||||
let DppTemplateAddress = "";
|
||||
let DppAdminTemplateAddress = "";
|
||||
let CpTemplateAddress = "";
|
||||
//Facotry
|
||||
let DvmFactoryAddress = "";
|
||||
let UnownedDvmFactoryAddress = "";
|
||||
let DppFactoryAddress = "";
|
||||
let CpFactoryAddress = "";
|
||||
//Approve
|
||||
let DODOApproveAddress = "";
|
||||
//Account
|
||||
let multiSigAddress = "";
|
||||
let defaultMaintainer = "";
|
||||
|
||||
if (network == "kovan") {
|
||||
//Helper
|
||||
DODOSellHelperAddress = "0xbdEae617F2616b45DCB69B287D52940a76035Fe3";
|
||||
WETHAddress = "0x5eca15b12d959dfcf9c71c59f8b467eb8c6efd0b";
|
||||
chiAddress = "0x0000000000004946c0e9f43f4dee607b0ef1fa1c";
|
||||
DODOApproveAddress = "0x0C4a80B2e234448E5f6fD86e7eFA733d985004c8";
|
||||
DODOCalleeHelperAddress = "0x507EBbb195CF54E0aF147A2b269C08a38EA36989";
|
||||
//Template
|
||||
CloneFactoryAddress = "0xf7959fe661124C49F96CF30Da33729201aEE1b27";
|
||||
FeeRateModelTemplateAddress = "0xEF3137780B387313c5889B999D03BdCf9aeEa892";
|
||||
ConstFeeRateModelTemplateAddress = "";
|
||||
PermissionManagerTemplateAddress = "0x5D2Da09501d97a7bf0A8F192D2eb2F9Aa80d3241";
|
||||
ExternalValueTemplateAddress = "0xe0f813951dE2BB012f7Feb981669F9a7b5250A57";
|
||||
//Default Template
|
||||
DefaultGasSourceAddress = "0xE0c0df0e0be7ec4f579503304a6C186cA4365407";
|
||||
DvmTemplateAddress = "0x460Ada67279Ff2ce8c87cb88F99070c6520Aa624";
|
||||
DvmAdminTemplateAddress = "0xbB9F79f6ac9e577B658E3B2E1340838d8965986B";
|
||||
DppTemplateAddress = "0x577c2cE26B8b5C8b3f7c57826Bf351ac7c21a441";
|
||||
DppAdminTemplateAddress = "0x402ace5a3e6Aa71FB942d309341F8867afcde302";
|
||||
DefaultMtFeeRateAddress = "";
|
||||
DefaultPermissionAddress = "";
|
||||
|
||||
DvmTemplateAddress = "";
|
||||
DvmAdminTemplateAddress = "";
|
||||
DppTemplateAddress = "";
|
||||
DppAdminTemplateAddress = "";
|
||||
CpTemplateAddress = "";
|
||||
//Factory
|
||||
DvmFactoryAddress = "0xaeF2cce5678e6e29f7a7C2A6f5d2Ce26df600dc1";
|
||||
DppFactoryAddress = "0x5935a606383Ba43C61FcE5E632357744a95e9dC3";
|
||||
DvmFactoryAddress = "";
|
||||
UnownedDvmFactoryAddress = "";
|
||||
DppFactoryAddress = "";
|
||||
CpFactoryAddress = "";
|
||||
//Proxy
|
||||
DODOApproveAddress = "";
|
||||
//Account
|
||||
multiSigAddress = accounts[0];
|
||||
defaultMaintainer = accounts[0];
|
||||
} else if (network == "live") {
|
||||
//Helper
|
||||
DODOSellHelperAddress = "0x533da777aedce766ceae696bf90f8541a4ba80eb";
|
||||
WETHAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
|
||||
chiAddress = "0x0000000000004946c0e9F43F4Dee607b0eF1fA1c";
|
||||
DODOApproveAddress = "0x4eC851895d85bfa6835241b3157ae10FfFD3BebC";
|
||||
//Tempalte
|
||||
DODOCalleeHelperAddress = "";
|
||||
//Template
|
||||
CloneFactoryAddress = "";
|
||||
FeeRateModelTemplateAddress = "";
|
||||
ConstFeeRateModelTemplateAddress = "";
|
||||
PermissionManagerTemplateAddress = "";
|
||||
ExternalValueTemplateAddress = "";
|
||||
//Default Template
|
||||
DefaultGasSourceAddress = "";
|
||||
DefaultMtFeeRateAddress = "";
|
||||
DefaultPermissionAddress = "";
|
||||
|
||||
DvmTemplateAddress = "";
|
||||
DvmAdminTemplateAddress = "";
|
||||
DppTemplateAddress = "";
|
||||
DppAdminTemplateAddress = "";
|
||||
CpTemplateAddress = "";
|
||||
//Factory
|
||||
DvmFactoryAddress = "";
|
||||
UnownedDvmFactoryAddress = "";
|
||||
DppFactoryAddress = "";
|
||||
CpFactoryAddress = "";
|
||||
//Proxy
|
||||
DODOApproveAddress = "";
|
||||
//Account
|
||||
multiSigAddress = "0x95C4F5b83aA70810D4f142d58e5F7242Bd891CB0";
|
||||
defaultMaintainer = "0x95C4F5b83aA70810D4f142d58e5F7242Bd891CB0";
|
||||
} else if (network == "bsclive") {
|
||||
//Helper
|
||||
DODOSellHelperAddress = "0x0F859706AeE7FcF61D5A8939E8CB9dBB6c1EDA33";
|
||||
WETHAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
|
||||
chiAddress = "0x0000000000000000000000000000000000000000";
|
||||
DODOApproveAddress = "0x19DA73be23Cea6bFA804Ec020041b8F3971BC522";
|
||||
DODOCalleeHelperAddress = "";
|
||||
//Template
|
||||
CloneFactoryAddress = "";
|
||||
FeeRateModelTemplateAddress = "";
|
||||
ConstFeeRateModelTemplateAddress = "";
|
||||
PermissionManagerTemplateAddress = "";
|
||||
ExternalValueTemplateAddress = "";
|
||||
//Default Template
|
||||
DefaultGasSourceAddress = "";
|
||||
DefaultMtFeeRateAddress = "";
|
||||
DefaultPermissionAddress = "";
|
||||
|
||||
DvmTemplateAddress = "";
|
||||
DvmAdminTemplateAddress = "";
|
||||
DppTemplateAddress = "";
|
||||
DppAdminTemplateAddress = "";
|
||||
CpTemplateAddress = "";
|
||||
//Factory
|
||||
DvmFactoryAddress = "";
|
||||
UnownedDvmFactoryAddress = "";
|
||||
DppFactoryAddress = "";
|
||||
CpFactoryAddress = "";
|
||||
//Proxy
|
||||
DODOApproveAddress = "";
|
||||
//Account
|
||||
multiSigAddress = "";
|
||||
defaultMaintainer = "";
|
||||
} else return;
|
||||
|
||||
|
||||
@@ -78,6 +163,19 @@ module.exports = async (deployer, network, accounts) => {
|
||||
logger.log("network type: " + network);
|
||||
logger.log("Deploy time: " + new Date().toLocaleString());
|
||||
logger.log("Deploy type: V2");
|
||||
//Helper
|
||||
if (DODOSellHelperAddress == "") {
|
||||
await deployer.deploy(DODOSellHelper);
|
||||
DODOSellHelperAddress = DODOSellHelper.address;
|
||||
logger.log("DODOSellHelper Address: ", DODOSellHelperAddress);
|
||||
}
|
||||
if (DODOCalleeHelperAddress == "") {
|
||||
await deployer.deploy(DODOCalleeHelper, WETHAddress);
|
||||
DODOCalleeHelperAddress = DODOCalleeHelper.address;
|
||||
logger.log("DODOCalleeHelperAddress: ", DODOCalleeHelperAddress);
|
||||
}
|
||||
|
||||
//Template
|
||||
if (CloneFactoryAddress == "") {
|
||||
await deployer.deploy(CloneFactory);
|
||||
CloneFactoryAddress = CloneFactory.address;
|
||||
@@ -88,6 +186,11 @@ module.exports = async (deployer, network, accounts) => {
|
||||
FeeRateModelTemplateAddress = FeeRateModelTemplate.address;
|
||||
logger.log("FeeRateModelTemplateAddress: ", FeeRateModelTemplateAddress);
|
||||
}
|
||||
if (ConstFeeRateModelTemplateAddress == "") {
|
||||
await deployer.deploy(ConstFeeRateModelTemplate);
|
||||
ConstFeeRateModelTemplateAddress = ConstFeeRateModelTemplate.address;
|
||||
logger.log("ConstFeeRateModelTemplateAddress: ", ConstFeeRateModelTemplateAddress);
|
||||
}
|
||||
if (PermissionManagerTemplateAddress == "") {
|
||||
await deployer.deploy(PermissionManagerTemplate);
|
||||
PermissionManagerTemplateAddress = PermissionManagerTemplate.address;
|
||||
@@ -103,9 +206,28 @@ module.exports = async (deployer, network, accounts) => {
|
||||
DefaultGasSourceAddress = ExternalValueTemplate.address;
|
||||
logger.log("DefaultGasSourceAddress: ", DefaultGasSourceAddress);
|
||||
const defaultGasSourceInstance = await ExternalValueTemplate.at(DefaultGasSourceAddress);
|
||||
var tx = await defaultGasSourceInstance.init(accounts[0], "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
logger.log("Set default Gas Tx:", tx.tx);
|
||||
var tx = await defaultGasSourceInstance.init(multiSigAddress, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
logger.log("Init DefaultGasSource Tx:", tx.tx);
|
||||
}
|
||||
|
||||
if (DefaultMtFeeRateAddress == "") {
|
||||
await deployer.deploy(ConstFeeRateModelTemplate);
|
||||
DefaultMtFeeRateAddress = ConstFeeRateModelTemplate.address;
|
||||
logger.log("DefaultMtFeeRateAddress: ", DefaultMtFeeRateAddress);
|
||||
const defaultMtFeeRateInstance = await ConstFeeRateModelTemplate.at(DefaultMtFeeRateAddress);
|
||||
var tx = await defaultMtFeeRateInstance.init(multiSigAddress, 0);
|
||||
logger.log("Init DefaultMtFeeRate Tx:", tx.tx);
|
||||
}
|
||||
|
||||
if (DefaultPermissionAddress == "") {
|
||||
await deployer.deploy(PermissionManagerTemplate);
|
||||
DefaultPermissionAddress = PermissionManagerTemplate.address;
|
||||
logger.log("DefaultPermissionAddress: ", DefaultPermissionAddress);
|
||||
const defaultPermissionInstance = await PermissionManagerTemplate.at(DefaultPermissionAddress);
|
||||
var tx = await defaultPermissionInstance.initOwner(multiSigAddress);
|
||||
logger.log("Init DefaultPermissionAddress Tx:", tx.tx);
|
||||
}
|
||||
|
||||
if (DvmTemplateAddress == "") {
|
||||
await deployer.deploy(DvmTemplate);
|
||||
DvmTemplateAddress = DvmTemplate.address;
|
||||
@@ -126,21 +248,19 @@ module.exports = async (deployer, network, accounts) => {
|
||||
DppAdminTemplateAddress = DppAdminTemplate.address;
|
||||
logger.log("DppAdminTemplateAddress: ", DppAdminTemplateAddress);
|
||||
}
|
||||
if (CpTemplateAddress == "") {
|
||||
await deployer.deploy(CpTemplate);
|
||||
CpTemplateAddress = CpTemplate.address;
|
||||
logger.log("CpTemplateAddress: ", CpTemplateAddress);
|
||||
}
|
||||
|
||||
//Approve
|
||||
if (DODOApproveAddress == "") {
|
||||
await deployer.deploy(DODOApprove);
|
||||
DODOApproveAddress = DODOApprove.address;
|
||||
logger.log("DODOApprove Address: ", DODOApproveAddress);
|
||||
}
|
||||
if (DODOSellHelperAddress == "") {
|
||||
await deployer.deploy(DODOSellHelper);
|
||||
DODOSellHelperAddress = DODOSellHelper.address;
|
||||
logger.log("DODOSellHelper Address: ", DODOSellHelperAddress);
|
||||
}
|
||||
if (DODOCalleeHelperAddress == "") {
|
||||
await deployer.deploy(DODOCalleeHelper,WETHAddress);
|
||||
DODOCalleeHelperAddress = DODOCalleeHelper.address;
|
||||
logger.log("DODOCalleeHelperAddress: ", DODOCalleeHelperAddress);
|
||||
}
|
||||
|
||||
//Factory
|
||||
if (DvmFactoryAddress == "") {
|
||||
await deployer.deploy(
|
||||
@@ -148,13 +268,32 @@ module.exports = async (deployer, network, accounts) => {
|
||||
CloneFactoryAddress,
|
||||
DvmTemplateAddress,
|
||||
DvmAdminTemplateAddress,
|
||||
FeeRateModelTemplateAddress,
|
||||
ConstFeeRateModelTemplateAddress,
|
||||
PermissionManagerTemplateAddress,
|
||||
DefaultGasSourceAddress
|
||||
);
|
||||
DvmFactoryAddress = DvmFactory.address;
|
||||
logger.log("DvmFactoryAddress: ", DvmFactoryAddress);
|
||||
const DvmFactoryInstance = await DvmFactory.at(DvmFactoryAddress);
|
||||
var tx = await DvmFactoryInstance.initOwner(multiSigAddress);
|
||||
logger.log("Init DvmFactory Tx:", tx.tx);
|
||||
}
|
||||
|
||||
if (UnownedDvmFactoryAddress == "") {
|
||||
await deployer.deploy(
|
||||
UnownedDvmFactory,
|
||||
CloneFactoryAddress,
|
||||
DvmTemplateAddress,
|
||||
ConstFeeRateModelTemplateAddress,
|
||||
defaultMaintainer,
|
||||
DefaultMtFeeRateAddress,
|
||||
DefaultPermissionAddress,
|
||||
DefaultGasSourceAddress
|
||||
);
|
||||
UnownedDvmFactoryAddress = UnownedDvmFactory.address;
|
||||
logger.log("UnownedDvmFactoryAddress: ", UnownedDvmFactoryAddress);
|
||||
}
|
||||
|
||||
if (DppFactoryAddress == "") {
|
||||
await deployer.deploy(
|
||||
DppFactory,
|
||||
@@ -169,21 +308,45 @@ module.exports = async (deployer, network, accounts) => {
|
||||
);
|
||||
DppFactoryAddress = DppFactory.address;
|
||||
logger.log("DppFactoryAddress: ", DppFactoryAddress);
|
||||
const DppFactoryInstance = await DppFactory.at(DppFactoryAddress);
|
||||
var tx = await DppFactoryInstance.initOwner(multiSigAddress);
|
||||
logger.log("Init DppFactory Tx:", tx.tx);
|
||||
}
|
||||
|
||||
if (CpFactoryAddress == "") {
|
||||
await deployer.deploy(
|
||||
CpFactory,
|
||||
CloneFactoryAddress,
|
||||
CpTemplateAddress,
|
||||
UnownedDvmFactoryAddress,
|
||||
ConstFeeRateModelTemplateAddress,
|
||||
defaultMaintainer,
|
||||
DefaultMtFeeRateAddress,
|
||||
DefaultPermissionAddress,
|
||||
DefaultGasSourceAddress
|
||||
);
|
||||
CpFactoryAddress = CpFactory.address;
|
||||
logger.log("CpFactoryAddress: ", CpFactoryAddress);
|
||||
}
|
||||
|
||||
//Proxy
|
||||
await deployer.deploy(
|
||||
DODOProxyV2,
|
||||
DvmFactoryAddress,
|
||||
DppFactoryAddress,
|
||||
CpFactoryAddress,
|
||||
WETHAddress,
|
||||
DODOApproveAddress,
|
||||
DODOSellHelperAddress
|
||||
);
|
||||
logger.log("DODOProxyV2 Address: ", DODOProxyV2.address);
|
||||
const DODOProxyV2Instance = await DODOProxyV2.at(DODOProxyV2.address);
|
||||
var tx = await DODOProxyV2Instance.initOwner(multiSigAddress);
|
||||
logger.log("Init DODOProxyV2 Tx:", tx.tx);
|
||||
|
||||
|
||||
const DODOApproveInstance = await DODOApprove.at(DODOApproveAddress);
|
||||
var tx = await DODOApproveInstance.setDODOProxy(DODOProxyV2.address);
|
||||
logger.log("DODOApprovce setProxy tx: ", tx.tx);
|
||||
var tx = await DODOApproveInstance.init(multiSigAddress,DODOProxyV2.address);
|
||||
logger.log("DODOApprovce Init tx: ", tx.tx);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
// import * as assert from 'assert';
|
||||
|
||||
import { decimalStr } from '../utils/Converter';
|
||||
import { decimalStr, mweiStr } from '../utils/Converter';
|
||||
import { DPPContext, getDPPContext } from '../utils/DPPContext';
|
||||
import { assert } from 'chai';
|
||||
import { EXTERNAL_VALUE_NAME, getContractWithAddress, MINTABLE_ERC20_CONTRACT_NAME, newContract } from '../utils/Contracts';
|
||||
import { sendParam } from '../../script/utils';
|
||||
// import { sendParam } from '../../script/utils';
|
||||
const truffleAssert = require('truffle-assertions');
|
||||
|
||||
let lp: string;
|
||||
@@ -29,7 +29,7 @@ async function init(ctx: DPPContext): Promise<void> {
|
||||
var kValue = decimalStr("0.2")
|
||||
await ctx.transferBaseToDPP(lp, baseAmount)
|
||||
await ctx.transferQuoteToDPP(lp, quoteAmount)
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
}
|
||||
|
||||
describe("DPP Trader", () => {
|
||||
@@ -59,7 +59,7 @@ describe("DPP Trader", () => {
|
||||
var kValue = decimalStr("0.3")
|
||||
await ctx.transferBaseToDPP(lp, decimalStr("10"))
|
||||
await ctx.transferQuoteToDPP(lp, decimalStr("1000"))
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
|
||||
var state = await ctx.DPP.methods.getPMMState().call()
|
||||
assert.equal(state.B, decimalStr("20"))
|
||||
@@ -77,7 +77,7 @@ describe("DPP Trader", () => {
|
||||
var mtFeeRate = decimalStr("0.02")
|
||||
var iValue = decimalStr("300")
|
||||
var kValue = decimalStr("0.3")
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, decimalStr("1"), decimalStr("100")).send(ctx.sendParam(ctx.Deployer))
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, decimalStr("1"), decimalStr("100"), "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
|
||||
var state = await ctx.DPP.methods.getPMMState().call()
|
||||
assert.equal(state.B, decimalStr("9"))
|
||||
@@ -95,7 +95,7 @@ describe("DPP Trader", () => {
|
||||
var mtFeeRate = decimalStr("0.02")
|
||||
var iValue = decimalStr("300")
|
||||
var kValue = decimalStr("0.3")
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer))
|
||||
|
||||
var state = await ctx.DPP.methods.getPMMState().call()
|
||||
assert.equal(state.B, decimalStr("10"))
|
||||
@@ -138,16 +138,16 @@ describe("DPP Trader", () => {
|
||||
|
||||
it("i or k can not out of range", async () => {
|
||||
await truffleAssert.reverts(
|
||||
ctx.DPP.methods.reset(lp, "0", "0", "0", decimalStr("1"), "0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE"
|
||||
ctx.DPP.methods.reset(lp, "0", "0", "0", decimalStr("1"), "0", "0" ,"0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE"
|
||||
)
|
||||
await truffleAssert.reverts(
|
||||
ctx.DPP.methods.reset(lp, "0", "0", "10000000000000000000000000000000000000", decimalStr("1"), "0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE"
|
||||
ctx.DPP.methods.reset(lp, "0", "0", "10000000000000000000000000000000000000", decimalStr("1"), "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE"
|
||||
)
|
||||
await truffleAssert.reverts(
|
||||
ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), "1", "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE"
|
||||
ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), "1", "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE"
|
||||
)
|
||||
await truffleAssert.reverts(
|
||||
ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), decimalStr("2"), "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE"
|
||||
ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), decimalStr("2"), "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
220
test/Proxy/proxy.cp.test.ts
Normal file
220
test/Proxy/proxy.cp.test.ts
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 DODO ZOO.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
*/
|
||||
import { decimalStr, mweiStr } from '../utils/Converter';
|
||||
import { logGas } from '../utils/Log';
|
||||
import { ProxyContext, getProxyContext } from '../utils/ProxyContextV2';
|
||||
import { assert } from 'chai';
|
||||
import * as contracts from '../utils/Contracts';
|
||||
import { Contract } from 'web3-eth-contract';
|
||||
|
||||
let project: string;
|
||||
let buyer1: string;
|
||||
let buyer2: string;
|
||||
|
||||
|
||||
async function init(ctx: ProxyContext): Promise<void> {
|
||||
project = ctx.SpareAccounts[1];
|
||||
buyer1 = ctx.SpareAccounts[2];
|
||||
buyer2 = ctx.SpareAccounts[3];
|
||||
|
||||
await ctx.mintTestToken(project, ctx.DODO, decimalStr("1000000"));
|
||||
|
||||
await ctx.mintTestToken(buyer1, ctx.USDT, mweiStr("10000"));
|
||||
await ctx.mintTestToken(buyer2, ctx.USDT, mweiStr("10000"));
|
||||
|
||||
await ctx.approveProxy(project);
|
||||
await ctx.approveProxy(buyer1);
|
||||
await ctx.approveProxy(buyer2);
|
||||
}
|
||||
|
||||
async function initCreateCP(ctx: ProxyContext, token0: string, token1: string, token0Amount: string, timeLine: number[], valueList: string[]): Promise<string> {
|
||||
await ctx.DODOProxyV2.methods.createCrowdPooling(
|
||||
token0,
|
||||
token1,
|
||||
token0Amount,
|
||||
timeLine,
|
||||
valueList,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
).send(ctx.sendParam(project));
|
||||
if (token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address;
|
||||
if (token1 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token1 = ctx.WETH.options.address;
|
||||
var addr = await ctx.CPFactory.methods._REGISTRY_(token0, token1, 0).call();
|
||||
return addr;
|
||||
}
|
||||
|
||||
function delay(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
|
||||
describe("DODOProxyV2.0", () => {
|
||||
let snapshotId: string;
|
||||
let ctx: ProxyContext;
|
||||
let cp_DODO_USDT: string;
|
||||
let cp_DODO_WETH: string;
|
||||
let CP_DODO_USDT: Contract;
|
||||
let CP_DODO_WETH: Contract;
|
||||
|
||||
before(async () => {
|
||||
let ETH = await contracts.newContract(
|
||||
contracts.WETH_CONTRACT_NAME
|
||||
);
|
||||
ctx = await getProxyContext(ETH.options.address);
|
||||
await init(ctx);
|
||||
var timeLine = [
|
||||
Math.floor(new Date().getTime() / 1000) + 10,
|
||||
60 * 60 * 24,
|
||||
60 * 60 * 24,
|
||||
60 * 60 * 24 * 30
|
||||
]
|
||||
var valueList = [
|
||||
mweiStr("10000"),
|
||||
decimalStr("0.2"),
|
||||
decimalStr("0.5"),
|
||||
decimalStr("1")
|
||||
]
|
||||
cp_DODO_USDT = await initCreateCP(ctx, ctx.DODO.options.address, ctx.USDT.options.address, decimalStr("100000"), timeLine, valueList);
|
||||
CP_DODO_USDT = contracts.getContractWithAddress(contracts.CROWD_POOLING_NAME, cp_DODO_USDT);
|
||||
console.log("cp_DODO_USDT:", cp_DODO_USDT);
|
||||
cp_DODO_WETH = await initCreateCP(ctx, ctx.DODO.options.address, ctx.WETH.options.address, decimalStr("100000"), timeLine, valueList);
|
||||
CP_DODO_WETH = contracts.getContractWithAddress(contracts.CROWD_POOLING_NAME, cp_DODO_WETH);
|
||||
console.log("cp_DODO_WETH:", cp_DODO_WETH);
|
||||
console.log("Wait to bid start...");
|
||||
await delay(11000);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
snapshotId = await ctx.EVM.snapshot();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await ctx.EVM.reset(snapshotId);
|
||||
});
|
||||
|
||||
describe("DODOProxy", () => {
|
||||
it("createCP", async () => {
|
||||
var baseToken = ctx.DODO.options.address;
|
||||
var quoteToken = ctx.USDT.options.address;
|
||||
var baseAmount = decimalStr("100000");
|
||||
var timeLine = [
|
||||
Math.floor(new Date().getTime() / 1000) + 10,
|
||||
60 * 60 * 24,
|
||||
60 * 60 * 24,
|
||||
60 * 60 * 24 * 30
|
||||
]
|
||||
var valueList = [
|
||||
mweiStr("10000"),
|
||||
decimalStr("0.2"),
|
||||
decimalStr("0.5"),
|
||||
decimalStr("1")
|
||||
]
|
||||
await logGas(await ctx.DODOProxyV2.methods.createCrowdPooling(
|
||||
baseToken,
|
||||
quoteToken,
|
||||
baseAmount,
|
||||
timeLine,
|
||||
valueList,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(project), "createCP");
|
||||
var addrs = await ctx.CPFactory.methods.getCrowdPooling(baseToken, quoteToken).call();
|
||||
assert.equal(
|
||||
await ctx.DODO.methods.balanceOf(addrs[1]).call(),
|
||||
baseAmount
|
||||
);
|
||||
});
|
||||
|
||||
it("bid", async () => {
|
||||
var b_base = await ctx.DODO.methods.balanceOf(cp_DODO_USDT).call();
|
||||
var b_quote = await ctx.USDT.methods.balanceOf(cp_DODO_USDT).call();
|
||||
var b_lp_1 = await CP_DODO_USDT.methods.getShares(buyer1).call();
|
||||
var b_lp_2 = await CP_DODO_USDT.methods.getShares(buyer2).call();
|
||||
assert.equal(b_base, decimalStr("100000"));
|
||||
assert.equal(b_quote, mweiStr("0"));
|
||||
assert.equal(b_lp_1, decimalStr("0"));
|
||||
assert.equal(b_lp_2, decimalStr("0"));
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.bid(
|
||||
buyer1,
|
||||
cp_DODO_USDT,
|
||||
mweiStr("50"),
|
||||
0,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(buyer1), "bid");
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.bid(
|
||||
buyer2,
|
||||
cp_DODO_USDT,
|
||||
mweiStr("80"),
|
||||
0,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(buyer2), "bid");
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.bid(
|
||||
buyer2,
|
||||
cp_DODO_USDT,
|
||||
mweiStr("80"),
|
||||
0,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(buyer2), "bid");
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.bid(
|
||||
buyer2,
|
||||
cp_DODO_USDT,
|
||||
mweiStr("80"),
|
||||
0,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(buyer2), "bid");
|
||||
|
||||
var a_base = await ctx.DODO.methods.balanceOf(cp_DODO_USDT).call();
|
||||
var a_quote = await ctx.USDT.methods.balanceOf(cp_DODO_USDT).call();
|
||||
var a_lp_1 = await CP_DODO_USDT.methods.getShares(buyer1).call();
|
||||
var a_lp_2 = await CP_DODO_USDT.methods.getShares(buyer2).call();
|
||||
assert.equal(a_base, decimalStr("100000"));
|
||||
assert.equal(a_quote, mweiStr("290"));
|
||||
assert.equal(a_lp_1, mweiStr("50"));
|
||||
assert.equal(a_lp_2, mweiStr("240"));
|
||||
});
|
||||
|
||||
|
||||
it("bid - ETH", async () => {
|
||||
var b_base = await ctx.DODO.methods.balanceOf(cp_DODO_WETH).call();
|
||||
var b_quote = await ctx.WETH.methods.balanceOf(cp_DODO_WETH).call();
|
||||
var b_lp_1 = await CP_DODO_WETH.methods.getShares(buyer1).call();
|
||||
var b_lp_2 = await CP_DODO_WETH.methods.getShares(buyer2).call();
|
||||
assert.equal(b_base, decimalStr("100000"));
|
||||
assert.equal(b_quote, decimalStr("0"));
|
||||
assert.equal(b_lp_1, decimalStr("0"));
|
||||
assert.equal(b_lp_2, decimalStr("0"));
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.bid(
|
||||
buyer1,
|
||||
cp_DODO_WETH,
|
||||
decimalStr("2"),
|
||||
1,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(buyer1, "2"), "bid");
|
||||
|
||||
await logGas(await ctx.DODOProxyV2.methods.bid(
|
||||
buyer2,
|
||||
cp_DODO_WETH,
|
||||
decimalStr("1"),
|
||||
1,
|
||||
Math.floor(new Date().getTime() / 1000 + 60 * 10)
|
||||
), ctx.sendParam(buyer2, "1"), "bid");
|
||||
|
||||
var a_base = await ctx.DODO.methods.balanceOf(cp_DODO_WETH).call();
|
||||
var a_quote = await ctx.WETH.methods.balanceOf(cp_DODO_WETH).call();
|
||||
var a_lp_1 = await CP_DODO_WETH.methods.getShares(buyer1).call();
|
||||
var a_lp_2 = await CP_DODO_WETH.methods.getShares(buyer2).call();
|
||||
assert.equal(a_base, decimalStr("100000"));
|
||||
assert.equal(a_quote, decimalStr("3"));
|
||||
assert.equal(a_lp_1, decimalStr("2"));
|
||||
assert.equal(a_lp_2, decimalStr("1"));
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -153,15 +153,11 @@ describe("DODOProxyV2.0", () => {
|
||||
assert.equal(beforeState.Q0,mweiStr("30000"));
|
||||
await logGas(await ctx.DODOProxyV2.methods.resetDODOPrivatePool(
|
||||
dpp_DODO_USDT,
|
||||
config.lpFeeRate,
|
||||
config.mtFeeRate,
|
||||
mweiStr("0.3"),
|
||||
decimalStr("0.2"),
|
||||
decimalStr("1000"),
|
||||
mweiStr("1000"),
|
||||
decimalStr("0"),
|
||||
mweiStr("0"),
|
||||
[config.lpFeeRate, config.mtFeeRate, mweiStr("0.3"), decimalStr("0.2")],
|
||||
[decimalStr("1000"), mweiStr("1000"), decimalStr("0"), mweiStr("0")],
|
||||
0,
|
||||
decimalStr("100000"),
|
||||
mweiStr("0"),
|
||||
Math.floor(new Date().getTime()/1000 + 60 * 10)
|
||||
),ctx.sendParam(project),"resetDPP");
|
||||
var afterState = await DPP_DODO_USDT.methods.getPMMState().call();
|
||||
@@ -179,15 +175,11 @@ describe("DODOProxyV2.0", () => {
|
||||
var b_ETH = await ctx.Web3.eth.getBalance(project);
|
||||
var tx = await logGas(await ctx.DODOProxyV2.methods.resetDODOPrivatePool(
|
||||
dpp_WETH_USDT,
|
||||
config.lpFeeRate,
|
||||
config.mtFeeRate,
|
||||
mweiStr("600"),
|
||||
decimalStr("0.2"),
|
||||
decimalStr("0"),
|
||||
mweiStr("1000"),
|
||||
decimalStr("1"),
|
||||
mweiStr("0"),
|
||||
[config.lpFeeRate, config.mtFeeRate, mweiStr("600"), decimalStr("0.2")],
|
||||
[decimalStr("0"), mweiStr("1000"), decimalStr("1"), mweiStr("0")],
|
||||
3,
|
||||
decimalStr("0"),
|
||||
mweiStr("0"),
|
||||
Math.floor(new Date().getTime()/1000 + 60 * 10)
|
||||
),ctx.sendParam(project),"resetDPP-OutETH");
|
||||
var afterState = await DPP_WETH_USDT.methods.getPMMState().call();
|
||||
@@ -209,15 +201,11 @@ describe("DODOProxyV2.0", () => {
|
||||
var b_ETH = await ctx.Web3.eth.getBalance(project);
|
||||
var tx = await logGas(await ctx.DODOProxyV2.methods.resetDODOPrivatePool(
|
||||
dpp_WETH_USDT,
|
||||
config.lpFeeRate,
|
||||
config.mtFeeRate,
|
||||
mweiStr("600"),
|
||||
decimalStr("0.2"),
|
||||
decimalStr("1"),
|
||||
mweiStr("1000"),
|
||||
[config.lpFeeRate, config.mtFeeRate, mweiStr("600"), decimalStr("0.2")],
|
||||
[decimalStr("1"), mweiStr("1000"), decimalStr("0"), mweiStr("0")],
|
||||
1,
|
||||
decimalStr("0"),
|
||||
mweiStr("0"),
|
||||
1,
|
||||
Math.floor(new Date().getTime()/1000 + 60 * 10)
|
||||
),ctx.sendParam(project,"1"),"resetDPP-InETH");
|
||||
var afterState = await DPP_WETH_USDT.methods.getPMMState().call();
|
||||
|
||||
@@ -237,7 +237,9 @@ export class DODOContext {
|
||||
// [this.DODOApprove.options.address, this.DODOSellHelper.options.address, this.WETH.options.address, "0x0000000000000000000000000000000000000000"]
|
||||
);
|
||||
|
||||
await this.DODOApprove.methods.setDODOProxy(this.DODOProxyV1.options.address).send(this.sendParam(this.Deployer));
|
||||
await this.DODOProxyV1.methods.initOwner(this.Deployer).send(this.sendParam(this.Deployer));
|
||||
await this.DODOApprove.methods.init(this.Deployer,this.DODOProxyV1.options.address).send(this.sendParam(this.Deployer));
|
||||
|
||||
|
||||
// await this.CHI.methods.transfer(this.DODOProxyV1.options.address,140).send(this.sendParam(this.Deployer));
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ export const DVM_ADMIN_NAME = "DVMAdmin"
|
||||
export const DPP_ADMIN_NAME = "DPPAdmin"
|
||||
export const DODO_CALLEE_HELPER_NAME = "DODOCalleeHelper"
|
||||
export const CROWD_POOLING_NAME = "CP"
|
||||
export const CROWD_POOLING_FACTORY = "CrowdPoolingFactory"
|
||||
|
||||
interface ContractJson {
|
||||
abi: any;
|
||||
|
||||
@@ -92,6 +92,13 @@ export class DPPContext {
|
||||
this.Maintainer = allAccounts[1];
|
||||
this.SpareAccounts = allAccounts.slice(2, 10);
|
||||
|
||||
await gasPriceSource.methods.init(this.Deployer, MAX_UINT256).send(this.sendParam(this.Deployer))
|
||||
await lpFeeRateModel.methods.init(this.DPP.options.address, config.lpFeeRate).send(this.sendParam(this.Deployer))
|
||||
await mtFeeRateModel.methods.init(this.DPP.options.address, config.mtFeeRate).send(this.sendParam(this.Deployer))
|
||||
|
||||
await kSource.methods.init(this.DPP.options.address, config.k).send(this.sendParam(this.Deployer))
|
||||
await iSource.methods.init(this.DPP.options.address, config.i).send(this.sendParam(this.Deployer))
|
||||
|
||||
await this.DPP.methods.init(
|
||||
this.Deployer,
|
||||
this.Maintainer,
|
||||
@@ -105,13 +112,6 @@ export class DPPContext {
|
||||
permissionManager.options.address,
|
||||
).send(this.sendParam(this.Deployer))
|
||||
|
||||
await gasPriceSource.methods.init(this.Deployer, MAX_UINT256).send(this.sendParam(this.Deployer))
|
||||
await lpFeeRateModel.methods.init(this.DPP.options.address, config.lpFeeRate).send(this.sendParam(this.Deployer))
|
||||
await mtFeeRateModel.methods.init(this.DPP.options.address, config.mtFeeRate).send(this.sendParam(this.Deployer))
|
||||
|
||||
await kSource.methods.init(this.DPP.options.address, config.k).send(this.sendParam(this.Deployer))
|
||||
await iSource.methods.init(this.DPP.options.address, config.i).send(this.sendParam(this.Deployer))
|
||||
|
||||
console.log(log.blueText("[Init DPP context]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ export class ProxyContext {
|
||||
DODOProxyV2: Contract;
|
||||
DVMFactory: Contract;
|
||||
DPPFactory: Contract;
|
||||
CPFactory: Contract;
|
||||
UnownedDVMFactory: Contract;
|
||||
DODOApprove: Contract;
|
||||
DODOCalleeHelper: Contract;
|
||||
DODOSellHelper: Contract;
|
||||
@@ -44,7 +46,6 @@ export class ProxyContext {
|
||||
async init(weth:string) {
|
||||
this.EVM = new EVM();
|
||||
this.Web3 = getDefaultWeb3();
|
||||
|
||||
const allAccounts = await this.Web3.eth.getAccounts();
|
||||
this.Deployer = allAccounts[0];
|
||||
this.Maintainer = allAccounts[1];
|
||||
@@ -57,6 +58,7 @@ export class ProxyContext {
|
||||
);
|
||||
var dvmTemplate = await contracts.newContract(contracts.DVM_NAME)
|
||||
var dppTemplate = await contracts.newContract(contracts.DPP_NAME)
|
||||
var cpTemplate = await contracts.newContract(contracts.CROWD_POOLING_NAME)
|
||||
var dvmAdminTemplate = await contracts.newContract(contracts.DVM_ADMIN_NAME)
|
||||
var dppAdminTemplate = await contracts.newContract(contracts.DPP_ADMIN_NAME)
|
||||
var feeRateModelTemplate = await contracts.newContract(contracts.FEE_RATE_MODEL_NAME)
|
||||
@@ -76,10 +78,24 @@ export class ProxyContext {
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
this.UnownedDVMFactory = await contracts.newContract(contracts.UNOWNED_DVM_FACTORY_NAME,
|
||||
[
|
||||
cloneFactory.options.address,
|
||||
dvmTemplate.options.address,
|
||||
feeRateModelTemplate.options.address,
|
||||
this.Deployer,
|
||||
feeRateModelTemplate.options.address,
|
||||
permissionManagerTemplate.options.address,
|
||||
defaultGasSource.options.address
|
||||
]
|
||||
)
|
||||
|
||||
this.DODOApprove = await contracts.newContract(
|
||||
contracts.SMART_APPROVE
|
||||
);
|
||||
|
||||
|
||||
this.DPPFactory = await contracts.newContract(contracts.DPP_FACTORY_NAME,
|
||||
[
|
||||
cloneFactory.options.address,
|
||||
@@ -93,6 +109,19 @@ export class ProxyContext {
|
||||
]
|
||||
)
|
||||
|
||||
this.CPFactory = await contracts.newContract(contracts.CROWD_POOLING_FACTORY,
|
||||
[
|
||||
cloneFactory.options.address,
|
||||
cpTemplate.options.address,
|
||||
this.UnownedDVMFactory.options.address,
|
||||
feeRateModelTemplate.options.address,
|
||||
this.Deployer,
|
||||
feeRateModelTemplate.options.address,
|
||||
permissionManagerTemplate.options.address,
|
||||
defaultGasSource.options.address
|
||||
]
|
||||
)
|
||||
|
||||
this.DODOSellHelper = await contracts.newContract(
|
||||
contracts.DODO_SELL_HELPER
|
||||
);
|
||||
@@ -101,13 +130,15 @@ export class ProxyContext {
|
||||
[
|
||||
this.DVMFactory.options.address,
|
||||
this.DPPFactory.options.address,
|
||||
this.CPFactory.options.address,
|
||||
this.WETH.options.address,
|
||||
this.DODOApprove.options.address,
|
||||
this.DODOSellHelper.options.address
|
||||
]
|
||||
);
|
||||
|
||||
await this.DODOApprove.methods.setDODOProxy(this.DODOProxyV2.options.address).send(this.sendParam(this.Deployer));
|
||||
await this.DODOProxyV2.methods.initOwner(this.Deployer).send(this.sendParam(this.Deployer));
|
||||
await this.DODOApprove.methods.init(this.Deployer,this.DODOProxyV2.options.address).send(this.sendParam(this.Deployer));
|
||||
|
||||
this.DODO = await contracts.newContract(
|
||||
contracts.MINTABLE_ERC20_CONTRACT_NAME,
|
||||
|
||||
@@ -68,7 +68,7 @@ module.exports = {
|
||||
return new HDWalletProvider(privKey, "https://mainnet.infura.io/v3/" + infuraId);
|
||||
},
|
||||
gas: 3000000,
|
||||
gasPrice: 50000000000,
|
||||
gasPrice: 100000000000,
|
||||
network_id: 1,
|
||||
skipDryRun: true
|
||||
},
|
||||
|
||||
@@ -21,6 +21,11 @@ then
|
||||
truffle test ./test/Proxy/proxy.classical.test.ts
|
||||
fi
|
||||
|
||||
if [ "$1"x = "proxy-cp"x ]
|
||||
then
|
||||
truffle test ./test/Proxy/proxy.cp.test.ts
|
||||
fi
|
||||
|
||||
if [ "$1"x = "route"x ]
|
||||
then
|
||||
truffle test ./test/Route/route.test.ts
|
||||
|
||||
Reference in New Issue
Block a user