From 74ad9908807bf0ac69a6131d9a0fad64982c6587 Mon Sep 17 00:00:00 2001 From: owen05 Date: Fri, 27 Nov 2020 15:35:36 +0800 Subject: [PATCH] update v1.5 proxy --- .../DODOVendingMachine/impl/DVMFunding.sol | 3 +++ contracts/SmartRoute/DODOV1Proxy01.sol | 10 ++++----- contracts/SmartRoute/DODOV2Proxy01.sol | 2 +- contracts/lib/UniversalERC20.sol | 13 ++++++++++- test/DVM/funding.test.ts | 6 ++--- test/Proxy/proxy.dpp.test.ts | 8 +++---- test/Proxy/proxy.dvm.test.ts | 8 +++---- test/Route/Route.test.ts | 22 ++++++++++++------- test/utils-v1/EVM.ts | 1 + 9 files changed, 46 insertions(+), 27 deletions(-) diff --git a/contracts/DODOVendingMachine/impl/DVMFunding.sol b/contracts/DODOVendingMachine/impl/DVMFunding.sol index da3f465..d04b14f 100644 --- a/contracts/DODOVendingMachine/impl/DVMFunding.sol +++ b/contracts/DODOVendingMachine/impl/DVMFunding.sol @@ -53,6 +53,8 @@ contract DVMFunding is DVMVault { function sellShares( uint256 shareAmount, address to, + uint256 baseMinAmount, + uint256 quoteMinAmount, bytes calldata data ) external preventReentrant returns (uint256 baseAmount, uint256 quoteAmount) { (uint256 baseBalance, uint256 quoteBalance) = getVaultBalance(); @@ -60,6 +62,7 @@ contract DVMFunding is DVMVault { require(shareAmount <= _SHARES_[msg.sender], "DLP_NOT_ENOUGH"); baseAmount = baseBalance.mul(shareAmount).div(totalShares); quoteAmount = quoteBalance.mul(shareAmount).div(totalShares); + require(baseAmount >= baseMinAmount && quoteAmount >= quoteMinAmount,'WITHDRAW_DLP_NOT_ENOUGH'); _burn(msg.sender, shareAmount); _transferBaseOut(to, baseAmount); _transferQuoteOut(to, quoteAmount); diff --git a/contracts/SmartRoute/DODOV1Proxy01.sol b/contracts/SmartRoute/DODOV1Proxy01.sol index 5f6635c..678de37 100644 --- a/contracts/SmartRoute/DODOV1Proxy01.sol +++ b/contracts/SmartRoute/DODOV1Proxy01.sol @@ -21,7 +21,7 @@ contract DODOV1Proxy01 is Ownable { using SafeMath for uint256; using UniversalERC20 for IERC20; - address constant ETH_ADDRESS = 0x000000000000000000000000000000000000000E; + address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public dodoApprove; address public dodoSellHelper; address payable public _WETH_; @@ -66,7 +66,7 @@ contract DODOV1Proxy01 is Ownable { require(minReturnAmount > 0, 'DODOV1Proxy01: Min return should be bigger then 0.'); if (fromToken != ETH_ADDRESS) { - IDODOApprove(dodoApprove).claimTokens(fromToken, msg.sender, address(this),fromTokenAmount); + IDODOApprove(dodoApprove).claimTokens(fromToken, msg.sender, address(this), fromTokenAmount); } else { require(msg.value == fromTokenAmount, 'DODOV1Proxy01: ETH_AMOUNT_NOT_MATCH'); IWETH(_WETH_).deposit{value: fromTokenAmount}(); @@ -77,12 +77,12 @@ contract DODOV1Proxy01 is Ownable { if (directions[i] == 0) { address curDodoBase = IDODO(curDodoPair)._BASE_TOKEN_(); uint256 curAmountIn = IERC20(curDodoBase).balanceOf(address(this)); - IERC20(curDodoBase).universalApprove(curDodoPair, curAmountIn); + IERC20(curDodoBase).universalApproveMax(curDodoPair, curAmountIn); IDODO(curDodoPair).sellBaseToken(curAmountIn, 0, ""); } else { address curDodoQuote = IDODO(curDodoPair)._QUOTE_TOKEN_(); uint256 curAmountIn = IERC20(curDodoQuote).balanceOf(address(this)); - IERC20(curDodoQuote).universalApprove(curDodoPair, curAmountIn); + IERC20(curDodoQuote).universalApproveMax(curDodoPair, curAmountIn); uint256 canBuyBaseAmount = IDODOSellHelper(dodoSellHelper).querySellQuoteToken( curDodoPair, curAmountIn @@ -90,7 +90,6 @@ contract DODOV1Proxy01 is Ownable { IDODO(curDodoPair).buyBaseToken(canBuyBaseAmount, curAmountIn, ""); } } - IERC20(fromToken).universalTransfer(msg.sender, IERC20(fromToken).universalBalanceOf(address(this))); if (toToken == ETH_ADDRESS) { uint256 wethAmount = IWETH(_WETH_).balanceOf(address(this)); @@ -127,7 +126,6 @@ contract DODOV1Proxy01 is Ownable { require(success, 'DODOV1Proxy01: Contract Swap execution Failed'); - IERC20(fromToken).universalTransfer(msg.sender, IERC20(fromToken).universalBalanceOf(address(this))); returnAmount = IERC20(toToken).universalBalanceOf(address(this)); require(returnAmount >= minReturnAmount, 'DODOV1Proxy01: Return amount is not enough'); diff --git a/contracts/SmartRoute/DODOV2Proxy01.sol b/contracts/SmartRoute/DODOV2Proxy01.sol index 25bfaa5..d19506b 100644 --- a/contracts/SmartRoute/DODOV2Proxy01.sol +++ b/contracts/SmartRoute/DODOV2Proxy01.sol @@ -19,7 +19,7 @@ contract DODOV2Proxy01 is IDODOV2Proxy01 { using SafeMath for uint256; using UniversalERC20 for IERC20; - address constant ETH_ADDRESS = 0x000000000000000000000000000000000000000E; + address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address payable public _WETH_; address public dodoApprove; address public dodoSellHelper; diff --git a/contracts/lib/UniversalERC20.sol b/contracts/lib/UniversalERC20.sol index c85f1e9..583f826 100644 --- a/contracts/lib/UniversalERC20.sol +++ b/contracts/lib/UniversalERC20.sol @@ -16,7 +16,7 @@ library UniversalERC20 { using SafeERC20 for IERC20; IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000); - IERC20 private constant ETH_ADDRESS = IERC20(0x000000000000000000000000000000000000000E); + IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); function isETH(IERC20 token) internal pure returns (bool) { return (token == ZERO_ADDRESS || token == ETH_ADDRESS); @@ -48,6 +48,17 @@ library UniversalERC20 { } } + function universalApproveMax(IERC20 token, address to, uint256 amount) internal { + uint256 allowance = token.allowance(address(this), to); + if (allowance < amount) { + if (allowance > 0) { + token.safeApprove(to, 0); + } + token.safeApprove(to, uint(-1)); + } + } + + function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) { if (isETH(token)) { return who.balance; diff --git a/test/DVM/funding.test.ts b/test/DVM/funding.test.ts index 03f3770..0b45d47 100644 --- a/test/DVM/funding.test.ts +++ b/test/DVM/funding.test.ts @@ -154,11 +154,11 @@ describe("Funding", () => { var vaultShares = new BigNumber(await ctx.DVM.methods.balanceOf(lp).call()) var bob = ctx.SpareAccounts[5] - await ctx.DVM.methods.sellShares(vaultShares.div(2).toFixed(0), bob, "0x").send(ctx.sendParam(lp)) + await ctx.DVM.methods.sellShares(vaultShares.div(2).toFixed(0), 0, 0, bob, "0x").send(ctx.sendParam(lp)) assert.equal(await ctx.BASE.methods.balanceOf(bob).call(), decimalStr("5")) assert.equal(await ctx.QUOTE.methods.balanceOf(bob).call(), decimalStr("50")) - await ctx.DVM.methods.sellShares(vaultShares.div(2).toFixed(0), bob, "0x").send(ctx.sendParam(lp)) + await ctx.DVM.methods.sellShares(vaultShares.div(2).toFixed(0), 0, 0, bob, "0x").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")) }) @@ -170,7 +170,7 @@ describe("Funding", () => { var vaultShares = await ctx.DVM.methods.balanceOf(lp).call() var bob = ctx.SpareAccounts[5] - await ctx.DVM.methods.sellShares(vaultShares, bob, "0x").send(ctx.sendParam(lp)) + await ctx.DVM.methods.sellShares(vaultShares, 0, 0, bob, "0x").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/Proxy/proxy.dpp.test.ts b/test/Proxy/proxy.dpp.test.ts index 2a38eb2..91fd1f6 100644 --- a/test/Proxy/proxy.dpp.test.ts +++ b/test/Proxy/proxy.dpp.test.ts @@ -58,8 +58,8 @@ async function initCreateDPP(ctx: ProxyContext, token0: string, token1:string, t config.k, Math.floor(new Date().getTime()/1000 + 60 * 10) ).send(ctx.sendParam(project,ethValue)); - if(token0 == '0x000000000000000000000000000000000000000E') token0 = ctx.WETH.options.address; - if(token1 == '0x000000000000000000000000000000000000000E') token1 = ctx.WETH.options.address; + if(token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address; + if(token1 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token1 = ctx.WETH.options.address; var addr = await ctx.DPPFactory.methods._REGISTRY_(token0,token1,0).call(); return addr; } @@ -77,7 +77,7 @@ describe("DODOProxyV2.0", () => { 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")); DPP_DODO_USDT = contracts.getContractWithAddress(contracts.DPP_NAME,dpp_DODO_USDT); - dpp_WETH_USDT = await initCreateDPP(ctx,'0x000000000000000000000000000000000000000E',ctx.USDT.options.address,decimalStr("5"),mweiStr("30000"),"5",mweiStr("600")); + dpp_WETH_USDT = await initCreateDPP(ctx,'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',ctx.USDT.options.address,decimalStr("5"),mweiStr("30000"),"5",mweiStr("600")); DPP_WETH_USDT = contracts.getContractWithAddress(contracts.DPP_NAME,dpp_WETH_USDT); console.log("dpp_DODO_USDT:",dpp_DODO_USDT); console.log("dpp_WETH_USDT:",dpp_WETH_USDT); @@ -126,7 +126,7 @@ describe("DODOProxyV2.0", () => { it("createDPP - ETH", async () => { - var baseToken = '0x000000000000000000000000000000000000000E'; + var baseToken = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; var quoteToken = ctx.USDT.options.address; var baseAmount = decimalStr("5"); var quoteAmount = mweiStr("10000"); diff --git a/test/Proxy/proxy.dvm.test.ts b/test/Proxy/proxy.dvm.test.ts index fede2e7..33f5bfd 100644 --- a/test/Proxy/proxy.dvm.test.ts +++ b/test/Proxy/proxy.dvm.test.ts @@ -58,8 +58,8 @@ async function initCreateDVM(ctx: ProxyContext, token0: string, token1:string, t config.k, Math.floor(new Date().getTime()/1000 + 60 * 10) ).send(ctx.sendParam(project,ethValue)); - if(token0 == '0x000000000000000000000000000000000000000E') token0 = ctx.WETH.options.address; - if(token1 == '0x000000000000000000000000000000000000000E') token1 = ctx.WETH.options.address; + if(token0 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token0 = ctx.WETH.options.address; + if(token1 == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') token1 = ctx.WETH.options.address; var addr = await ctx.DVMFactory.methods._REGISTRY_(token0,token1,0).call(); return addr; } @@ -78,7 +78,7 @@ describe("DODOProxyV2.0", () => { await init(ctx); dvm_DODO_USDT = await initCreateDVM(ctx,ctx.DODO.options.address,ctx.USDT.options.address,decimalStr("100000"),mweiStr("30000"), "0",mweiStr("0.3")); DVM_DODO_USDT = contracts.getContractWithAddress(contracts.DVM_NAME,dvm_DODO_USDT); - dvm_WETH_USDT = await initCreateDVM(ctx,'0x000000000000000000000000000000000000000E',ctx.USDT.options.address,decimalStr("5"),mweiStr("30000"),"5",mweiStr("600")); + dvm_WETH_USDT = await initCreateDVM(ctx,'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',ctx.USDT.options.address,decimalStr("5"),mweiStr("30000"),"5",mweiStr("600")); DVM_WETH_USDT = contracts.getContractWithAddress(contracts.DVM_NAME,dvm_WETH_USDT); console.log("dvm_DODO_USDT:",dvm_DODO_USDT); console.log("dvm_WETH_USDT:",dvm_WETH_USDT); @@ -128,7 +128,7 @@ describe("DODOProxyV2.0", () => { it("createDVM - ETH", async () => { - var baseToken = '0x000000000000000000000000000000000000000E'; + var baseToken = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; var quoteToken = ctx.USDT.options.address; var baseAmount = decimalStr("5"); var quoteAmount = mweiStr("10000"); diff --git a/test/Route/Route.test.ts b/test/Route/Route.test.ts index 0e21924..7ab28e8 100644 --- a/test/Route/Route.test.ts +++ b/test/Route/Route.test.ts @@ -68,14 +68,14 @@ async function initWETH_USDC(ctx: DODOContext): Promise { let WETH_USDC = ctx.WETH_USDC; await ctx.approvePair(WETH, USDC, WETH_USDC.options.address, lp); - await ctx.mintToken(null, USDC, lp, decimalStr("0"), mweiStr("36000")); - await WETH.methods.deposit().send(ctx.sendParam(lp, '80')); + await ctx.mintToken(null, USDC, lp, decimalStr("0"), mweiStr("3600")); + await WETH.methods.deposit().send(ctx.sendParam(lp, '8')); await WETH_USDC.methods - .depositBaseTo(lp, decimalStr("80")) + .depositBaseTo(lp, decimalStr("8")) .send(ctx.sendParam(lp)); await WETH_USDC.methods - .depositQuoteTo(lp, mweiStr("36000")) + .depositQuoteTo(lp, mweiStr("3600")) .send(ctx.sendParam(lp)); } @@ -163,7 +163,8 @@ describe("Trader", () => { pairContract: ctx.DODO_USDT }]; - var tx = await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "directly swap") + await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "directly swap") + await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "directly swap") // console.log(tx.events['OrderHistory']); var a_DODO = await ctx.DODO.methods.balanceOf(trader).call() var a_USDT = await ctx.USDT.methods.balanceOf(trader).call() @@ -203,7 +204,8 @@ describe("Trader", () => { pairContract: ctx.USDT_USDC }]; - var tx = await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "tow hops swap") + var tx = await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "two hops swap") + var tx = await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "two hops swap") // console.log(tx.events['Swapped']); var a_DODO = await ctx.DODO.methods.balanceOf(trader).call() var a_USDC = await ctx.USDC.methods.balanceOf(trader).call() @@ -250,6 +252,7 @@ describe("Trader", () => { pairContract: ctx.WETH_USDC }]; + var tx = await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "three hops swap") var tx = await logGas(await calcRoute(ctx, decimalStr('10'), 0.1, routes, pairs), ctx.sendParam(trader), "three hops swap") console.log(tx.events['TestAmount']); var a_DODO = await ctx.DODO.methods.balanceOf(trader).call() @@ -286,6 +289,7 @@ describe("Trader", () => { pairContract: ctx.WETH_USDC }]; + var tx = await logGas(await calcRoute(ctx, decimalStr('1'), 0.1, routes, pairs), ctx.sendParam(trader, '1'), "wrap eth and directly swap") var tx = await logGas(await calcRoute(ctx, decimalStr('1'), 0.1, routes, pairs), ctx.sendParam(trader, '1'), "wrap eth and directly swap") var a_ETH = await ctx.Web3.eth.getBalance(trader) var a_WETH = await ctx.WETH.methods.balanceOf(trader).call() @@ -331,7 +335,8 @@ describe("Trader", () => { pairContract: ctx.USDT_USDC }]; - var tx = await logGas(await calcRoute(ctx, decimalStr('1'), 0.1, routes, pairs), ctx.sendParam(trader, '1'), "wrap eth and tow hops swap") + var tx = await logGas(await calcRoute(ctx, decimalStr('1'), 0.1, routes, pairs), ctx.sendParam(trader, '1'), "wrap eth and two hops swap") + var tx = await logGas(await calcRoute(ctx, decimalStr('1'), 0.1, routes, pairs), ctx.sendParam(trader, '1'), "wrap eth and two hops swap") var a_ETH = await ctx.Web3.eth.getBalance(trader) var a_WETH = await ctx.WETH.methods.balanceOf(trader).call() var a_USDT = await ctx.USDT.methods.balanceOf(trader).call() @@ -386,7 +391,8 @@ describe("Trader", () => { pairContract: ctx.WETH_USDC }]; - var tx = await logGas(await calcRoute(ctx, decimalStr('1000'), 0.1, routes, pairs), ctx.sendParam(trader), "unwrap eth and three hops swap") + var tx = await logGas(await calcRoute(ctx, decimalStr('100'), 0.1, routes, pairs), ctx.sendParam(trader), "unwrap eth and three hops swap") + var tx = await logGas(await calcRoute(ctx, decimalStr('100'), 0.1, routes, pairs), ctx.sendParam(trader), "unwrap eth and three hops swap") var a_ETH = await ctx.Web3.eth.getBalance(trader) var a_WETH = await ctx.WETH.methods.balanceOf(trader).call() var a_DODO = await ctx.DODO.methods.balanceOf(trader).call() diff --git a/test/utils-v1/EVM.ts b/test/utils-v1/EVM.ts index 75e071a..dac9d61 100644 --- a/test/utils-v1/EVM.ts +++ b/test/utils-v1/EVM.ts @@ -27,6 +27,7 @@ export class EVM { return this.snapshot(); } + public async snapshot(): Promise { return this.callJsonrpcMethod('evm_snapshot'); }