Skip to content

Commit

Permalink
Merge f29bdc1 into a43b04b
Browse files Browse the repository at this point in the history
  • Loading branch information
jiro-ono committed Nov 25, 2022
2 parents a43b04b + f29bdc1 commit 0b3009d
Show file tree
Hide file tree
Showing 13 changed files with 621 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"mochaExplorer.files": "test/**/*.{j,t}s",
"mochaExplorer.files": ["test/constant-product/*.test.ts", "test/stable-pool/*test.ts"],
"mochaExplorer.fullTrace": true,
"mochaExplorer.exit": true,
"solidity.compileUsingRemoteVersion": "v0.8.7+commit.e28d00a7",
Expand Down
2 changes: 1 addition & 1 deletion deploy/StablePoolFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ const deployFunction: DeployFunction = async function ({

export default deployFunction;

// deployFunction.dependencies = ["MasterDeployer"];
//deployFunction.dependencies = ["MasterDeployer"];

deployFunction.tags = ["StablePoolFactory"];
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
"moonbase:export": "hardhat --network moonbase export --export exports/moonbase.json",
"arbitrum:deploy": "hardhat --network arbitrum deploy",
"arbitrum:export": "hardhat --network arbitrum export --export exports/arbitrum.json",
"test": "hardhat test test/_/*.ts test/abstract/*.test.ts test/constant-product/*.test.ts test/deployer/*.test.ts test/library/*.test.ts test/router/*.test.ts",
"test": "hardhat test test/_/*.ts test/abstract/*.test.ts test/constant-product/*.test.ts test/stable-pool/*.test.ts test/deployer/*.test.ts test/library/*.test.ts test/router/*.test.ts",
"testTines": "hardhat test test/constant-product/ConstantProductRouting.test.ts test/stable-pool/StablePoolRouting.test.ts test/router/RoutingMultiPool.test.ts test/router/RoutingMultiPoolComplex.test.ts test/router/TridentRouter.test.ts",
"testOnly": "hardhat test",
"test:debug": "mocha --inspect-brk",
"test:trace": "yarn test --logs",
"test:coverage": "COVERAGE=true hardhat coverage --testfiles \"{test/_/*.ts,test/abstract/*.test.ts,test/constant-product/*.test.ts,test/deployer/*.test.ts,test/library/*.test.ts,test/router/*.test.ts}\"",
"test:coverage": "COVERAGE=true hardhat coverage --testfiles \"{test/_/*.ts,test/abstract/*.test.ts,test/constant-product/*.test.ts,test/stable-pool/*.test.ts,test/deployer/*.test.ts,test/library/*.test.ts,test/router/*.test.ts}\"",
"test:gas": "cross-env REPORT_GAS=true yarn test",
"prettier": "prettier --write 'test/**/*.{js,ts}' && prettier --write contracts/**/*.sol",
"lint": "yarn prettier && solhint -c .solhint.json contracts/**/*.sol",
Expand Down
119 changes: 113 additions & 6 deletions test/constant-product/ConstantProductPool.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from "chai";
import { BigNumber } from "ethers";
import { BigNumber, utils } from "ethers";
import { deployments, ethers, getNamedAccounts } from "hardhat";

import {
Expand Down Expand Up @@ -36,7 +36,7 @@ describe("Constant Product Pool", () => {
await expect(cppFactory.deployPool(deployData)).to.be.revertedWith("ZeroAddress()");
});

it("deploys if token1 is zero", async () => {
it("reverts if token1 is zero", async () => {
const cppFactory = await ethers.getContract<ConstantProductPoolFactory>("ConstantProductPoolFactory");
const deployData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "uint256", "bool"],
Expand Down Expand Up @@ -111,11 +111,65 @@ describe("Constant Product Pool", () => {
});

describe("#burn", function () {
//
it("burns all liquidity to token0 and token1 balances", async () => {
const deployer = await ethers.getNamedSigner("deployer");
const bob = await ethers.getNamedSigner("bob");
const pool = await initializedConstantProductPool();
const token0 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token0());
const token1 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token1());

await pool.transfer(pool.address, await pool.balanceOf(deployer.address));
const burnData = ethers.utils.defaultAbiCoder.encode(["address", "bool"], [bob.address, true]);
await pool.burn(burnData);

expect(await token0.balanceOf(bob.address)).to.be.above(0);

expect(await token1.balanceOf(bob.address)).to.be.above(0);
});
});

describe("#burnSingle", function () {
//
it("removes liquidity all in token0", async () => {
const bob = await ethers.getNamedSigner("bob");
const pool = await initializedConstantProductPool();
const token0 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token0());

await pool.transfer(pool.address, await "1000");
const burnData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "bool"],
[token0.address, bob.address, true]
);
await pool.burnSingle(burnData);

expect(await token0.balanceOf(bob.address)).to.be.above(0);
});

it("removes liquidity all in token1", async () => {
const bob = await ethers.getNamedSigner("bob");
const pool = await initializedConstantProductPool();
const token1 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token1());

await pool.transfer(pool.address, await "1000");
const burnData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "bool"],
[token1.address, bob.address, true]
);
await pool.burnSingle(burnData);

expect(await token1.balanceOf(bob.address)).to.be.above(0);
});

it("reverts if tokenOut is not equal to token0 or token1", async () => {
const deployer = await ethers.getNamedSigner("deployer");
const pool = await initializedConstantProductPool();
await pool.transfer(pool.address, await pool.balanceOf(deployer.address));
const burnData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "bool"],
["0x0000000000000000000000000000000000000003", deployer.address, true]
);

expect(pool.burnSingle(burnData)).to.be.revertedWith("InvalidOutputToken()");
});
});

describe("#swap", function () {
Expand All @@ -127,6 +181,54 @@ describe("Constant Product Pool", () => {
);
await expect(pool.swap(data)).to.be.revertedWith("PoolUninitialized()");
});

it("swaps token0 to token1", async () => {
const bob = await ethers.getNamedSigner("bob");
const bento = await ethers.getContract<BentoBoxV1>("BentoBoxV1");
const pool = await initializedConstantProductPool();
const token0 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token0());
const token1 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token1());

await token0.transfer(bento.address, "10000000");
await bento.deposit(token0.address, bento.address, pool.address, "10000000", 0);
const swapData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "bool"],
[token0.address, bob.address, true]
);
await pool.swap(swapData);

expect(await token1.balanceOf(bob.address)).to.be.above(0);
});

it("simple swap token1 to token0", async () => {
const bob = await ethers.getNamedSigner("bob");
const bento = await ethers.getContract<BentoBoxV1>("BentoBoxV1");
const pool = await initializedConstantProductPool();
const token0 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token0());
const token1 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token1());

await token1.transfer(bento.address, "10000000");
await bento.deposit(token1.address, bento.address, pool.address, "10000000", 0);
const swapData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "bool"],
[token1.address, bob.address, true]
);
await pool.swap(swapData);

expect(await token0.balanceOf(bob.address)).to.be.above(0);
});

it("reverts if tokenOut is not equal to token0 or token1", async () => {
const deployer = await ethers.getNamedSigner("deployer");
const pool = await initializedConstantProductPool();

const swapData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "bool"],
["0x0000000000000000000000000000000000000003", deployer.address, true]
);

expect(pool.swap(swapData)).to.be.revertedWith("InvalidInputToken()");
});
});

describe("#flashSwap", function () {
Expand All @@ -153,7 +255,7 @@ describe("Constant Product Pool", () => {
await expect(pool.flashSwap(data)).to.be.revertedWith("InvalidInputToken()");
});

it("reverts on insuffiecient amount in token 0", async () => {
it("reverts on insufficient amount in token 0", async () => {
const pool = await initializedConstantProductPool();
const token0 = await ethers.getContractAt<ERC20Mock>("ERC20Mock", await pool.token0());
const bento = await ethers.getContract<BentoBoxV1>("BentoBoxV1");
Expand Down Expand Up @@ -290,7 +392,12 @@ describe("Constant Product Pool", () => {
});

describe("#poolIdentifier", function () {
//
it("returns correct identifier for Constant Product Pools", async () => {
const pool = await initializedConstantProductPool();
expect(await (await pool.poolIdentifier()).toString()).to.equal(
utils.formatBytes32String("Trident:ConstantProduct")
);
});
});

describe("#getAssets", function () {
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/constant-product/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { initializedConstantProductPool } from "./initializedConstantProductPool";
export { uninitializedConstantProductPool } from "./uninitializedConstantProductPool";
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ConstantProductPool__factory,
ERC20Mock__factory,
MasterDeployer,
} from "../../types";
} from "../../../types";

export const initializedConstantProductPool = deployments.createFixture(
async (
Expand Down Expand Up @@ -76,7 +76,6 @@ export const initializedConstantProductPool = deployments.createFixture(
.then((tx) => tx.wait());

await bento

.transfer(token1.address, deployer.address, contractReceipt.events?.[0].args?.pool, "1000000000000000000")
.then((tx) => tx.wait());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ConstantProductPool__factory,
ERC20Mock__factory,
MasterDeployer,
} from "../../types";
} from "../../../types";

export const uninitializedConstantProductPool = deployments.createFixture(async ({ deployments, ethers }, options) => {
await deployments.fixture(["ConstantProductPoolFactory"]); // ensure you start from a fresh deployments
Expand Down
5 changes: 2 additions & 3 deletions test/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export { initializedConstantProductPool } from "./initializedConstantProductPool";
export { uninitializedConstantProductPool } from "./uninitializedConstantProductPool";
export { initializedStablePool, uninitializedStablePool } from "./stable-pool";
export * from "./constant-product";
export * from "./stable-pool";
1 change: 1 addition & 0 deletions test/fixtures/stable-pool/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { initializedStablePool } from "./initializedStablePool";
export { uninitializedStablePool } from "./uninitializedStablePool";
export { vanillaInitializedStablePool } from "./vanillaInitializedStablePool";
24 changes: 18 additions & 6 deletions test/fixtures/stable-pool/initializedStablePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export const initializedStablePool = deployments.createFixture(
},
options?: {
fee?: number;
token0?: string;
token1?: string;
token0Decimals?: number;
token1Decimals?: number;
}
) => {
options = {
Expand All @@ -35,18 +35,30 @@ export const initializedStablePool = deployments.createFixture(
const ERC20 = await ethers.getContractFactory<ERC20Mock__factory>("ERC20Mock");

let token0, token1;
if (options.token0 === undefined) {
if (options.token0Decimals === undefined) {
token0 = await ERC20.deploy("Token 0", "TOKEN0", ethers.constants.MaxUint256);
await token0.deployed();
} else {
token0 = await ethers.getContract<ERC20Mock>(options.token0 as string);
token0 = await ERC20.deploy(
`Token0-${options.token0Decimals}`,
`TOKEN0-${options.token0Decimals}`,
ethers.constants.MaxUint256
);
token0.setDecimals(options.token0Decimals);
await token0.deployed();
}

if (options.token1 === undefined) {
if (options.token1Decimals === undefined) {
token1 = await ERC20.deploy("Token 1", "TOKEN1", ethers.constants.MaxUint256);
await token1.deployed();
} else {
token1 = await ethers.getContract<ERC20Mock>(options.token1 as string);
token1 = await ERC20.deploy(
`Token1-${options.token1Decimals}`,
`TOKEN1-${options.token1Decimals}`,
ethers.constants.MaxUint256
);
token1.setDecimals(options.token1Decimals);
await token0.deployed();
}

const masterDeployer = await ethers.getContract<MasterDeployer>("MasterDeployer");
Expand Down
83 changes: 83 additions & 0 deletions test/fixtures/stable-pool/vanillaInitializedStablePool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { ethers, deployments } from "hardhat";
import { BentoBoxV1, StablePoolFactory, StablePool__factory, ERC20Mock__factory, MasterDeployer } from "../../../types";

export const vanillaInitializedStablePool = deployments.createFixture(
async (
{
deployments,
ethers: {
getNamedSigners,
constants: { MaxUint256 },
},
},
options
) => {
await deployments.fixture(["StablePoolFactory"], { keepExistingDeployments: true }); // ensure you start from a fresh deployments
const { deployer } = await getNamedSigners();

const ERC20 = await ethers.getContractFactory<ERC20Mock__factory>("ERC20Mock");

const token0 = await ERC20.deploy("Token 0", "TOKEN0", ethers.constants.MaxUint256);
await token0.deployed();

const token1 = await ERC20.deploy("Token 1", "TOKEN1", ethers.constants.MaxUint256);
await token1.deployed();

const masterDeployer = await ethers.getContract<MasterDeployer>("MasterDeployer");

const stablePoolFactory = await ethers.getContract<StablePoolFactory>("StablePoolFactory");

const deployData = ethers.utils.defaultAbiCoder.encode(
["address", "address", "uint256"],
[token0.address, token1.address, 0]
);

const contractReceipt = await masterDeployer
.deployPool(stablePoolFactory.address, deployData)
.then((tx) => tx.wait());

const bento = await ethers.getContract<BentoBoxV1>("BentoBoxV1");

await bento.whitelistMasterContract("0x0000000000000000000000000000000000000001", true);

await token0.approve(bento.address, MaxUint256).then((tx) => tx.wait());

await token1.approve(bento.address, MaxUint256).then((tx) => tx.wait());

await bento
.setMasterContractApproval(
deployer.address,
"0x0000000000000000000000000000000000000001",
true,
"0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000000"
)
.then((tx) => tx.wait());

await bento
.deposit(token0.address, deployer.address, deployer.address, "1000000000000000000", 0)
.then((tx) => tx.wait());

await bento
.deposit(token1.address, deployer.address, deployer.address, "1000000000000000000", 0)
.then((tx) => tx.wait());

await bento
.transfer(token0.address, deployer.address, contractReceipt.events?.[0].args?.pool, "1000000000000000000")
.then((tx) => tx.wait());

await bento
.transfer(token1.address, deployer.address, contractReceipt.events?.[0].args?.pool, "1000000000000000000")
.then((tx) => tx.wait());

const Pool = await ethers.getContractFactory<StablePool__factory>("StablePool");

const pool = Pool.attach(contractReceipt.events?.[0].args?.pool);

await pool.mint(ethers.utils.defaultAbiCoder.encode(["address"], [deployer.address])).then((tx) => tx.wait());

return pool;
},
"vanillaInitializedStablePool"
);
Loading

0 comments on commit 0b3009d

Please sign in to comment.