dsa-connectors-2.0/test/mainnet/ubiquity/ubiquity.test.ts
2023-12-16 04:20:02 +05:30

463 lines
16 KiB
TypeScript

import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider } = waffle;
const { BigNumber, utils } = ethers;
import {deployAndEnableConnector} from "../../../scripts/tests/deployAndEnableConnector";
import {buildDSAv2} from "../../../scripts/tests/buildDSAv2";
import {encodeSpells} from "../../../scripts/tests/encodeSpells";
import {addresses} from "../../../scripts/tests/mainnet/addresses";
import {abis} from "../../../scripts/constant/abis";
import {impersonateAccounts} from "../../../scripts/tests/impersonate";
import type { Signer, Contract, BigNumberish } from "ethers";
import {forkReset, sendEth, mineNBlock} from "./utils";
import { ConnectV2Ubiquity__factory } from "../../../typechain";
import { abi as implementationsABI } from "../../../scripts/constant/abi/core/InstaImplementations.json";
const implementationsMappingAddr = "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D";
describe("Ubiquity", function () {
const ubiquityTest = "UBIQUITY-TEST-A";
const BOND = "0x2dA07859613C14F6f05c97eFE37B9B4F212b5eF5";
const UAD = "0x0F644658510c95CB46955e55D7BA9DDa9E9fBEc6";
const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const USDT = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
const CRV3 = "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490";
const POOL3 = "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7";
const UAD3CRVF = "0x20955CB69Ae1515962177D164dfC9522feef567E";
const ethWhaleAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
const uadWhaleAddress = "0xefC0e701A824943b469a694aC564Aa1efF7Ab7dd";
const blockFork = 13097100;
const one = BigNumber.from(10).pow(18);
const onep = BigNumber.from(10).pow(6);
const ABI = [
"function balanceOf(address owner) view returns (uint256)",
"function allowance(address owner, address spender) external view returns (uint256)",
"function transfer(address to, uint amount) returns (boolean)",
"function remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_received) external returns (uint256)",
"function add_liquidity(uint256[3],uint256) returns (uint256)",
"function approve(address, uint256) external",
"function holderTokens(address) view returns (uint256[])",
"function getBond(uint256) view returns (tuple(address,uint256,uint256,uint256,uint256,uint256))"
];
let dsa: Contract;
let POOL3Contract: Contract;
let CRV3Contract: Contract;
let uAD3CRVfContract: Contract;
let uADContract: Contract;
let DAIContract: Contract;
let USDCContract: Contract;
let USDTContract: Contract;
let BONDContract: Contract;
let instaIndex: Contract;
let instaConnectorsV2: Contract;
let connector: Contract;
let instaImplementationsMapping;
let InstaAccountV2DefaultImpl;
let uadWhale;
const bondingShare = async function (address: any) {
let lpAmount = BigNumber.from(0);
let lpAmountTotal = BigNumber.from(0);
let bondId = -1;
const bondIds = await BONDContract.holderTokens(address);
const bondN = bondIds?.length || 0;
if (bondN) {
for await (bondId of bondIds) {
lpAmountTotal = lpAmountTotal.add((await BONDContract.getBond(bondId))[5]);
}
bondId = Number(bondIds[bondN - 1]);
lpAmount = (await BONDContract.getBond(bondId))[5];
}
return { bondId, bondN, lpAmount, lpAmountTotal };
};
const depositAndGetOneBond = async function () {
await dsaDepositUAD3CRVf(100);
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [UAD3CRVF, one.mul(100), 1, 0, 0]
}
]),
uadWhaleAddress
);
};
before(async () => {
// await forkReset(blockFork);
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 13097100,
},
},
],
});
[uadWhale] = await impersonateAccounts([uadWhaleAddress]);
const [ethWhale] = await impersonateAccounts([ethWhaleAddress]);
await sendEth(ethWhale, uadWhaleAddress, 100);
POOL3Contract = new ethers.Contract(POOL3, ABI, uadWhale);
CRV3Contract = new ethers.Contract(CRV3, ABI, uadWhale);
uAD3CRVfContract = new ethers.Contract(UAD3CRVF, ABI, uadWhale);
uADContract = new ethers.Contract(UAD, ABI, uadWhale);
DAIContract = new ethers.Contract(DAI, ABI, uadWhale);
USDCContract = new ethers.Contract(USDC, ABI, uadWhale);
USDTContract = new ethers.Contract(USDT, ABI, uadWhale);
BONDContract = new ethers.Contract(BOND, ABI, uadWhale);
dsa = (await buildDSAv2(uadWhaleAddress)).connect(uadWhale);
await sendEth(ethWhale, dsa.address, 100);
await sendEth(ethWhale, uadWhaleAddress, 100);
instaIndex = new ethers.Contract(addresses.core.instaIndex, abis.core.instaIndex, ethWhale);
const masterAddress = await instaIndex.master();
const [master] = await impersonateAccounts([masterAddress]);
await sendEth(ethWhale, masterAddress, 100);
instaConnectorsV2 = new ethers.Contract(addresses.core.connectorsV2, abis.core.connectorsV2);
instaImplementationsMapping = await ethers.getContractAt(implementationsABI, implementationsMappingAddr);
InstaAccountV2DefaultImpl = await ethers.getContractFactory("InstaDefaultImplementation");
InstaAccountV2DefaultImpl = await InstaAccountV2DefaultImpl.deploy(addresses.core.instaIndex);
await InstaAccountV2DefaultImpl.deployed();
await (
await instaImplementationsMapping.connect(master).setDefaultImplementation(InstaAccountV2DefaultImpl.address)
).wait();
connector = await deployAndEnableConnector({
connectorName: ubiquityTest,
contractArtifact: ConnectV2Ubiquity__factory,
signer: master,
connectors: instaConnectorsV2
});
});
const logAll = async function () {
console.log("dsa eth", utils.formatEther(await ethers.provider.getBalance(dsa.address)));
console.log("dsa dai", utils.formatEther(await DAIContract.balanceOf(dsa.address)));
console.log("dsa usdc", utils.formatUnits(await USDCContract.balanceOf(dsa.address), 6));
console.log("dsa usdt", utils.formatUnits(await USDTContract.balanceOf(dsa.address), 6));
console.log("dsa uad", utils.formatEther(await uADContract.balanceOf(dsa.address)));
console.log("dsa 3CRV", utils.formatEther(await CRV3Contract.balanceOf(dsa.address)));
console.log("dsa uad3CRV-f", utils.formatEther(await uAD3CRVfContract.balanceOf(dsa.address)));
const { bondId, bondN, lpAmount, lpAmountTotal } = await bondingShare(dsa.address);
console.log("dsa n bonds", utils.formatEther(lpAmountTotal), bondN);
console.log("dsa last bond", utils.formatEther(lpAmount), bondId);
};
afterEach(logAll);
const dsaDepositUAD3CRVf = async (amount: BigNumberish) => {
await uAD3CRVfContract.transfer(dsa.address, one.mul(amount));
};
const dsaDepositUAD = async (amount: BigNumberish) => {
await uAD3CRVfContract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 0, one.mul(amount));
await uADContract.transfer(dsa.address, one.mul(amount));
};
const dsaDepositCRV3 = async (amount: BigNumberish) => {
await uAD3CRVfContract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 1, one.mul(amount));
await CRV3Contract.transfer(dsa.address, one.mul(amount));
};
const dsaDepositDAI = async (amount: BigNumberish) => {
await uAD3CRVfContract.remove_liquidity_one_coin(
one.mul(amount).mul(120).div(100),
1,
one.mul(amount).mul(110).div(100)
);
await POOL3Contract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 0, one.mul(amount));
await DAIContract.transfer(dsa.address, one.mul(amount));
};
const dsaDepositUSDC = async (amount: BigNumberish) => {
await uAD3CRVfContract.remove_liquidity_one_coin(
one.mul(amount).mul(120).div(100),
1,
one.mul(amount).mul(110).div(100)
);
await POOL3Contract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 1, onep.mul(amount));
await USDCContract.transfer(dsa.address, onep.mul(amount));
};
const dsaDepositUSDT = async (amount: BigNumberish) => {
await uAD3CRVfContract.remove_liquidity_one_coin(
one.mul(amount).mul(120).div(100),
1,
one.mul(amount).mul(110).div(100)
);
await POOL3Contract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 2, onep.mul(amount));
await USDTContract.transfer(dsa.address, onep.mul(amount));
};
describe("Deposit", function () {
it("should deposit uAD3CRVf to get Ubiquity Bonding Shares", async function () {
await logAll();
await dsaDepositUAD3CRVf(100);
expect((await bondingShare(dsa.address)).lpAmount).to.be.equal(0);
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [UAD3CRVF, one.mul(100), 4, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
});
it("should deposit uAD to get Ubiquity Bonding Shares", async function () {
await dsaDepositUAD(100);
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [UAD, one.mul(100), 4, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
});
it("should deposit 3CRV to get Ubiquity Bonding Shares", async function () {
await dsaDepositCRV3(100);
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [CRV3, one.mul(100), 4, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
});
it("should deposit DAI to get Ubiquity Bonding Shares", async function () {
await dsaDepositDAI(100);
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [DAI, one.mul(100), 4, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
});
it("should deposit USDC to get Ubiquity Bonding Shares", async function () {
await dsaDepositUSDC(100);
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [USDC, onep.mul(100), 4, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
});
it("should deposit USDT to get Ubiquity Bonding Shares", async function () {
await dsaDepositUSDT(100);
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "deposit",
args: [USDT, onep.mul(100), 4, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
});
});
describe("Withdraw", function () {
let bondId = -1;
before(async () => {
await depositAndGetOneBond();
await depositAndGetOneBond();
await depositAndGetOneBond();
await depositAndGetOneBond();
await depositAndGetOneBond();
await depositAndGetOneBond();
({ bondId } = await bondingShare(dsa.address));
await logAll();
console.log("Mining 50 000 blocks for more than one week, please wait...");
await mineNBlock(50000, 1);
});
it("Should deposit and withdraw DAI", async function () {
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "withdraw",
args: [bondId, DAI, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
});
it("Should deposit and withdraw USDC", async function () {
// await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "withdraw",
args: [bondId - 1, USDC, 0, 0]
}
]),
uadWhaleAddress
);
// ).to.be.not.reverted;
});
it("Should deposit and withdraw USDT", async function () {
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "withdraw",
args: [bondId - 2, USDT, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
});
it("Should deposit and withdraw UAD", async function () {
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "withdraw",
args: [bondId - 3, UAD, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
});
it("Should deposit and withdraw CRV3", async function () {
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "withdraw",
args: [bondId - 4, CRV3, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
});
it("Should deposit and withdraw UAD3CRVF", async function () {
await expect(
dsa.cast(
...encodeSpells([
{
connector: ubiquityTest,
method: "withdraw",
args: [bondId - 5, UAD3CRVF, 0, 0]
}
]),
uadWhaleAddress
)
).to.be.not.reverted;
});
});
describe("DSA wallet setup", function () {
it("Should have contracts deployed.", async function () {
expect(POOL3Contract.address).to.be.properAddress;
expect(CRV3Contract.address).to.be.properAddress;
expect(uADContract.address).to.be.properAddress;
expect(uAD3CRVfContract.address).to.be.properAddress;
expect(DAIContract.address).to.be.properAddress;
expect(USDCContract.address).to.be.properAddress;
expect(USDTContract.address).to.be.properAddress;
expect(BONDContract.address).to.be.properAddress;
expect(instaIndex.address).to.be.properAddress;
expect(instaConnectorsV2.address).to.be.properAddress;
expect(connector.address).to.be.properAddress;
expect(dsa.address).to.be.properAddress;
});
it("Should deposit uAD3CRVf into DSA wallet", async function () {
await dsaDepositUAD3CRVf(100);
expect(await uAD3CRVfContract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
});
it("Should deposit uAD into DSA wallet", async function () {
await dsaDepositUAD(100);
expect(await uADContract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
});
it("Should deposit 3CRV into DSA wallet", async function () {
await dsaDepositCRV3(100);
expect(await CRV3Contract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
});
it("Should deposit DAI into DSA wallet", async function () {
await dsaDepositDAI(100);
expect(await DAIContract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
});
it("Should deposit USDC into DSA wallet", async function () {
await dsaDepositUSDC(100);
expect(await USDCContract.balanceOf(dsa.address)).to.be.gte(onep.mul(100));
});
it("Should deposit USDT into DSA wallet", async function () {
await dsaDepositUSDT(100);
expect(await USDTContract.balanceOf(dsa.address)).to.be.gte(onep.mul(100));
});
});
});