diff --git a/contracts/DODOPrivatePool/impl/DPPAdmin.sol b/contracts/DODOPrivatePool/impl/DPPAdmin.sol index 6e62b63..8ba077b 100644 --- a/contracts/DODOPrivatePool/impl/DPPAdmin.sol +++ b/contracts/DODOPrivatePool/impl/DPPAdmin.sol @@ -95,22 +95,26 @@ contract DPPAdmin is InitializableOwnable { uint256 newI, uint256 newK, uint256 baseOutAmount, - uint256 quoteOutAmount - ) external notFreezed { + uint256 quoteOutAmount, + uint256 minBaseReserve, + uint256 minQuoteReserve + ) external notFreezed returns (bool) { require( msg.sender == _OWNER_ || (msg.sender == IDODOApprove(_DODO_APPROVE_).getDODOProxy() && operator == _OPERATOR_), "RESET FORBIDDEN!" ); - IDPP(_DPP_).reset( + return IDPP(_DPP_).reset( msg.sender, newLpFeeRate, newMtFeeRate, newI, newK, baseOutAmount, - quoteOutAmount + quoteOutAmount, + minBaseReserve, + minQuoteReserve ); } diff --git a/contracts/DODOPrivatePool/impl/DPPVault.sol b/contracts/DODOPrivatePool/impl/DPPVault.sol index 5576a79..2e2f62f 100644 --- a/contracts/DODOPrivatePool/impl/DPPVault.sol +++ b/contracts/DODOPrivatePool/impl/DPPVault.sol @@ -78,8 +78,11 @@ contract DPPVault is DPPStorage { uint256 newI, uint256 newK, uint256 baseOutAmount, - uint256 quoteOutAmount - ) public preventReentrant onlyOwner { + uint256 quoteOutAmount, + uint256 minBaseReserve, + uint256 minQuoteReserve + ) public preventReentrant onlyOwner returns (bool) { + require(_BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve, "Reserve amount is not enough"); _LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate); _MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate); _I_.set(newI); @@ -89,6 +92,7 @@ contract DPPVault is DPPStorage { _resetTargetAndReserve(); _checkIK(); emit Reset(newLpFeeRate, newMtFeeRate); + return true; } function _setRState() internal { diff --git a/contracts/DODOPrivatePool/intf/IDPP.sol b/contracts/DODOPrivatePool/intf/IDPP.sol index c7c5b6b..a5c93d9 100644 --- a/contracts/DODOPrivatePool/intf/IDPP.sol +++ b/contracts/DODOPrivatePool/intf/IDPP.sol @@ -60,6 +60,8 @@ interface IDPP { uint256 newI, uint256 newK, uint256 baseOutAmount, - uint256 quoteOutAmount - ) external; + uint256 quoteOutAmount, + uint256 minBaseReserve, + uint256 minQuoteReserve + ) external returns (bool); } diff --git a/contracts/SmartRoute/DODOV2Proxy01.sol b/contracts/SmartRoute/DODOV2Proxy01.sol index 015ddb9..80eba6d 100644 --- a/contracts/SmartRoute/DODOV2Proxy01.sol +++ b/contracts/SmartRoute/DODOV2Proxy01.sol @@ -258,44 +258,42 @@ contract DODOV2Proxy01 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable function resetDODOPrivatePool( address dppAddress, - uint256 newLpFeeRate, - uint256 newMtFeeRate, - uint256 newI, - uint256 newK, - uint256 baseInAmount, - uint256 quoteInAmount, - uint256 baseOutAmount, - uint256 quoteOutAmount, + uint256[] memory paramList, //0 - newLpFeeRate, 1 - newMtFeeRate, 2 - newI, 3 - newK + uint256[] memory amountList, //0 - baseInAmount, 1 - quoteInAmount, 2 - baseOutAmount, 3- quoteOutAmount uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH + uint256 minBaseReserve, + uint256 minQuoteReserve, uint256 deadLine ) external override payable preventReentrant judgeExpired(deadLine) { _deposit( msg.sender, dppAddress, IDODOV2(dppAddress)._BASE_TOKEN_(), - baseInAmount, + amountList[0], flag == 1 ); _deposit( msg.sender, dppAddress, IDODOV2(dppAddress)._QUOTE_TOKEN_(), - quoteInAmount, + amountList[1], flag == 2 ); - IDODOV2(IDODOV2(dppAddress)._OWNER_()).reset( + require(IDODOV2(IDODOV2(dppAddress)._OWNER_()).reset( msg.sender, - newLpFeeRate, - newMtFeeRate, - newI, - newK, - baseOutAmount, - quoteOutAmount - ); + paramList[0], + paramList[1], + paramList[2], + paramList[3], + amountList[2], + amountList[3], + minBaseReserve, + minQuoteReserve + ), "Reset Failed"); - _withdraw(msg.sender, IDODOV2(dppAddress)._BASE_TOKEN_(), baseOutAmount, flag == 3); - _withdraw(msg.sender, IDODOV2(dppAddress)._QUOTE_TOKEN_(), quoteOutAmount, flag == 4); + _withdraw(msg.sender, IDODOV2(dppAddress)._BASE_TOKEN_(), amountList[2], flag == 3); + _withdraw(msg.sender, IDODOV2(dppAddress)._QUOTE_TOKEN_(), amountList[3], flag == 4); } // ============ Swap ============ diff --git a/contracts/SmartRoute/intf/IDODOV2.sol b/contracts/SmartRoute/intf/IDODOV2.sol index 9db1a69..4d8ab53 100644 --- a/contracts/SmartRoute/intf/IDODOV2.sol +++ b/contracts/SmartRoute/intf/IDODOV2.sol @@ -61,8 +61,10 @@ interface IDODOV2 { uint256 newI, uint256 newK, uint256 baseOutAmount, - uint256 quoteOutAmount - ) external; + uint256 quoteOutAmount, + uint256 minBaseReserve, + uint256 minQuoteReserve + ) external returns (bool); //========== CrowdPooling =========== diff --git a/contracts/SmartRoute/intf/IDODOV2Proxy01.sol b/contracts/SmartRoute/intf/IDODOV2Proxy01.sol index c64840c..0542eb9 100644 --- a/contracts/SmartRoute/intf/IDODOV2Proxy01.sol +++ b/contracts/SmartRoute/intf/IDODOV2Proxy01.sol @@ -86,15 +86,11 @@ interface IDODOV2Proxy01 is IDODOV1Proxy01 { function resetDODOPrivatePool( address dppAddress, - uint256 newLpFeeRate, - uint256 newMtFeeRate, - uint256 newI, - uint256 newK, - uint256 baseInAmount, - uint256 quoteInAmount, - uint256 baseOutAmount, - uint256 quoteOutAmount, + uint256[] memory paramList, //0 - newLpFeeRate, 1 - newMtFeeRate, 2 - newI, 3 - newK + uint256[] memory amountList, //0 - baseInAmount, 1 - quoteInAmount, 2 - baseOutAmount, 3 - quoteOutAmount uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH + uint256 minBaseReserve, + uint256 minQuoteReserve, uint256 deadLine ) external payable; diff --git a/test/DPP/reset.test.ts b/test/DPP/reset.test.ts index 577927f..a65fd6f 100644 --- a/test/DPP/reset.test.ts +++ b/test/DPP/reset.test.ts @@ -7,11 +7,11 @@ // import * as assert from 'assert'; -import { decimalStr } from '../utils/Converter'; +import { decimalStr, mweiStr } from '../utils/Converter'; import { DPPContext, getDPPContext } from '../utils/DPPContext'; import { assert } from 'chai'; import { EXTERNAL_VALUE_NAME, getContractWithAddress, MINTABLE_ERC20_CONTRACT_NAME, newContract } from '../utils/Contracts'; -import { sendParam } from '../../script/utils'; +// import { sendParam } from '../../script/utils'; const truffleAssert = require('truffle-assertions'); let lp: string; @@ -29,7 +29,7 @@ async function init(ctx: DPPContext): Promise { var kValue = decimalStr("0.2") await ctx.transferBaseToDPP(lp, baseAmount) await ctx.transferQuoteToDPP(lp, quoteAmount) - await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0").send(ctx.sendParam(ctx.Deployer)) + await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)) } describe("DPP Trader", () => { @@ -59,7 +59,7 @@ describe("DPP Trader", () => { var kValue = decimalStr("0.3") await ctx.transferBaseToDPP(lp, decimalStr("10")) await ctx.transferQuoteToDPP(lp, decimalStr("1000")) - await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0").send(ctx.sendParam(ctx.Deployer)) + await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)) var state = await ctx.DPP.methods.getPMMState().call() assert.equal(state.B, decimalStr("20")) @@ -77,7 +77,7 @@ describe("DPP Trader", () => { var mtFeeRate = decimalStr("0.02") var iValue = decimalStr("300") var kValue = decimalStr("0.3") - await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, decimalStr("1"), decimalStr("100")).send(ctx.sendParam(ctx.Deployer)) + await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, decimalStr("1"), decimalStr("100"), "0", "0").send(ctx.sendParam(ctx.Deployer)) var state = await ctx.DPP.methods.getPMMState().call() assert.equal(state.B, decimalStr("9")) @@ -95,7 +95,7 @@ describe("DPP Trader", () => { var mtFeeRate = decimalStr("0.02") var iValue = decimalStr("300") var kValue = decimalStr("0.3") - await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0").send(ctx.sendParam(ctx.Deployer)) + await ctx.DPP.methods.reset(lp, lpFeeRate, mtFeeRate, iValue, kValue, "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)) var state = await ctx.DPP.methods.getPMMState().call() assert.equal(state.B, decimalStr("10")) @@ -138,16 +138,16 @@ describe("DPP Trader", () => { it("i or k can not out of range", async () => { await truffleAssert.reverts( - ctx.DPP.methods.reset(lp, "0", "0", "0", decimalStr("1"), "0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE" + ctx.DPP.methods.reset(lp, "0", "0", "0", decimalStr("1"), "0", "0" ,"0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE" ) await truffleAssert.reverts( - ctx.DPP.methods.reset(lp, "0", "0", "10000000000000000000000000000000000000", decimalStr("1"), "0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE" + ctx.DPP.methods.reset(lp, "0", "0", "10000000000000000000000000000000000000", decimalStr("1"), "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)), "I_OUT_OF_RANGE" ) await truffleAssert.reverts( - ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), "1", "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE" + ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), "1", "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE" ) await truffleAssert.reverts( - ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), decimalStr("2"), "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE" + ctx.DPP.methods.reset(lp, "0", "0", decimalStr("1"), decimalStr("2"), "0", "0", "0", "0").send(ctx.sendParam(ctx.Deployer)), "K_OUT_OF_RANGE" ) }) }) diff --git a/test/Proxy/proxy.dpp.test.ts b/test/Proxy/proxy.dpp.test.ts index 136d634..f6eb813 100644 --- a/test/Proxy/proxy.dpp.test.ts +++ b/test/Proxy/proxy.dpp.test.ts @@ -153,15 +153,11 @@ describe("DODOProxyV2.0", () => { assert.equal(beforeState.Q0,mweiStr("30000")); await logGas(await ctx.DODOProxyV2.methods.resetDODOPrivatePool( dpp_DODO_USDT, - config.lpFeeRate, - config.mtFeeRate, - mweiStr("0.3"), - decimalStr("0.2"), - decimalStr("1000"), - mweiStr("1000"), - decimalStr("0"), - mweiStr("0"), + [config.lpFeeRate, config.mtFeeRate, mweiStr("0.3"), decimalStr("0.2")], + [decimalStr("1000"), mweiStr("1000"), decimalStr("0"), mweiStr("0")], 0, + decimalStr("100000"), + mweiStr("0"), Math.floor(new Date().getTime()/1000 + 60 * 10) ),ctx.sendParam(project),"resetDPP"); var afterState = await DPP_DODO_USDT.methods.getPMMState().call(); @@ -179,15 +175,11 @@ describe("DODOProxyV2.0", () => { var b_ETH = await ctx.Web3.eth.getBalance(project); var tx = await logGas(await ctx.DODOProxyV2.methods.resetDODOPrivatePool( dpp_WETH_USDT, - config.lpFeeRate, - config.mtFeeRate, - mweiStr("600"), - decimalStr("0.2"), - decimalStr("0"), - mweiStr("1000"), - decimalStr("1"), - mweiStr("0"), + [config.lpFeeRate, config.mtFeeRate, mweiStr("600"), decimalStr("0.2")], + [decimalStr("0"), mweiStr("1000"), decimalStr("1"), mweiStr("0")], 3, + decimalStr("0"), + mweiStr("0"), Math.floor(new Date().getTime()/1000 + 60 * 10) ),ctx.sendParam(project),"resetDPP-OutETH"); var afterState = await DPP_WETH_USDT.methods.getPMMState().call(); @@ -209,15 +201,11 @@ describe("DODOProxyV2.0", () => { var b_ETH = await ctx.Web3.eth.getBalance(project); var tx = await logGas(await ctx.DODOProxyV2.methods.resetDODOPrivatePool( dpp_WETH_USDT, - config.lpFeeRate, - config.mtFeeRate, - mweiStr("600"), - decimalStr("0.2"), - decimalStr("1"), - mweiStr("1000"), + [config.lpFeeRate, config.mtFeeRate, mweiStr("600"), decimalStr("0.2")], + [decimalStr("1"), mweiStr("1000"), decimalStr("0"), mweiStr("0")], + 1, decimalStr("0"), mweiStr("0"), - 1, Math.floor(new Date().getTime()/1000 + 60 * 10) ),ctx.sendParam(project,"1"),"resetDPP-InETH"); var afterState = await DPP_WETH_USDT.methods.getPMMState().call(); diff --git a/test/utils/DPPContext.ts b/test/utils/DPPContext.ts index d8366fc..ce8d575 100644 --- a/test/utils/DPPContext.ts +++ b/test/utils/DPPContext.ts @@ -92,6 +92,13 @@ export class DPPContext { this.Maintainer = allAccounts[1]; this.SpareAccounts = allAccounts.slice(2, 10); + await gasPriceSource.methods.init(this.Deployer, MAX_UINT256).send(this.sendParam(this.Deployer)) + await lpFeeRateModel.methods.init(this.DPP.options.address, config.lpFeeRate).send(this.sendParam(this.Deployer)) + await mtFeeRateModel.methods.init(this.DPP.options.address, config.mtFeeRate).send(this.sendParam(this.Deployer)) + + await kSource.methods.init(this.DPP.options.address, config.k).send(this.sendParam(this.Deployer)) + await iSource.methods.init(this.DPP.options.address, config.i).send(this.sendParam(this.Deployer)) + await this.DPP.methods.init( this.Deployer, this.Maintainer, @@ -105,13 +112,6 @@ export class DPPContext { permissionManager.options.address, ).send(this.sendParam(this.Deployer)) - await gasPriceSource.methods.init(this.Deployer, MAX_UINT256).send(this.sendParam(this.Deployer)) - await lpFeeRateModel.methods.init(this.DPP.options.address, config.lpFeeRate).send(this.sendParam(this.Deployer)) - await mtFeeRateModel.methods.init(this.DPP.options.address, config.mtFeeRate).send(this.sendParam(this.Deployer)) - - await kSource.methods.init(this.DPP.options.address, config.k).send(this.sendParam(this.Deployer)) - await iSource.methods.init(this.DPP.options.address, config.i).send(this.sendParam(this.Deployer)) - console.log(log.blueText("[Init DPP context]")); }