init test env
This commit is contained in:
925
test/V1/LiquidityProvider.test.ts
Normal file
925
test/V1/LiquidityProvider.test.ts
Normal file
@@ -0,0 +1,925 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 DODO ZOO.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
|
||||
import { DODOContext, getDODOContext } from './utils/DVMContext';
|
||||
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/
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user