add reset protection mechanism

This commit is contained in:
owen05
2020-12-18 11:27:45 +08:00
parent 83c8bbaa85
commit 0c77f9c9fe
9 changed files with 72 additions and 78 deletions

View File

@@ -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
);
}

View File

@@ -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 {

View File

@@ -60,6 +60,8 @@ interface IDPP {
uint256 newI,
uint256 newK,
uint256 baseOutAmount,
uint256 quoteOutAmount
) external;
uint256 quoteOutAmount,
uint256 minBaseReserve,
uint256 minQuoteReserve
) external returns (bool);
}

View File

@@ -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 ============

View File

@@ -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 ===========

View File

@@ -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;

View File

@@ -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<void> {
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"
)
})
})

View File

@@ -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();

View File

@@ -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]"));
}