diff --git a/contracts/DODOVendingMachine/impl/DVMFunding.sol b/contracts/DODOVendingMachine/impl/DVMFunding.sol index 0326a92..de3262e 100644 --- a/contracts/DODOVendingMachine/impl/DVMFunding.sol +++ b/contracts/DODOVendingMachine/impl/DVMFunding.sol @@ -50,8 +50,8 @@ contract DVMFunding is DVMVault { // 在提币的时候向下取整。因此永远不会出现,balance为0但totalsupply不为0的情况 // 但有可能出现,reserve>0但totalSupply=0的场景 if (totalSupply == 0) { - shares = baseBalance.sub(10**3); // 以免出现balance很大但shares很小的情况 - _mint(address(0), 10**3); + 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 +62,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]); diff --git a/test/Proxy/proxy.cp.test.ts b/test/Proxy/proxy.cp.test.ts new file mode 100644 index 0000000..1511eb4 --- /dev/null +++ b/test/Proxy/proxy.cp.test.ts @@ -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 { + 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 { + 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")); + }); + + }); +}); diff --git a/test/utils-v1/ProxyContextV1.ts b/test/utils-v1/ProxyContextV1.ts index 61988ba..e239e9d 100644 --- a/test/utils-v1/ProxyContextV1.ts +++ b/test/utils-v1/ProxyContextV1.ts @@ -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)); diff --git a/test/utils/Contracts.ts b/test/utils/Contracts.ts index 988f931..d121814 100644 --- a/test/utils/Contracts.ts +++ b/test/utils/Contracts.ts @@ -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; diff --git a/test/utils/ProxyContextV2.ts b/test/utils/ProxyContextV2.ts index 759ed25..98bcdbf 100644 --- a/test/utils/ProxyContextV2.ts +++ b/test/utils/ProxyContextV2.ts @@ -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, diff --git a/truffle-test.sh b/truffle-test.sh index 27aeca5..ed75834 100644 --- a/truffle-test.sh +++ b/truffle-test.sh @@ -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