init test env
This commit is contained in:
@@ -31,7 +31,7 @@ contract DVMFactory is Ownable {
|
|||||||
_CONTROLLER_TEMPLATE_ = controllerTemplate;
|
_CONTROLLER_TEMPLATE_ = controllerTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDODOVenderMachine(
|
function createDODOVendorMachine(
|
||||||
address maintainer,
|
address maintainer,
|
||||||
address baseToken,
|
address baseToken,
|
||||||
address quoteToken,
|
address quoteToken,
|
||||||
@@ -40,17 +40,15 @@ contract DVMFactory is Ownable {
|
|||||||
uint256 i,
|
uint256 i,
|
||||||
uint256 k,
|
uint256 k,
|
||||||
uint256 gasPriceLimit
|
uint256 gasPriceLimit
|
||||||
) external returns (address newVenderMachine) {
|
) external returns (address newVendorMachine) {
|
||||||
DVMController controller = DVMController(
|
newVendorMachine = ICloneFactory(_CLONE_FACTORY_).clone(_CONTROLLER_TEMPLATE_);
|
||||||
ICloneFactory(_CLONE_FACTORY_).clone(_CONTROLLER_TEMPLATE_)
|
address vault = ICloneFactory(_CLONE_FACTORY_).clone(_VAULT_TEMPLATE_);
|
||||||
);
|
DVMVault(vault).init(newVendorMachine, baseToken, quoteToken); // vault owner is controller
|
||||||
DVMVault vault = DVMVault(ICloneFactory(_CLONE_FACTORY_).clone(_VAULT_TEMPLATE_));
|
|
||||||
vault.init(address(controller), baseToken, quoteToken); // vault owner is controller
|
|
||||||
|
|
||||||
controller.init(
|
DVMController(newVendorMachine).init(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
maintainer,
|
maintainer,
|
||||||
address(vault),
|
vault,
|
||||||
lpFeeRateModel,
|
lpFeeRateModel,
|
||||||
mtFeeRateModel,
|
mtFeeRateModel,
|
||||||
i,
|
i,
|
||||||
@@ -58,8 +56,15 @@ contract DVMFactory is Ownable {
|
|||||||
gasPriceLimit
|
gasPriceLimit
|
||||||
);
|
);
|
||||||
|
|
||||||
newVenderMachine = address(controller);
|
_REGISTRY_[baseToken][quoteToken].push(newVendorMachine);
|
||||||
_REGISTRY_[baseToken][quoteToken].push(newVenderMachine);
|
return newVendorMachine;
|
||||||
return newVenderMachine;
|
}
|
||||||
|
|
||||||
|
function getVendorMachine(address baseToken, address quoteToken)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (address[] memory machines)
|
||||||
|
{
|
||||||
|
return _REGISTRY_[baseToken][quoteToken];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,9 @@ contract DVMController is DVMTrader, DVMFunding, DVMAdmin {
|
|||||||
) external {
|
) external {
|
||||||
initOwner(owner);
|
initOwner(owner);
|
||||||
_MAINTAINER_ = maintainer;
|
_MAINTAINER_ = maintainer;
|
||||||
_BASE_TOKEN_ = DVMVault(vault)._BASE_TOKEN_();
|
_VAULT_ = DVMVault(vault);
|
||||||
_QUOTE_TOKEN_ = DVMVault(vault)._QUOTE_TOKEN_();
|
_BASE_TOKEN_ = _VAULT_._BASE_TOKEN_();
|
||||||
|
_QUOTE_TOKEN_ = _VAULT_._QUOTE_TOKEN_();
|
||||||
_LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel);
|
_LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel);
|
||||||
_MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel);
|
_MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel);
|
||||||
_I_ = i;
|
_I_ = i;
|
||||||
@@ -15,41 +15,35 @@ contract DVMFunding is DVMStorage {
|
|||||||
function buyShares(address account) external returns (uint256) {
|
function buyShares(address account) external returns (uint256) {
|
||||||
uint256 baseInput = _VAULT_.getBaseInput();
|
uint256 baseInput = _VAULT_.getBaseInput();
|
||||||
uint256 quoteInput = _VAULT_.getQuoteInput();
|
uint256 quoteInput = _VAULT_.getQuoteInput();
|
||||||
|
|
||||||
require(baseInput > 0, "NO_BASE_INPUT");
|
require(baseInput > 0, "NO_BASE_INPUT");
|
||||||
|
|
||||||
uint256 baseReserve = _VAULT_._BASE_RESERVE_();
|
uint256 baseReserve = _VAULT_._BASE_RESERVE_();
|
||||||
uint256 quoteReserve = _VAULT_._QUOTE_RESERVE_();
|
uint256 quoteReserve = _VAULT_._QUOTE_RESERVE_();
|
||||||
uint256 mintAmount;
|
uint256 mintAmount;
|
||||||
|
|
||||||
// case 1. initial supply
|
// case 1. initial supply
|
||||||
if (baseReserve == 0 && quoteReserve == 0) {
|
if (baseReserve == 0 && quoteReserve == 0) {
|
||||||
mintAmount = baseInput;
|
mintAmount = baseInput;
|
||||||
}
|
}
|
||||||
|
// // case 2. supply when quote reserve is 0
|
||||||
// case 2. supply when quote reserve is 0
|
// if (baseReserve > 0 && quoteReserve == 0) {
|
||||||
if (baseReserve > 0 && quoteReserve == 0) {
|
// uint256 mintRatio = DecimalMath.divFloor(baseInput, baseReserve);
|
||||||
uint256 mintRatio = DecimalMath.divFloor(baseInput, baseReserve);
|
// mintAmount = DecimalMath.mulFloor(_VAULT_.totalSupply(), mintRatio);
|
||||||
mintAmount = DecimalMath.mulFloor(_VAULT_.totalSupply(), mintRatio);
|
// }
|
||||||
}
|
// // case 3. normal case
|
||||||
|
// if (baseReserve > 0 && quoteReserve > 0) {
|
||||||
// case 3. normal case
|
// uint256 baseInputRatio = DecimalMath.divFloor(baseInput, baseReserve);
|
||||||
if (baseReserve > 0 && quoteReserve > 0) {
|
// uint256 quoteInputRatio = DecimalMath.divFloor(quoteInput, quoteReserve);
|
||||||
uint256 baseInputRatio = DecimalMath.divFloor(baseInput, baseReserve);
|
// uint256 mintRatio = baseInputRatio > quoteInputRatio ? quoteInputRatio : baseInputRatio;
|
||||||
uint256 quoteInputRatio = DecimalMath.divFloor(quoteInput, quoteReserve);
|
// // 在提币的时候向下取整。因此永远不会出现,balance为0但totalsupply不为0的情况
|
||||||
uint256 mintRatio = baseInputRatio > quoteInputRatio ? quoteInputRatio : baseInputRatio;
|
// // 但有可能出现,reserve>0但totalSupply=0的场景
|
||||||
// 在提币的时候向下取整。因此永远不会出现,balance为0但totalsupply不为0的情况
|
// uint256 totalShare = _VAULT_.totalSupply();
|
||||||
// 但有可能出现,reserve>0但totalSupply=0的场景
|
// if (totalShare > 0) {
|
||||||
uint256 totalShare = _VAULT_.totalSupply();
|
// mintAmount = DecimalMath.mulFloor(totalShare, mintRatio);
|
||||||
if (totalShare > 0) {
|
// } else {
|
||||||
mintAmount = DecimalMath.mulFloor(totalShare, mintRatio);
|
// mintAmount = baseInput;
|
||||||
} else {
|
// }
|
||||||
mintAmount = baseInput;
|
// }
|
||||||
}
|
// _VAULT_.mint(account, mintAmount);
|
||||||
}
|
// _VAULT_.sync();
|
||||||
|
|
||||||
_VAULT_.mint(account, mintAmount);
|
|
||||||
_VAULT_.sync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sellShares(
|
function sellShares(
|
||||||
@@ -66,6 +66,8 @@ contract DVMVault is InitializableOwnable {
|
|||||||
);
|
);
|
||||||
symbol = "DLP";
|
symbol = "DLP";
|
||||||
decimals = IERC20(_baseToken).decimals();
|
decimals = IERC20(_baseToken).decimals();
|
||||||
|
_BASE_TOKEN_ = _baseToken;
|
||||||
|
_QUOTE_TOKEN_ = _quoteToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vault related
|
// Vault related
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
pragma solidity 0.6.9;
|
pragma solidity 0.6.9;
|
||||||
|
|
||||||
import {Ownable} from "../lib/Ownable.sol";
|
import {Ownable} from "../lib/Ownable.sol";
|
||||||
import {DVMController} from "../DODOVenderMachine/impl/DVMController.sol";
|
import {DVMController} from "../DODOVendorMachine/impl/DVMController.sol";
|
||||||
import {DVMVault} from "../DODOVenderMachine/impl/DVMVault.sol";
|
import {DVMVault} from "../DODOVendorMachine/impl/DVMVault.sol";
|
||||||
import {IERC20} from "../intf/IERC20.sol";
|
import {IERC20} from "../intf/IERC20.sol";
|
||||||
import {SafeERC20} from "../lib/SafeERC20.sol";
|
import {SafeERC20} from "../lib/SafeERC20.sol";
|
||||||
import {SafeMath} from "../lib/SafeMath.sol";
|
import {SafeMath} from "../lib/SafeMath.sol";
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ pragma solidity 0.6.9;
|
|||||||
|
|
||||||
import {SafeMath} from "../../lib/SafeMath.sol";
|
import {SafeMath} from "../../lib/SafeMath.sol";
|
||||||
|
|
||||||
contract TestERC20 {
|
contract MintableERC20 {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
|
|
||||||
string public name;
|
string public name;
|
||||||
|
string public symbol;
|
||||||
uint8 public decimals;
|
uint8 public decimals;
|
||||||
|
|
||||||
mapping(address => uint256) balances;
|
mapping(address => uint256) balances;
|
||||||
@@ -21,8 +22,13 @@ contract TestERC20 {
|
|||||||
event Transfer(address indexed from, address indexed to, uint256 amount);
|
event Transfer(address indexed from, address indexed to, uint256 amount);
|
||||||
event Approval(address indexed owner, address indexed spender, uint256 amount);
|
event Approval(address indexed owner, address indexed spender, uint256 amount);
|
||||||
|
|
||||||
constructor(string memory _name, uint8 _decimals) public {
|
constructor(
|
||||||
|
string memory _name,
|
||||||
|
string memory _symbol,
|
||||||
|
uint8 _decimals
|
||||||
|
) public {
|
||||||
name = _name;
|
name = _name;
|
||||||
|
symbol = _symbol;
|
||||||
decimals = _decimals;
|
decimals = _decimals;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,3 +1 @@
|
|||||||
const DODOZoo = artifacts.require("DODOZoo");
|
|
||||||
|
|
||||||
module.exports = async (deployer, network) => {};
|
module.exports = async (deployer, network) => {};
|
||||||
|
|||||||
85
test/DVM/trader.ts
Normal file
85
test/DVM/trader.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 DODO ZOO.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// import * as assert from 'assert';
|
||||||
|
|
||||||
|
import { decimalStr } from '../utils/Converter';
|
||||||
|
import { logGas } from '../utils/Log';
|
||||||
|
import { DVMContext, getDVMContext } from '../utils/DVMContext';
|
||||||
|
import { DVM_VAULT_NAME, getContractWithAddress } from '../utils/Contracts';
|
||||||
|
import { Contract } from 'web3-eth-contract';
|
||||||
|
|
||||||
|
let lp: string;
|
||||||
|
let trader: string;
|
||||||
|
let vault: Contract
|
||||||
|
|
||||||
|
async function init(ctx: DVMContext): Promise<void> {
|
||||||
|
lp = ctx.SpareAccounts[0];
|
||||||
|
trader = ctx.SpareAccounts[1];
|
||||||
|
await ctx.approveRoute(lp);
|
||||||
|
await ctx.approveRoute(trader);
|
||||||
|
|
||||||
|
console.log("approve")
|
||||||
|
|
||||||
|
await ctx.mintTestToken(lp, decimalStr("10"), decimalStr("1000"));
|
||||||
|
await ctx.mintTestToken(trader, decimalStr("10"), decimalStr("1000"));
|
||||||
|
|
||||||
|
console.log("mint")
|
||||||
|
|
||||||
|
var vaultAddress = await ctx.DVM.methods._VAULT_().call();
|
||||||
|
vault = getContractWithAddress(DVM_VAULT_NAME, vaultAddress)
|
||||||
|
|
||||||
|
await ctx.Route.methods
|
||||||
|
.depositToDVM(ctx.DVM.options.address, lp, decimalStr("10"), decimalStr("0"))
|
||||||
|
.send(ctx.sendParam(lp));
|
||||||
|
|
||||||
|
console.log(await vault.methods.getVaultBalance().call())
|
||||||
|
|
||||||
|
console.log("deposit")
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Trader", () => {
|
||||||
|
let snapshotId: string;
|
||||||
|
let ctx: DVMContext;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
ctx = await getDVMContext();
|
||||||
|
await init(ctx);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
snapshotId = await ctx.EVM.snapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await ctx.EVM.reset(snapshotId);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("trade", () => {
|
||||||
|
it("buy when R equals ONE", async () => {
|
||||||
|
await logGas(ctx.Route.methods.sellBaseOnDVM(ctx.DVM.options.address, trader, decimalStr("1"), decimalStr("90")), ctx.sendParam(trader), "buy base token when balanced")
|
||||||
|
// trader balances
|
||||||
|
console.log(
|
||||||
|
await ctx.BASE.methods.balanceOf(trader).call(),
|
||||||
|
decimalStr("11")
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
await ctx.QUOTE.methods.balanceOf(trader).call(),
|
||||||
|
"898581839502056240973"
|
||||||
|
);
|
||||||
|
// maintainer balances
|
||||||
|
console.log(
|
||||||
|
await ctx.BASE.methods.balanceOf(ctx.Maintainer).call(),
|
||||||
|
decimalStr("0.001")
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
await ctx.QUOTE.methods.balanceOf(ctx.Maintainer).call(),
|
||||||
|
decimalStr("0")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -15,7 +15,7 @@ import { Contract } from 'web3-eth-contract';
|
|||||||
|
|
||||||
export const CLONE_FACTORY_CONTRACT_NAME = "CloneFactory"
|
export const CLONE_FACTORY_CONTRACT_NAME = "CloneFactory"
|
||||||
export const DODO_CONTRACT_NAME = "DODO"
|
export const DODO_CONTRACT_NAME = "DODO"
|
||||||
export const TEST_ERC20_CONTRACT_NAME = "TestERC20"
|
export const MINTABLE_ERC20_CONTRACT_NAME = "MintableERC20"
|
||||||
export const NAIVE_ORACLE_CONTRACT_NAME = "NaiveOracle"
|
export const NAIVE_ORACLE_CONTRACT_NAME = "NaiveOracle"
|
||||||
export const DODO_LP_TOKEN_CONTRACT_NAME = "DODOLpToken"
|
export const DODO_LP_TOKEN_CONTRACT_NAME = "DODOLpToken"
|
||||||
export const DODO_ZOO_CONTRACT_NAME = "DOOZoo"
|
export const DODO_ZOO_CONTRACT_NAME = "DOOZoo"
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ export class DVMContext {
|
|||||||
this.DVMFactory = await contracts.newContract(contracts.DVM_FACTORY_NAME, [cloneFactory.options.address, vaultTemplate.options.address, controllerTemplate.options.address])
|
this.DVMFactory = await contracts.newContract(contracts.DVM_FACTORY_NAME, [cloneFactory.options.address, vaultTemplate.options.address, controllerTemplate.options.address])
|
||||||
|
|
||||||
this.BASE = await contracts.newContract(
|
this.BASE = await contracts.newContract(
|
||||||
contracts.TEST_ERC20_CONTRACT_NAME,
|
contracts.MINTABLE_ERC20_CONTRACT_NAME,
|
||||||
["TestBase", 18]
|
["TestBase", "BASE", 18]
|
||||||
);
|
);
|
||||||
this.QUOTE = await contracts.newContract(
|
this.QUOTE = await contracts.newContract(
|
||||||
contracts.TEST_ERC20_CONTRACT_NAME,
|
contracts.MINTABLE_ERC20_CONTRACT_NAME,
|
||||||
["TestQuote", 18]
|
["TestQuote", "QUOTE", 18]
|
||||||
);
|
);
|
||||||
|
|
||||||
const allAccounts = await this.Web3.eth.getAccounts();
|
const allAccounts = await this.Web3.eth.getAccounts();
|
||||||
@@ -92,7 +92,7 @@ export class DVMContext {
|
|||||||
|
|
||||||
var lpFeeRateModel = await contracts.newContract(contracts.NAIVE_FEE_RATE_MODEL_NAME, [config.lpFeeRate])
|
var lpFeeRateModel = await contracts.newContract(contracts.NAIVE_FEE_RATE_MODEL_NAME, [config.lpFeeRate])
|
||||||
var mtFeeRateModel = await contracts.newContract(contracts.NAIVE_FEE_RATE_MODEL_NAME, [config.mtFeeRate])
|
var mtFeeRateModel = await contracts.newContract(contracts.NAIVE_FEE_RATE_MODEL_NAME, [config.mtFeeRate])
|
||||||
var DVMAddress = this.DVMFactory.methods.createDODOVenderMachine(
|
await this.DVMFactory.methods.createDODOVendorMachine(
|
||||||
this.Maintainer,
|
this.Maintainer,
|
||||||
this.BASE.options.address,
|
this.BASE.options.address,
|
||||||
this.QUOTE.options.address,
|
this.QUOTE.options.address,
|
||||||
@@ -102,7 +102,8 @@ export class DVMContext {
|
|||||||
config.k,
|
config.k,
|
||||||
config.gasPriceLimit).send(this.sendParam(this.Deployer))
|
config.gasPriceLimit).send(this.sendParam(this.Deployer))
|
||||||
|
|
||||||
this.DVM = contracts.getContractWithAddress(contracts.DVM_CONTROLLER_NAME, DVMAddress)
|
var vendorMachines = await this.DVMFactory.methods.getVendorMachine(this.BASE.options.address, this.QUOTE.options.address).call()
|
||||||
|
this.DVM = contracts.getContractWithAddress(contracts.DVM_CONTROLLER_NAME, vendorMachines[0])
|
||||||
|
|
||||||
console.log(log.blueText("[Init DVM context]"));
|
console.log(log.blueText("[Init DVM context]"));
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,7 @@ export class DVMContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDODOContext(
|
export async function getDVMContext(
|
||||||
config: DVMContextInitConfig = DefaultDVMContextInitConfig
|
config: DVMContextInitConfig = DefaultDVMContextInitConfig
|
||||||
): Promise<DVMContext> {
|
): Promise<DVMContext> {
|
||||||
var context = new DVMContext();
|
var context = new DVMContext();
|
||||||
|
|||||||
Reference in New Issue
Block a user