Files
dodo-contractV2/test/LiquidityProvider.test.ts
Michael Zhou e3ce9758e5 Fix tests
Use the new logGas.
2020-09-08 20:37:11 +08:00

926 lines
27 KiB
TypeScript

/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
import * as assert from 'assert';
import { DODOContext, getDODOContext } from './utils/Context';
import { decimalStr } from './utils/Converter';
import { logGas } from './utils/Log';
let lp1: string;
let lp2: string;
let trader: string;
async function init(ctx: DODOContext): Promise<void> {
await ctx.setOraclePrice(decimalStr("100"));
lp1 = ctx.spareAccounts[0];
lp2 = ctx.spareAccounts[1];
trader = ctx.spareAccounts[2];
await ctx.mintTestToken(lp1, decimalStr("100"), decimalStr("10000"));
await ctx.mintTestToken(lp2, decimalStr("100"), decimalStr("10000"));
await ctx.mintTestToken(trader, decimalStr("100"), decimalStr("10000"));
await ctx.approveDODO(lp1);
await ctx.approveDODO(lp2);
await ctx.approveDODO(trader);
}
describe("LiquidityProvider", () => {
let snapshotId: string;
let ctx: DODOContext;
before(async () => {
ctx = await getDODOContext();
await init(ctx);
});
beforeEach(async () => {
snapshotId = await ctx.EVM.snapshot();
});
afterEach(async () => {
await ctx.EVM.reset(snapshotId);
});
describe("R equals to ONE", () => {
it("multi lp deposit & withdraw", async () => {
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("0")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("0")
);
await logGas(
ctx.DODO.methods.depositBase(decimalStr("10")),
ctx.sendParam(lp1),
"deposit base"
);
assert.equal(
await ctx.BASE.methods.balanceOf(lp1).call(),
decimalStr("90")
);
await logGas(
ctx.DODO.methods.depositQuote(decimalStr("1000")),
ctx.sendParam(lp1),
"deposit quote"
);
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp1).call(),
decimalStr("9000")
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods._BASE_BALANCE_().call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("1000")
);
assert.equal(
await ctx.DODO.methods._QUOTE_BALANCE_().call(),
decimalStr("1000")
);
await ctx.DODO.methods
.depositBase(decimalStr("3"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.depositQuote(decimalStr("70"))
.send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("1000")
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp2).call(),
decimalStr("3")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp2).call(),
decimalStr("70")
);
assert.equal(
await ctx.DODO.methods._BASE_BALANCE_().call(),
decimalStr("13")
);
assert.equal(
await ctx.DODO.methods._QUOTE_BALANCE_().call(),
decimalStr("1070")
);
await ctx.DODO.methods
.withdrawBase(decimalStr("5"))
.send(ctx.sendParam(lp1));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("5")
);
assert.equal(
await ctx.BASE.methods.balanceOf(lp1).call(),
decimalStr("95")
);
await ctx.DODO.methods
.withdrawQuote(decimalStr("100"))
.send(ctx.sendParam(lp1));
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("900")
);
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp1).call(),
decimalStr("9100")
);
await ctx.DODO.methods.withdrawAllBase().send(ctx.sendParam(lp1));
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp1).call(), "0");
assert.equal(
await ctx.BASE.methods.balanceOf(lp1).call(),
decimalStr("100")
);
await ctx.DODO.methods.withdrawAllQuote().send(ctx.sendParam(lp1));
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp1).call(), "0");
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp1).call(),
decimalStr("10000")
);
});
});
describe("R is ABOVE ONE", () => {
it("deposit", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"10010841132009222923"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("1000")
);
await ctx.DODO.methods
.depositBase(decimalStr("5"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.depositQuote(decimalStr("100"))
.send(ctx.sendParam(lp2));
// lp1 & lp2 would both have profit because the curve becomes flatter
// but the withdraw penalty is greater than this free profit
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"10163234422929069723"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("1000")
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp2).call(),
"5076114129127759292"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp2).call(),
decimalStr("100")
);
assert.equal(
await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("5")).call(),
"228507420047606093"
);
assert.equal(
await ctx.DODO.methods
.getWithdrawQuotePenalty(decimalStr("100"))
.call(),
"0"
);
});
it("withdraw", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
assert.equal(
await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("4")).call(),
"1065045389392391665"
);
assert.equal(
await ctx.DODO.methods
.getWithdrawQuotePenalty(decimalStr("100"))
.call(),
"0"
);
await ctx.DODO.methods
.withdrawBase(decimalStr("4"))
.send(ctx.sendParam(lp1));
assert.equal(
await ctx.BASE.methods.balanceOf(lp1).call(),
"92934954610607608335"
);
assert.equal(
await ctx.DODO.methods._BASE_BALANCE_().call(),
"2060045389392391665"
);
assert.equal(
await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(),
"7075045389392391665"
);
await ctx.DODO.methods
.withdrawQuote(decimalStr("100"))
.send(ctx.sendParam(lp1));
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp1).call(),
decimalStr("9100")
);
assert.equal(
await ctx.DODO.methods._QUOTE_BALANCE_().call(),
"1451951805416248746119"
);
assert.equal(
await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(),
decimalStr("900")
);
});
});
describe("R is BELOW ONE", () => {
it("deposit", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.sellBaseToken(decimalStr("5"), decimalStr("200"), "0x")
.send(ctx.sendParam(trader));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
"1000978629616255276996"
);
await ctx.DODO.methods
.depositQuote(decimalStr("500"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.depositBase(decimalStr("5"))
.send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
"1012529270910521756641"
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp2).call(),
decimalStr("5")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp2).call(),
"505769674273013522654"
);
assert.equal(
await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("5")).call(),
"0"
);
assert.equal(
await ctx.DODO.methods
.getWithdrawQuotePenalty(decimalStr("500"))
.call(),
"17320315567280002300"
);
});
it("withdraw", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.sellBaseToken(decimalStr("5"), decimalStr("200"), "0x")
.send(ctx.sendParam(trader));
assert.equal(
await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("4")).call(),
"0"
);
assert.equal(
await ctx.DODO.methods
.getWithdrawQuotePenalty(decimalStr("100"))
.call(),
"7389428846238900753"
);
await ctx.DODO.methods
.withdrawQuote(decimalStr("100"))
.send(ctx.sendParam(lp1));
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp1).call(),
"9092610571153761099247"
);
assert.equal(
await ctx.DODO.methods._QUOTE_BALANCE_().call(),
"447655402437037253588"
);
assert.equal(
await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(),
"908310739520405637520"
);
await ctx.DODO.methods
.withdrawBase(decimalStr("4"))
.send(ctx.sendParam(lp1));
assert.equal(
await ctx.BASE.methods.balanceOf(lp1).call(),
decimalStr("94")
);
assert.equal(
await ctx.DODO.methods._BASE_BALANCE_().call(),
decimalStr("11")
);
assert.equal(
await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(),
decimalStr("6")
);
});
});
describe("Oracle changes", () => {
it("base side lp don't has pnl when R is BELOW ONE", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.sellBaseToken(decimalStr("5"), decimalStr("200"), "0x")
.send(ctx.sendParam(trader));
await ctx.setOraclePrice(decimalStr("80"));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
"914362409397559037208"
);
await ctx.setOraclePrice(decimalStr("120"));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
decimalStr("10")
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
"1085284653936129406317"
);
});
it("quote side lp don't has pnl when R is ABOVE ONE", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("600"), "0x")
.send(ctx.sendParam(trader));
await ctx.setOraclePrice(decimalStr("80"));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"11138732839027528597"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("1000")
);
await ctx.setOraclePrice(decimalStr("120"));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"9234731968726215588"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
decimalStr("1000")
);
});
});
describe("Transfer lp token", () => {
it("transfer", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.BaseCapital.methods
.transfer(lp2, decimalStr("5"))
.send(ctx.sendParam(lp1));
await ctx.QuoteCapital.methods
.transfer(lp2, decimalStr("5"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods.withdrawAllBase().send(ctx.sendParam(lp2));
await ctx.DODO.methods.withdrawAllQuote().send(ctx.sendParam(lp2));
assert.equal(
await ctx.BASE.methods.balanceOf(lp2).call(),
decimalStr("105")
);
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp2).call(),
decimalStr("10005")
);
});
});
describe("Deposit & transfer to other account", () => {
it("base token", async () => {
await ctx.DODO.methods
.depositBaseTo(lp2, decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.withdrawBaseTo(trader, decimalStr("5"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.withdrawAllBaseTo(ctx.Supervisor)
.send(ctx.sendParam(lp2));
assert.equal(
await ctx.BASE.methods.balanceOf(lp1).call(),
decimalStr("90")
);
assert.equal(
await ctx.BASE.methods.balanceOf(lp2).call(),
decimalStr("100")
);
assert.equal(
await ctx.BASE.methods.balanceOf(trader).call(),
decimalStr("105")
);
assert.equal(
await ctx.BASE.methods.balanceOf(ctx.Supervisor).call(),
decimalStr("5")
);
});
it("quote token", async () => {
await ctx.DODO.methods
.depositQuoteTo(lp2, decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.withdrawQuoteTo(trader, decimalStr("500"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.withdrawAllQuoteTo(ctx.Supervisor)
.send(ctx.sendParam(lp2));
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp1).call(),
decimalStr("9000")
);
assert.equal(
await ctx.QUOTE.methods.balanceOf(lp2).call(),
decimalStr("10000")
);
assert.equal(
await ctx.QUOTE.methods.balanceOf(trader).call(),
decimalStr("10500")
);
assert.equal(
await ctx.QUOTE.methods.balanceOf(ctx.Supervisor).call(),
decimalStr("500")
);
});
});
describe("Corner cases", () => {
it("single side deposit", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
await ctx.DODO.methods
.sellBaseToken("5015841132009222923", decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
assert.equal(await ctx.DODO.methods._R_STATUS_().call(), "0");
assert.equal(
await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(),
"10010841132009222923"
);
assert.equal(
await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(),
"1103903610832497492"
);
await ctx.DODO.methods.depositQuote("1").send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getQuoteCapitalBalanceOf(lp2).call(),
"1103903610832497493"
);
});
it("single side deposit & lp deposit when R isn't equal to ONE", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
await ctx.DODO.methods.depositQuote("1").send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getQuoteCapitalBalanceOf(lp2).call(),
"1"
);
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp2).call(), "1");
});
it("single side deposit (base) & oracle change introduces loss", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
await ctx.setOraclePrice(decimalStr("120"));
await ctx.DODO.methods
.sellBaseToken(decimalStr("4"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
await ctx.DODO.methods
.sellBaseToken(decimalStr("1"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
assert.equal(await ctx.DODO.methods._R_STATUS_().call(), "2");
assert.equal(
await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(),
"9234731968726215603"
);
assert.equal(
await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(),
"1105993618321025490"
);
await ctx.DODO.methods.depositQuote("1").send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getQuoteCapitalBalanceOf(lp2).call(),
"7221653398290521828"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp2).call(),
"7221653398290521884"
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"9234731968726215603"
);
});
it("single side deposit (base) & oracle change introduces profit", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
await ctx.setOraclePrice(decimalStr("80"));
await ctx.DODO.methods
.sellBaseToken(decimalStr("4"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
await ctx.DODO.methods
.sellBaseToken(decimalStr("4"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
assert.equal(await ctx.DODO.methods._R_STATUS_().call(), "2");
assert.equal(
await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(),
"11138732839027528584"
);
assert.equal(
await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(),
"1105408308382702868"
);
await ctx.DODO.methods.depositQuote("1").send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getQuoteCapitalBalanceOf(lp2).call(),
"21553269260529319669"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp2).call(),
"21553269260529319697"
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"11138732839027528584"
);
});
it("single side deposit (quote) & oracle change introduces loss", async () => {
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.sellBaseToken(decimalStr("5"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
await ctx.setOraclePrice(decimalStr("80"));
await ctx.DODO.methods
.buyBaseToken(decimalStr("4"), decimalStr("600"), "0x")
.send(ctx.sendParam(trader));
await ctx.DODO.methods
.buyBaseToken(decimalStr("0.99"), decimalStr("500"), "0x")
.send(ctx.sendParam(trader));
assert.equal(await ctx.DODO.methods._R_STATUS_().call(), "1");
assert.equal(
await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(),
"9980000000000000"
);
assert.equal(
await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(),
"914362409397559035414"
);
await ctx.DODO.methods.depositBase("1").send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getBaseCapitalBalanceOf(lp2).call(),
"10247647352975730"
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp2).call(),
"10247647352975730"
);
assert.equal(
await ctx.DODO.methods.getLpQuoteBalance(lp1).call(),
"914362409397559035414"
);
});
it("deposit and withdraw immediately", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"10010841132009222923"
);
await ctx.DODO.methods
.depositBase(decimalStr("5"))
.send(ctx.sendParam(lp2));
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"10163234422929069723"
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp2).call(),
"5076114129127759292"
);
await ctx.DODO.methods.withdrawAllBase().send(ctx.sendParam(lp2));
assert.equal(
await ctx.BASE.methods.balanceOf(lp2).call(),
"99841132414635941792"
);
assert.equal(
await ctx.DODO.methods.getLpBaseBalance(lp1).call(),
"10182702153814588648"
);
});
});
describe("Revert cases", () => {
it("withdraw base amount exceeds DODO balance", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("5"), decimalStr("1000"), "0x")
.send(ctx.sendParam(trader));
await assert.rejects(
ctx.DODO.methods.withdrawBase(decimalStr("6")).send(ctx.sendParam(lp1)),
/DODO_BASE_BALANCE_NOT_ENOUGH/
);
await assert.rejects(
ctx.DODO.methods.withdrawAllBase().send(ctx.sendParam(lp1)),
/DODO_BASE_BALANCE_NOT_ENOUGH/
);
});
it("withdraw quote amount exceeds DODO balance", async () => {
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.sellBaseToken(decimalStr("5"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
await assert.rejects(
ctx.DODO.methods
.withdrawQuote(decimalStr("600"))
.send(ctx.sendParam(lp1)),
/DODO_QUOTE_BALANCE_NOT_ENOUGH/
);
await assert.rejects(
ctx.DODO.methods.withdrawAllQuote().send(ctx.sendParam(lp1)),
/DODO_QUOTE_BALANCE_NOT_ENOUGH/
);
});
it("withdraw base could not afford penalty", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.buyBaseToken(decimalStr("9"), decimalStr("10000"), "0x")
.send(ctx.sendParam(trader));
await assert.rejects(
ctx.DODO.methods
.withdrawBase(decimalStr("0.5"))
.send(ctx.sendParam(lp1)),
/PENALTY_EXCEED/
);
await assert.rejects(
ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("10")).call(),
/DODO_BASE_BALANCE_NOT_ENOUGH/
);
});
it("withdraw quote could not afford penalty", async () => {
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.sellBaseToken(decimalStr("10"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
await assert.rejects(
ctx.DODO.methods
.withdrawQuote(decimalStr("200"))
.send(ctx.sendParam(lp1)),
/PENALTY_EXCEED/
);
await assert.rejects(
ctx.DODO.methods.getWithdrawQuotePenalty(decimalStr("1000")).call(),
/DODO_QUOTE_BALANCE_NOT_ENOUGH/
);
});
it("withdraw all base could not afford penalty", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("9.5"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositBase(decimalStr("0.5"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.buyBaseToken(decimalStr("9"), decimalStr("10000"), "0x")
.send(ctx.sendParam(trader));
await assert.rejects(
ctx.DODO.methods
.withdrawBase(decimalStr("0.5"))
.send(ctx.sendParam(lp2)),
/PENALTY_EXCEED/
);
});
it("withdraw all quote could not afford penalty", async () => {
await ctx.DODO.methods
.depositQuote(decimalStr("800"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("200"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.sellBaseToken(decimalStr("10"), decimalStr("0"), "0x")
.send(ctx.sendParam(trader));
await assert.rejects(
ctx.DODO.methods
.withdrawQuote(decimalStr("200"))
.send(ctx.sendParam(lp2)),
/PENALTY_EXCEED/
);
});
it("withdraw amount exceeds lp balance", async () => {
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositBase(decimalStr("10"))
.send(ctx.sendParam(lp2));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp1));
await ctx.DODO.methods
.depositQuote(decimalStr("1000"))
.send(ctx.sendParam(lp2));
await assert.rejects(
ctx.DODO.methods
.withdrawBase(decimalStr("11"))
.send(ctx.sendParam(lp1)),
/LP_BASE_CAPITAL_BALANCE_NOT_ENOUGH/
);
await assert.rejects(
ctx.DODO.methods
.withdrawQuote(decimalStr("1100"))
.send(ctx.sendParam(lp1)),
/LP_QUOTE_CAPITAL_BALANCE_NOT_ENOUGH/
);
});
it("withdraw when there is no lp", async () => {
await assert.rejects(
ctx.DODO.methods.withdrawBase(decimalStr("1")).send(ctx.sendParam(lp1)),
/NO_BASE_LP/
);
await assert.rejects(
ctx.DODO.methods
.withdrawQuote(decimalStr("1"))
.send(ctx.sendParam(lp1)),
/NO_QUOTE_LP/
);
});
});
});