457 lines
23 KiB
TypeScript
457 lines
23 KiB
TypeScript
/*
|
|
|
|
Copyright 2020 DODO ZOO.
|
|
SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
import { DODOContext, getDODOContext } from './utils/Context';
|
|
import { decimalStr } from './utils/Converter';
|
|
import { logGas } from './utils/Log';
|
|
import * as assert from "assert"
|
|
|
|
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"))
|
|
|
|
logGas(await ctx.DODO.methods.depositBase(decimalStr("10")).send(ctx.sendParam(lp1)), "deposit base")
|
|
assert.equal(await ctx.BASE.methods.balanceOf(lp1).call(), decimalStr("90"))
|
|
logGas(await ctx.DODO.methods.depositQuote(decimalStr("1000")).send(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")).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(), "10163234422929069690")
|
|
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp1).call(), decimalStr("1000"))
|
|
|
|
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp2).call(), "5076114129127759275")
|
|
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp2).call(), decimalStr("100"))
|
|
|
|
assert.equal(await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("5")).call(), "228507420047606043")
|
|
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")).send(ctx.sendParam(trader))
|
|
|
|
assert.equal(await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("4")).call(), "1065045389392391670")
|
|
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(), "92934954610607608330")
|
|
assert.equal(await ctx.DODO.methods._BASE_BALANCE_().call(), "2060045389392391670")
|
|
assert.equal(await ctx.DODO.methods._TARGET_BASE_TOKEN_AMOUNT_().call(), "7075045389392391670")
|
|
|
|
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")).send(ctx.sendParam(trader))
|
|
|
|
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp1).call(), decimalStr("10"))
|
|
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp1).call(), "1000978629616255274293")
|
|
|
|
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(), "1012529270910521748792")
|
|
|
|
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp2).call(), decimalStr("5"))
|
|
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp2).call(), "505769674273013520099")
|
|
|
|
assert.equal(await ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("5")).call(), "0")
|
|
assert.equal(await ctx.DODO.methods.getWithdrawQuotePenalty(decimalStr("500")).call(), "17320315567279994599")
|
|
})
|
|
|
|
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")).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(), "7389428846238898052")
|
|
|
|
await ctx.DODO.methods.withdrawQuote(decimalStr("100")).send(ctx.sendParam(lp1))
|
|
assert.equal(await ctx.QUOTE.methods.balanceOf(lp1).call(), "9092610571153761101948")
|
|
assert.equal(await ctx.DODO.methods._QUOTE_BALANCE_().call(), "447655402437037250886")
|
|
assert.equal(await ctx.DODO.methods._TARGET_QUOTE_TOKEN_AMOUNT_().call(), "908310739520405634819")
|
|
|
|
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")).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(), "914362409397559034505")
|
|
|
|
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(), "1085284653936129403614")
|
|
})
|
|
|
|
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")).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(), "9234731968726215538")
|
|
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")).send(ctx.sendParam(trader))
|
|
await ctx.DODO.methods.sellBaseToken("5015841132009222923", decimalStr("0")).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")).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")).send(ctx.sendParam(trader))
|
|
|
|
await ctx.setOraclePrice(decimalStr("120"))
|
|
await ctx.DODO.methods.sellBaseToken(decimalStr("4"), decimalStr("0")).send(ctx.sendParam(trader))
|
|
await ctx.DODO.methods.sellBaseToken(decimalStr("1"), decimalStr("0")).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(), "9234731968726215513")
|
|
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(), "7221653398290522326")
|
|
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp2).call(), "7221653398290522382")
|
|
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp1).call(), "9234731968726215513")
|
|
})
|
|
|
|
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")).send(ctx.sendParam(trader))
|
|
|
|
await ctx.setOraclePrice(decimalStr("80"))
|
|
await ctx.DODO.methods.sellBaseToken(decimalStr("4"), decimalStr("0")).send(ctx.sendParam(trader))
|
|
await ctx.DODO.methods.sellBaseToken(decimalStr("4"), decimalStr("0")).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(), "21553269260529319697")
|
|
assert.equal(await ctx.DODO.methods.getLpQuoteBalance(lp2).call(), "21553269260529319725")
|
|
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")).send(ctx.sendParam(trader))
|
|
|
|
await ctx.setOraclePrice(decimalStr("80"))
|
|
await ctx.DODO.methods.buyBaseToken(decimalStr("4"), decimalStr("600")).send(ctx.sendParam(trader))
|
|
await ctx.DODO.methods.buyBaseToken(decimalStr("0.99"), decimalStr("500")).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(), "914362409397559031579")
|
|
|
|
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(), "914362409397559031579")
|
|
})
|
|
|
|
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")).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(), "10163234422929069690")
|
|
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp2).call(), "5076114129127759275")
|
|
|
|
await ctx.DODO.methods.withdrawAllBase().send(ctx.sendParam(lp2))
|
|
|
|
assert.equal(await ctx.BASE.methods.balanceOf(lp2).call(), "99841132414635941818")
|
|
assert.equal(await ctx.DODO.methods.getLpBaseBalance(lp1).call(), "10182702153814588570")
|
|
})
|
|
})
|
|
|
|
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")).send(ctx.sendParam(trader))
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawBase(decimalStr("6")).send(ctx.sendParam(lp1)),
|
|
/DODO_BASE_TOKEN_BALANCE_NOT_ENOUGH/
|
|
)
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawAllBase().send(ctx.sendParam(lp1)),
|
|
/DODO_BASE_TOKEN_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")).send(ctx.sendParam(trader))
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawQuote(decimalStr("600")).send(ctx.sendParam(lp1)),
|
|
/DODO_QUOTE_TOKEN_BALANCE_NOT_ENOUGH/
|
|
)
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawAllQuote().send(ctx.sendParam(lp1)),
|
|
/DODO_QUOTE_TOKEN_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")).send(ctx.sendParam(trader))
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawBase(decimalStr("0.5")).send(ctx.sendParam(lp1)),
|
|
/COULD_NOT_AFFORD_LIQUIDITY_PENALTY/
|
|
)
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.getWithdrawBasePenalty(decimalStr("10")).call(),
|
|
/DODO_BASE_TOKEN_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")).send(ctx.sendParam(trader))
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawQuote(decimalStr("200")).send(ctx.sendParam(lp1)),
|
|
/COULD_NOT_AFFORD_LIQUIDITY_PENALTY/
|
|
)
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.getWithdrawQuotePenalty(decimalStr("1000")).call(),
|
|
/DODO_QUOTE_TOKEN_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")).send(ctx.sendParam(trader))
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawBase(decimalStr("0.5")).send(ctx.sendParam(lp2)),
|
|
/COULD_NOT_AFFORD_LIQUIDITY_PENALTY/
|
|
)
|
|
})
|
|
|
|
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")).send(ctx.sendParam(trader))
|
|
|
|
await assert.rejects(
|
|
ctx.DODO.methods.withdrawQuote(decimalStr("200")).send(ctx.sendParam(lp2)),
|
|
/COULD_NOT_AFFORD_LIQUIDITY_PENALTY/
|
|
)
|
|
})
|
|
|
|
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/
|
|
)
|
|
})
|
|
})
|
|
|
|
}) |