From f66a90d7b26d8068b0a6227d0f18bae9c392d04b Mon Sep 17 00:00:00 2001 From: mingda Date: Thu, 5 Nov 2020 14:10:59 +0800 Subject: [PATCH] fix test --- .../DODOVendorMachine/impl/DVMFunding.sol | 26 +++++++++------ .../DODOVendorMachine/impl/DVMStorage.sol | 8 ++++- .../DODOVendorMachine/impl/DVMTrader.sol | 10 +++--- contracts/SmartRoute/SmartRoute.sol | 4 ++- test/DVM/funding.test.ts | 13 ++++++++ test/DVM/trader.test.ts | 6 ++-- test/utils/Contracts.ts | 5 +-- test/utils/DVMContext.ts | 33 ++++++++++--------- 8 files changed, 68 insertions(+), 37 deletions(-) diff --git a/contracts/DODOVendorMachine/impl/DVMFunding.sol b/contracts/DODOVendorMachine/impl/DVMFunding.sol index 65be8bb..346cc72 100644 --- a/contracts/DODOVendorMachine/impl/DVMFunding.sol +++ b/contracts/DODOVendorMachine/impl/DVMFunding.sol @@ -12,7 +12,7 @@ import {DVMStorage} from "./DVMStorage.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol"; contract DVMFunding is DVMStorage { - function buyShares(address account) external returns (uint256) { + function buyShares(address to) external returns (uint256) { uint256 baseInput = _VAULT_.getBaseInput(); uint256 quoteInput = _VAULT_.getQuoteInput(); require(baseInput > 0, "NO_BASE_INPUT"); @@ -42,22 +42,28 @@ contract DVMFunding is DVMStorage { mintAmount = baseInput; } } - _VAULT_.mint(account, mintAmount); + _VAULT_.mint(to, mintAmount); _VAULT_.sync(); } - function sellShares( - address account, - address to, - uint256 amount - ) external returns (uint256) { - require(msg.sender == account, "PERMISSION_DENY"); - require(_VAULT_.balanceOf(account) >= amount, "SHARES_NOT_ENOUGH"); + function sellShares(address to, uint256 amount) external returns (uint256) { + require(_VAULT_.balanceOf(msg.sender) >= amount, "SHARES_NOT_ENOUGH"); (uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance(); uint256 totalShares = _VAULT_.totalSupply(); - _VAULT_.burn(account, amount); + _VAULT_.burn(msg.sender, amount); _VAULT_.transferBaseOut(to, baseBalance.mul(amount).div(totalShares)); _VAULT_.transferQuoteOut(to, quoteBalance.mul(amount).div(totalShares)); _VAULT_.sync(); } + + function retrieve(address to) external { + (uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance(); + (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); + if (baseBalance.sub(baseReserve) > 0) { + _VAULT_.transferBaseOut(to, baseBalance.sub(baseReserve)); + } + if (quoteBalance.sub(quoteReserve) > 0) { + _VAULT_.transferQuoteOut(to, quoteBalance.sub(quoteReserve)); + } + } } diff --git a/contracts/DODOVendorMachine/impl/DVMStorage.sol b/contracts/DODOVendorMachine/impl/DVMStorage.sol index 0d5f314..848fc2f 100644 --- a/contracts/DODOVendorMachine/impl/DVMStorage.sol +++ b/contracts/DODOVendorMachine/impl/DVMStorage.sol @@ -58,7 +58,13 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { // ============ Helper Functions ============ - function getBase0(uint256 baseAmount, uint256 quoteAmount) public view returns (uint256) { + function calculateBase0(uint256 baseAmount, uint256 quoteAmount) public view returns (uint256) { + uint256 fairAmount = DecimalMath.divFloor(quoteAmount, _I_); + return DODOMath._SolveQuadraticFunctionForTarget(baseAmount, _K_, fairAmount); + } + + function getBase0() public view returns (uint256) { + (uint256 baseAmount, uint256 quoteAmount) = _VAULT_.getVaultReserve(); uint256 fairAmount = DecimalMath.divFloor(quoteAmount, _I_); return DODOMath._SolveQuadraticFunctionForTarget(baseAmount, _K_, fairAmount); } diff --git a/contracts/DODOVendorMachine/impl/DVMTrader.sol b/contracts/DODOVendorMachine/impl/DVMTrader.sol index c212df4..52d0286 100644 --- a/contracts/DODOVendorMachine/impl/DVMTrader.sol +++ b/contracts/DODOVendorMachine/impl/DVMTrader.sol @@ -49,7 +49,7 @@ contract DVMTrader is DVMStorage { bytes calldata data ) external { (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); - uint256 B0 = getBase0(baseReserve, quoteReserve); + uint256 B0 = calculateBase0(baseReserve, quoteReserve); uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(assetTo, quoteAmount); uint256 baseMtFee = DecimalMath.mulCeil(baseAmount, mtFeeRate); @@ -63,7 +63,7 @@ contract DVMTrader is DVMStorage { IExternalCall(call).DVMCall(data); (uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance(); - uint256 newB0 = getBase0(baseBalance, quoteBalance); + uint256 newB0 = calculateBase0(baseBalance, quoteBalance); require(newB0 >= B0, "FLASH_LOAN_FAILED"); _VAULT_.sync(); } @@ -74,7 +74,7 @@ contract DVMTrader is DVMStorage { returns (uint256 receiveQuoteAmount, uint256 mtFee) { (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); - uint256 B0 = getBase0(baseReserve, quoteReserve); + uint256 B0 = calculateBase0(baseReserve, quoteReserve); uint256 B1 = baseReserve.add(payBaseAmount); require(B0 >= B1, "DODO_BASE_BALANCE_NOT_ENOUGH"); @@ -94,7 +94,7 @@ contract DVMTrader is DVMStorage { returns (uint256 receiveBaseAmount, uint256 mtFee) { (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); - uint256 B0 = getBase0(baseReserve, quoteReserve); + uint256 B0 = calculateBase0(baseReserve, quoteReserve); uint256 fairAmount = DecimalMath.divFloor(payQuoteAmount, _I_); uint256 newBaseReserve = DODOMath._SolveQuadraticFunctionForTrade( @@ -114,7 +114,7 @@ contract DVMTrader is DVMStorage { function getMidPrice() public view returns (uint256 midPrice) { (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); - uint256 B0 = getBase0(baseReserve, quoteReserve); + uint256 B0 = calculateBase0(baseReserve, quoteReserve); uint256 offsetRatio = DecimalMath.ONE.mul(B0).div(baseReserve).mul(B0).div(baseReserve); uint256 offset = DecimalMath.ONE.sub(_K_).add(DecimalMath.mulFloor(offsetRatio, _K_)); diff --git a/contracts/SmartRoute/SmartRoute.sol b/contracts/SmartRoute/SmartRoute.sol index d7949bf..5e0d958 100644 --- a/contracts/SmartRoute/SmartRoute.sol +++ b/contracts/SmartRoute/SmartRoute.sol @@ -95,6 +95,8 @@ contract SmartRoute is Ownable { adjustedQuoteAmount ); - return DVM(DVMAddress).buyShares(to); + shares = DVM(DVMAddress).buyShares(to); + + return shares; } } diff --git a/test/DVM/funding.test.ts b/test/DVM/funding.test.ts index 0f90ac4..93b7625 100644 --- a/test/DVM/funding.test.ts +++ b/test/DVM/funding.test.ts @@ -141,4 +141,17 @@ describe("Funding", () => { assert.equal(await ctx.Vault.methods.balanceOf(trader).call(), "499999999999999990") }) }); + + describe("sell shares", () => { + it("sell shares", async () => { + await ctx.Route.methods + .depositToDVM(ctx.DVM.options.address, lp, decimalStr("10"), decimalStr("100")) + .send(ctx.sendParam(lp)); + var vaultShares = await ctx.Vault.methods.balanceOf(lp).call() + var bob = ctx.SpareAccounts[0] + await ctx.DVM.methods.sellShares(bob, vaultShares).send(ctx.sendParam(lp)) + assert.equal(await ctx.BASE.methods.balanceOf(bob).call(), decimalStr("10")) + assert.equal(await ctx.QUOTE.methods.balanceOf(bob).call(), decimalStr("100")) + }) + }) }); diff --git a/test/DVM/trader.test.ts b/test/DVM/trader.test.ts index 6580bc0..e63d7e9 100644 --- a/test/DVM/trader.test.ts +++ b/test/DVM/trader.test.ts @@ -53,11 +53,11 @@ describe("Trader", () => { describe("trade", () => { it("buy & sell", async () => { - console.log("BASE0 before buy", await ctx.DVM.methods._BASE0_().call()) + console.log("BASE0 before buy", await ctx.DVM.methods.getBase0().call()) // buy await logGas(ctx.Route.methods.sellQuoteOnDVM(ctx.DVM.options.address, trader, decimalStr("200"), decimalStr("1")), ctx.sendParam(trader), "buy base token") - console.log("BASE0 after buy", await ctx.DVM.methods._BASE0_().call()) + console.log("BASE0 after buy", await ctx.DVM.methods.getBase0().call()) // trader balances assert.equal( await ctx.BASE.methods.balanceOf(trader).call(), @@ -88,7 +88,7 @@ describe("Trader", () => { // sell await logGas(ctx.Route.methods.sellBaseOnDVM(ctx.DVM.options.address, trader, decimalStr("1"), decimalStr("100")), ctx.sendParam(trader), "sell base token") - console.log("BASE0 after sell", await ctx.DVM.methods._BASE0_().call()) + console.log("BASE0 after sell", await ctx.DVM.methods.getBase0().call()) // trader balances assert.equal( await ctx.BASE.methods.balanceOf(trader).call(), diff --git a/test/utils/Contracts.ts b/test/utils/Contracts.ts index fae2178..f781f46 100644 --- a/test/utils/Contracts.ts +++ b/test/utils/Contracts.ts @@ -29,10 +29,11 @@ export const LOCKED_TOKEN_VAULT_CONTRACT_NAME = "LockedTokenVault" export const DODO_MINE_NAME = "DODOMine" export const DODO_MINE_READER_NAME = "DODOMineReader" export const DVM_VAULT_NAME = "DVMVault" -export const DVM_CONTROLLER_NAME = "DVMController" +export const DVM_NAME = "DVM" export const DVM_FACTORY_NAME = "DVMFactory" export const SMART_ROUTE_NAME = "SmartRoute" -export const NAIVE_FEE_RATE_MODEL_NAME = "NaiveFeeRateModel" +export const CONST_FEE_RATE_MODEL_NAME = "ConstFeeRateModel" +export const PERMISSION_MANAGER_NAME = "PermissionManager" interface ContractJson { abi: any; diff --git a/test/utils/DVMContext.ts b/test/utils/DVMContext.ts index 17d5d7d..2f35a1e 100644 --- a/test/utils/DVMContext.ts +++ b/test/utils/DVMContext.ts @@ -10,7 +10,7 @@ import Web3 from 'web3'; import { Contract } from 'web3-eth-contract'; import * as contracts from './Contracts'; -import { decimalStr, gweiStr, MAX_UINT256 } from './Converter'; +import { decimalStr, MAX_UINT256 } from './Converter'; import { EVM, getDefaultWeb3 } from './EVM'; import * as log from './Log'; @@ -24,7 +24,6 @@ export interface DVMContextInitConfig { mtFeeRate: string; k: string; i: string; - gasPriceLimit: string; } /* @@ -45,7 +44,6 @@ export let DefaultDVMContextInitConfig = { mtFeeRate: decimalStr("0.001"), k: decimalStr("0.1"), i: decimalStr("100"), - gasPriceLimit: gweiStr("100"), }; export class DVMContext { @@ -72,9 +70,16 @@ export class DVMContext { contracts.CLONE_FACTORY_CONTRACT_NAME ); var vaultTemplate = await contracts.newContract(contracts.DVM_VAULT_NAME) - var controllerTemplate = await contracts.newContract(contracts.DVM_CONTROLLER_NAME) + var dvmTemplate = await contracts.newContract(contracts.DVM_NAME) + var feeRateModelTemplate = await contracts.newContract(contracts.CONST_FEE_RATE_MODEL_NAME) + var permissionManagerTemplate = await contracts.newContract(contracts.PERMISSION_MANAGER_NAME) - 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, + dvmTemplate.options.address, + feeRateModelTemplate.options.address, + permissionManagerTemplate.options.address]) this.BASE = await contracts.newContract( contracts.MINTABLE_ERC20_CONTRACT_NAME, @@ -90,23 +95,21 @@ export class DVMContext { this.Maintainer = allAccounts[1]; this.SpareAccounts = allAccounts.slice(2, 10); - 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]) - await this.DVMFactory.methods.createDODOVendorMachine( - this.Maintainer, + await this.DVMFactory.methods.createStandardDODOVendorMachine( this.BASE.options.address, this.QUOTE.options.address, - lpFeeRateModel.options.address, - mtFeeRateModel.options.address, + config.lpFeeRate, + config.mtFeeRate, config.i, - config.k, - config.gasPriceLimit).send(this.sendParam(this.Deployer)) + config.k + ).send(this.sendParam(this.Deployer)) 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]) - + this.DVM = contracts.getContractWithAddress(contracts.DVM_NAME, vendorMachines[0]) this.Vault = contracts.getContractWithAddress(contracts.DVM_VAULT_NAME, await this.DVM.methods._VAULT_().call()) + await this.DVM.methods.setMaintainer(this.Maintainer).send(this.sendParam(this.Deployer)) + console.log(log.blueText("[Init DVM context]")); }