diff --git a/contracts/lib/DODOMath.sol b/contracts/lib/DODOMath.sol index c4a9c40..641b659 100644 --- a/contracts/lib/DODOMath.sol +++ b/contracts/lib/DODOMath.sol @@ -74,8 +74,16 @@ library DODOMath { // V0 = V1*(1+(sqrt-1)/2k) // sqrt = √(1+4kidelta/V1) // premium = 1+(sqrt-1)/2k - // uint256 sqrt = DecimalMath.multiMulWithDiv((4 * k).mul(i),delta,V1).add(DecimalMath.ONE2).sqrt(); - uint256 sqrt = (4 * k).mul(i).mul(delta).div(V1).add(DecimalMath.ONE2).sqrt(); + // uint256 sqrt = (4 * k).mul(i).mul(delta).div(V1).add(DecimalMath.ONE2).sqrt(); + uint256 sqrt; + uint256 ki = (4 * k).mul(i); + if(ki == 0 ) { + sqrt = DecimalMath.ONE; + }else if(ki * delta / ki == delta) { + sqrt = (ki * delta).div(V1).add(DecimalMath.ONE2).sqrt(); + }else { + sqrt = (4 * k).mul(i).div(V1).mul(delta).add(DecimalMath.ONE2).sqrt(); + } uint256 premium = DecimalMath.divFloor(sqrt.sub(DecimalMath.ONE), k * 2).add( DecimalMath.ONE ); @@ -129,8 +137,16 @@ library DODOMath { // Q2=Q1/(1+ideltaBQ1/Q0/Q0) // temp = ideltaBQ1/Q0/Q0 // Q1-Q2 = Q1*(temp/(1+temp)) - // uint256 temp = DecimalMath.multiMulWithDiv(i.mul(delta),V1,V0).div(V0); - uint256 temp = i.mul(delta).mul(V1).div(V0.mul(V0)); + // uint256 temp = i.mul(delta).mul(V1).div(V0.mul(V0)); + uint256 temp; + uint256 idelta = i.mul(delta); + if(idelta == 0) { + temp = 0; + }else if(idelta * V1 / idelta == V1) { + temp = (idelta * V1).div(V0.mul(V0)); + }else { + temp = delta.mul(V1).div(V0).mul(i).div(V0); + } return V1.mul(temp).div(temp.add(DecimalMath.ONE)); } diff --git a/contracts/lib/DecimalMath.sol b/contracts/lib/DecimalMath.sol index cb60aff..542bc77 100644 --- a/contracts/lib/DecimalMath.sol +++ b/contracts/lib/DecimalMath.sol @@ -45,10 +45,4 @@ library DecimalMath { function reciprocalCeil(uint256 target) internal pure returns (uint256) { return uint256(10**36).divCeil(target); } - - function multiMulWithDiv(uint256 x, uint256 y, uint256 z) internal pure returns (uint256) { - uint256 a = x.div(z); uint256 b = x.mod(z); // x = a * z + b - uint256 c = y.div(z); uint256 d = y.mod(z); // y = c * z + d - return a.mul(b).mul(z).add(a.mul(d)).add(b.mul(c)).add(b.mul(d).div(z)); - } } diff --git a/contracts/lib/SafeMath.sol b/contracts/lib/SafeMath.sol index d739497..dc5bb8d 100644 --- a/contracts/lib/SafeMath.sol +++ b/contracts/lib/SafeMath.sol @@ -32,11 +32,6 @@ library SafeMath { return a / b; } - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - require(b > 0, "MOD_ERROR"); - return a % b; - } - function divCeil(uint256 a, uint256 b) internal pure returns (uint256) { uint256 quotient = div(a, b); uint256 remainder = a - quotient * b; diff --git a/test/Proxy/proxy.classical.test.ts b/test/Proxy/proxy.classical.test.ts index bbb731b..caf6cf2 100644 --- a/test/Proxy/proxy.classical.test.ts +++ b/test/Proxy/proxy.classical.test.ts @@ -84,7 +84,8 @@ async function initWETH_USDC(ctx: DODOContext): Promise { //mock sdk logic async function calcRoute(ctx: ProxyContext, fromTokenAmount: string, slippage: number, routes: any[], pairs: any[]) { let swapAmount = fromTokenAmount - let directions: number[] = [] + let tmpDirections: number[] = [] + let strDirections: string = '' let dodoPairs: string[] = [] @@ -93,23 +94,23 @@ async function calcRoute(ctx: ProxyContext, fromTokenAmount: string, slippage: n dodoPairs.push(curPair.pair) let curContact = pairs[i].pairContract if (routes[i].address == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') { - directions[i] = 0; + tmpDirections[i] = 0; swapAmount = await curContact.methods.querySellBaseToken(swapAmount).call(); - // console.log(i + "-swapAmount:", swapAmount); } else if (curPair.base === routes[i].address) { - directions[i] = 0; + tmpDirections[i] = 0; swapAmount = await curContact.methods.querySellBaseToken(swapAmount).call(); - // console.log(i + "-swapAmount:", swapAmount); } else { - directions[i] = 1; + tmpDirections[i] = 1; swapAmount = await ctx.DODOSellHelper.methods.querySellQuoteToken(curPair.pair, swapAmount).call(); - // console.log(i + "-swapAmount:", swapAmount); } } + for (let i = tmpDirections.length - 1; i >= 0; i--) { + strDirections += tmpDirections[i].toString() + } + let toAmount = new BigNumber(swapAmount).multipliedBy(1 - slippage).toFixed(0, BigNumber.ROUND_DOWN) - // console.log("minAmount:", toAmount); let deadline = Math.floor(new Date().getTime() / 1000 + 60 * 10); return ctx.DODOProxyV2.methods.dodoSwapV1( @@ -118,7 +119,7 @@ async function calcRoute(ctx: ProxyContext, fromTokenAmount: string, slippage: n fromTokenAmount, toAmount, dodoPairs, - directions, + tmpDirections, deadline ) } @@ -173,7 +174,7 @@ describe("AddLiquidity", () => { console.log("dodo_lp:" + dodo_lp + " usdt_lp:" + usdt_lp); await ctxV1.DODO.methods.approve(ctxV2.DODOApprove.options.address, MAX_UINT256).send(ctxV2.sendParam(trader)); await ctxV1.USDT.methods.approve(ctxV2.DODOApprove.options.address, MAX_UINT256).send(ctxV2.sendParam(trader)); - var tx = await logGas(await ctxV2.DODOProxyV2.methods.addLiquidityToV1( + await logGas(await ctxV2.DODOProxyV2.methods.addLiquidityToV1( trader, ctxV1.DODO_USDT.options.address, decimalStr("100"), @@ -203,7 +204,7 @@ describe("AddLiquidity", () => { console.log("Before WETH:" + fromWei(b_WETH, 'ether') + "; USDC:" + fromWei(b_USDC, 'mwei') + "; ETH:" + fromWei(b_ETH, 'ether')); console.log("weth_lp:" + weth_lp + " usdc_lp:" + usdc_lp); await ctxV1.USDC.methods.approve(ctxV2.DODOApprove.options.address, MAX_UINT256).send(ctxV2.sendParam(trader)); - var tx = await logGas(await ctxV2.DODOProxyV2.methods.addLiquidityToV1( + await logGas(await ctxV2.DODOProxyV2.methods.addLiquidityToV1( trader, ctxV1.WETH_USDC.options.address, decimalStr("1"), @@ -246,8 +247,8 @@ describe("AddLiquidity", () => { pairContract: ctxV1.DODO_USDT }]; - await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "directly swap") - await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "directly swap") + await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "directly swap first") + await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "directly swap second") // console.log(tx.events['OrderHistory']); var a_DODO = await ctxV1.DODO.methods.balanceOf(trader).call() var a_USDT = await ctxV1.USDT.methods.balanceOf(trader).call() @@ -288,8 +289,8 @@ describe("AddLiquidity", () => { pairContract: ctxV1.USDT_USDC }]; - var tx = await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "two hops swap") - var tx = await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "two hops swap") + await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "two hops swap first") + await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "two hops swap second") // console.log(tx.events['Swapped']); var a_DODO = await ctxV1.DODO.methods.balanceOf(trader).call() var a_USDC = await ctxV1.USDC.methods.balanceOf(trader).call() @@ -337,8 +338,8 @@ describe("AddLiquidity", () => { pairContract: ctxV1.WETH_USDC }]; - var tx = await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "three hops swap") - var tx = await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "three hops swap") + var tx = await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "three hops swap first") + var tx = await logGas(await calcRoute(ctxV2, decimalStr('10'), 0.1, routes, pairs), ctxV2.sendParam(trader), "three hops swap second") console.log(tx.events['TestAmount']); var a_DODO = await ctxV1.DODO.methods.balanceOf(trader).call() var a_WETH = await ctxV1.WETH.methods.balanceOf(trader).call() @@ -375,8 +376,8 @@ describe("AddLiquidity", () => { pairContract: ctxV1.WETH_USDC }]; - var tx = await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and directly swap") - var tx = await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and directly swap") + await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and directly swap first") + await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and directly swap second") var a_ETH = await ctxV1.Web3.eth.getBalance(trader) var a_WETH = await ctxV1.WETH.methods.balanceOf(trader).call() var a_USDC = await ctxV1.USDC.methods.balanceOf(trader).call() @@ -422,8 +423,8 @@ describe("AddLiquidity", () => { pairContract: ctxV1.USDT_USDC }]; - var tx = await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and two hops swap") - var tx = await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and two hops swap") + await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and two hops swap first") + await logGas(await calcRoute(ctxV2, decimalStr('1'), 0.1, routes, pairs), ctxV2.sendParam(trader, '1'), "wrap eth and two hops swap second") var a_ETH = await ctxV1.Web3.eth.getBalance(trader) var a_WETH = await ctxV1.WETH.methods.balanceOf(trader).call() var a_USDT = await ctxV1.USDT.methods.balanceOf(trader).call() @@ -479,8 +480,8 @@ describe("AddLiquidity", () => { pairContract: ctxV1.WETH_USDC }]; - var tx = await logGas(await calcRoute(ctxV2, decimalStr('100'), 0.1, routes, pairs), ctxV2.sendParam(trader), "unwrap eth and three hops swap") - var tx = await logGas(await calcRoute(ctxV2, decimalStr('100'), 0.1, routes, pairs), ctxV2.sendParam(trader), "unwrap eth and three hops swap") + var tx = await logGas(await calcRoute(ctxV2, decimalStr('100'), 0.1, routes, pairs), ctxV2.sendParam(trader), "unwrap eth and three hops swap first") + var tx = await logGas(await calcRoute(ctxV2, decimalStr('100'), 0.1, routes, pairs), ctxV2.sendParam(trader), "unwrap eth and three hops swap second") var a_ETH = await ctxV1.Web3.eth.getBalance(trader) var a_WETH = await ctxV1.WETH.methods.balanceOf(trader).call() var a_DODO = await ctxV1.DODO.methods.balanceOf(trader).call() diff --git a/test/Proxy/proxy.cp.test.ts b/test/Proxy/proxy.cp.test.ts index 5aefc15..9322903 100644 --- a/test/Proxy/proxy.cp.test.ts +++ b/test/Proxy/proxy.cp.test.ts @@ -39,7 +39,7 @@ async function initCreateCP(ctx: ProxyContext, token0: string, token1: string, t timeLine, valueList, Math.floor(new Date().getTime() / 1000 + 60 * 10) - ).send(ctx.sendParam(project)); + ).send(ctx.sendParam(project, "0.2")); 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(); @@ -121,7 +121,7 @@ describe("DODOProxyV2.0", () => { timeLine, valueList, Math.floor(new Date().getTime() / 1000 + 60 * 10) - ), ctx.sendParam(project), "createCP"); + ), ctx.sendParam(project, "0.2"), "createCP"); var addrs = await ctx.CPFactory.methods.getCrowdPooling(baseToken, quoteToken).call(); assert.equal( await ctx.DODO.methods.balanceOf(addrs[1]).call(), diff --git a/test/Proxy/proxy.mix.test.ts b/test/Proxy/proxy.mix.test.ts index 8a05941..df6e1a7 100644 --- a/test/Proxy/proxy.mix.test.ts +++ b/test/Proxy/proxy.mix.test.ts @@ -47,7 +47,6 @@ async function initCreateDPP(ctx: ProxyContext, token0: string, token1: string, token0Amount, token1Amount, config.lpFeeRate, - config.mtFeeRate, i, config.k, Math.floor(new Date().getTime() / 1000 + 60 * 10) @@ -67,7 +66,6 @@ async function initCreateDVM(ctx: ProxyContext, token0: string, token1: string, token0Amount, token1Amount, config.lpFeeRate, - config.mtFeeRate, i, config.k, Math.floor(new Date().getTime() / 1000 + 60 * 10) @@ -90,8 +88,8 @@ describe("DODOProxyV2.0", () => { ); ctx = await getProxyContext(ETH.options.address); await init(ctx); - dpp_DODO_USDT = await initCreateDPP(ctx, ctx.DODO.options.address, ctx.USDT.options.address, decimalStr("100000"), mweiStr("30000"), "0", mweiStr("0.3")); - dvm_WETH_USDT = await initCreateDVM(ctx, '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', ctx.USDT.options.address, decimalStr("5"), mweiStr("30000"), "5", mweiStr("600")); + dpp_DODO_USDT = await initCreateDPP(ctx, ctx.DODO.options.address, ctx.USDT.options.address, decimalStr("100000"), mweiStr("20000"), "0", mweiStr("0.2")); + dvm_WETH_USDT = await initCreateDVM(ctx, '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', ctx.USDT.options.address, decimalStr("5"), mweiStr("3000"), "5", mweiStr("600")); console.log("dpp_DODO_USDT:", dpp_DODO_USDT); console.log("dvm_WETH_USDT:", dvm_WETH_USDT); }); @@ -114,11 +112,8 @@ describe("DODOProxyV2.0", () => { dpp_DODO_USDT, dvm_WETH_USDT ] - var directions = [ - 0, - 1 - ] - var tx = await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2TokenToToken( + var directions = 2 + await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2TokenToToken( trader, ctx.DODO.options.address, ctx.WETH.options.address, @@ -133,7 +128,7 @@ describe("DODOProxyV2.0", () => { console.log("b_DOOD:" + b_DOOD + " a_DODO:" + a_DOOD); console.log("b_WETH:" + b_WETH + " a_WETH:" + a_WETH); assert.equal(a_DOOD, decimalStr("500")); - assert.equal(a_WETH, "40729644076866177"); + assert.equal(a_WETH, "129932374904193666"); }); it("swap - two jump - inETH", async () => { @@ -144,11 +139,8 @@ describe("DODOProxyV2.0", () => { dvm_WETH_USDT, dpp_DODO_USDT ] - var directions = [ - 0, - 1 - ] - var tx = await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2ETHToToken( + var directions = 2 + await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2ETHToToken( trader, ctx.DODO.options.address, 1, @@ -162,7 +154,7 @@ describe("DODOProxyV2.0", () => { console.log("b_DOOD:" + b_DOOD + " a_DODO:" + a_DOOD); console.log("b_WETH:" + b_WETH + " a_WETH:" + a_WETH); console.log("b_ETH:" + b_ETH + " a_ETH:" + a_ETH); - assert.equal(a_DOOD, "10214032255413753721651"); + assert.equal(a_DOOD, "3589987832148472935171"); }); @@ -175,10 +167,7 @@ describe("DODOProxyV2.0", () => { dpp_DODO_USDT, dvm_WETH_USDT ] - var directions = [ - 0, - 1 - ] + var directions = 2 var tx = await logGas(await ctx.DODOProxyV2.methods.dodoSwapV2TokenToETH( trader, ctx.DODO.options.address, @@ -197,7 +186,7 @@ describe("DODOProxyV2.0", () => { assert.equal(a_DOOD, decimalStr("90000")); assert.equal( tx.events['OrderHistory'].returnValues['returnAmount'], - "711081782556285356" + "2131271397594357833" ) }); }); diff --git a/truffle-test.sh b/truffle-test.sh index ed75834..5393068 100644 --- a/truffle-test.sh +++ b/truffle-test.sh @@ -29,6 +29,4 @@ fi if [ "$1"x = "route"x ] then truffle test ./test/Route/route.test.ts -fi - - \ No newline at end of file +fi \ No newline at end of file