contracts-imtbl/test/testVester.ts
2024-08-27 15:13:22 +08:00

273 lines
13 KiB
TypeScript

import {expect} from "chai";
import hre from "hardhat";
import {getBytes, solidityPackedKeccak256, ZeroAddress} from "ethers";
import {loadFixture} from "@nomicfoundation/hardhat-toolbox/network-helpers";
import {expandDecimals, getBlockTime, increaseTime, mineBlock} from "./shared/utilities";
const secondsPerYear = 365 * 24 * 60 * 60;
describe("Vester", function () {
async function deployOneContract() {
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount] = await hre.ethers.getSigners();
const verifier = owner.address;
const chainId = hre.network.config.chainId;
const Cec = await hre.ethers.getContractFactory("MintableBaseToken");
const cec = await Cec.deploy("test cec", "cec");
const esCec = await Cec.deploy("test esCec", "esCec");
await cec.setMinter(owner.address, true);
await esCec.setMinter(owner.address, true);
const Vester = await hre.ethers.getContractFactory("Vester");
const vester = await Vester.deploy(
"Vested CEC",
"veCEC",
secondsPerYear,
esCec.target,
ZeroAddress,
cec.target,
ZeroAddress,
);
await cec.mint(owner.address, expandDecimals(100000, 18));
await esCec.mint(owner.address, expandDecimals(100000, 18));
return {owner, otherAccount, chainId, cec, esCec, vester};
}
describe("Deployment", function () {
it("should deploy Vester", async function () {
const {cec, esCec, vester} = await loadFixture(deployOneContract);
expect(await vester.name()).eq("Vested CEC");
expect(await vester.symbol()).eq("veCEC");
expect(await vester.vestingDuration()).eq(secondsPerYear);
expect(await vester.esToken()).eq(esCec.target);
expect(await vester.pairToken()).eq(ZeroAddress);
expect(await vester.claimableToken()).eq(cec.target);
expect(await vester.rewardTracker()).eq(ZeroAddress);
expect(await vester.hasPairToken()).eq(false);
expect(await vester.hasRewardTracker()).eq(false);
});
it("setTransferredAverageStakedAmounts", async () => {
const {owner, otherAccount, cec, esCec, vester} = await loadFixture(deployOneContract);
await expect(vester.setTransferredAverageStakedAmounts(owner.address, 200)).to.be.revertedWith(
"Vester: forbidden",
);
await vester.setHandler(owner.address, true);
expect(await vester.transferredAverageStakedAmounts(owner.address)).eq(0);
await vester.setTransferredAverageStakedAmounts(owner.address, 200);
expect(await vester.transferredAverageStakedAmounts(owner.address)).eq(200);
});
it("setTransferredCumulativeRewards", async () => {
const {owner, otherAccount, cec, esCec, vester} = await loadFixture(deployOneContract);
await expect(vester.setTransferredCumulativeRewards(owner.address, 200)).to.be.revertedWith("Vester: forbidden");
await vester.setHandler(owner.address, true);
expect(await vester.transferredCumulativeRewards(owner.address)).eq(0);
await vester.setTransferredCumulativeRewards(owner.address, 200);
expect(await vester.transferredCumulativeRewards(owner.address)).eq(200);
});
it("setCumulativeRewardDeductions", async () => {
const {owner, otherAccount, cec, esCec, vester} = await loadFixture(deployOneContract);
await expect(vester.setCumulativeRewardDeductions(owner.address, 200)).to.be.revertedWith("Vester: forbidden");
await vester.setHandler(owner.address, true);
expect(await vester.cumulativeRewardDeductions(owner.address)).eq(0);
await vester.setCumulativeRewardDeductions(owner.address, 200);
expect(await vester.cumulativeRewardDeductions(owner.address)).eq(200);
});
it("setBonusRewards", async () => {
const {owner, otherAccount, cec, esCec, vester} = await loadFixture(deployOneContract);
await expect(vester.setBonusRewards(owner.address, 200)).to.be.revertedWith("Vester: forbidden");
await vester.setHandler(owner.address, true);
expect(await vester.bonusRewards(owner.address)).eq(0);
await vester.setBonusRewards(owner.address, 200);
expect(await vester.bonusRewards(owner.address)).eq(200);
});
it("deposit, claim, withdraw", async () => {
const {owner, otherAccount, cec, esCec, vester} = await loadFixture(deployOneContract);
const wallet = owner;
const user0 = otherAccount;
const provider = wallet.provider;
await vester.setHandler(wallet.address, true);
await esCec.setMinter(vester.target, true);
// @ts-ignore
await expect(vester.connect(user0).deposit(0)).to.be.revertedWith("Vester: invalid _amount");
// @ts-ignore
await expect(vester.connect(user0).deposit(expandDecimals(1000, 18))).to.be.revertedWith(
"ERC20: insufficient allowance",
);
// @ts-ignore
await esCec.connect(user0).approve(vester.target, expandDecimals(1000, 18));
// @ts-ignore
await expect(vester.connect(user0).deposit(expandDecimals(1000, 18))).to.be.revertedWith(
"ERC20: transfer amount exceeds balance",
);
expect(await vester.balanceOf(user0.address)).eq(0);
expect(await vester.getTotalVested(user0.address)).eq(0);
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(0);
expect(await vester.claimedAmounts(user0.address)).eq(0);
expect(await vester.claimable(user0.address)).eq(0);
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(0);
await esCec.mint(user0.address, expandDecimals(1000, 18));
await vester.setBonusRewards(user0.address, expandDecimals(10_000, 18));
// @ts-ignore
await vester.connect(user0).deposit(expandDecimals(1000, 18));
let blockTime = await getBlockTime(provider);
expect(await vester.balanceOf(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.getTotalVested(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(0);
expect(await vester.claimedAmounts(user0.address)).eq(0);
expect(await vester.claimable(user0.address)).eq(0);
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(blockTime);
await increaseTime(provider, 24 * 60 * 60);
await mineBlock(provider);
expect(await esCec.balanceOf(user0.address)).eq(0);
expect(await cec.balanceOf(user0.address)).eq(0);
expect(await vester.balanceOf(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.getTotalVested(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(0);
expect(await vester.claimedAmounts(user0.address)).eq(0);
expect(await vester.claimable(user0.address)).gt("2730000000000000000"); // 1000 / 365 => ~2.739
expect(await vester.claimable(user0.address)).lt("2750000000000000000");
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(blockTime);
// @ts-ignore
await expect(vester.connect(user0).claim()).to.be.revertedWith("ERC20: transfer amount exceeds balance");
await cec.mint(vester.target, expandDecimals(2000, 18));
// @ts-ignore
await vester.connect(user0).claim();
blockTime = await getBlockTime(provider);
expect(await esCec.balanceOf(user0.address)).eq(0);
expect(await cec.balanceOf(user0.address)).gt("2730000000000000000");
expect(await cec.balanceOf(user0.address)).lt("2750000000000000000");
let cecAmount = await cec.balanceOf(user0.address);
expect(await vester.balanceOf(user0.address)).eq(expandDecimals(1000, 18) - cecAmount);
expect(await vester.getTotalVested(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimedAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimable(user0.address)).eq(0);
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(blockTime);
await increaseTime(provider, 48 * 60 * 60);
await mineBlock(provider);
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimedAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimable(user0.address)).gt("5478000000000000000"); // 1000 / 365 * 2 => ~5.479
expect(await vester.claimable(user0.address)).lt("5480000000000000000");
await increaseTime(provider, parseInt(365 / 2 - 1 + "") * 24 * 60 * 60);
await mineBlock(provider);
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimedAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimable(user0.address)).gt(expandDecimals(500, 18)); // 1000 / 2 => 500
expect(await vester.claimable(user0.address)).lt(expandDecimals(502, 18));
// @ts-ignore
await vester.connect(user0).claim();
blockTime = await getBlockTime(provider);
expect(await esCec.balanceOf(user0.address)).eq(0);
expect(await cec.balanceOf(user0.address)).gt(expandDecimals(503, 18));
expect(await cec.balanceOf(user0.address)).lt(expandDecimals(505, 18));
cecAmount = await cec.balanceOf(user0.address);
expect(await vester.balanceOf(user0.address)).eq(expandDecimals(1000, 18) - cecAmount);
expect(await vester.getTotalVested(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimedAmounts(user0.address)).eq(cecAmount);
expect(await vester.claimable(user0.address)).eq(0);
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(blockTime);
await increaseTime(provider, 24 * 60 * 60);
await mineBlock(provider);
// vesting rate should be the same even after claiming
expect(await vester.claimable(user0.address)).gt("2730000000000000000"); // 1000 / 365 => ~2.739
expect(await vester.claimable(user0.address)).lt("2750000000000000000");
await esCec.mint(user0.address, expandDecimals(500, 18));
// @ts-ignore
await esCec.connect(user0).approve(vester.target, expandDecimals(500, 18));
// @ts-ignore
await vester.connect(user0).deposit(expandDecimals(500, 18));
await increaseTime(provider, 24 * 60 * 60);
await mineBlock(provider);
expect(await vester.claimable(user0.address)).gt("6840000000000000000"); // 1000 / 365 + 1500 / 365 => 6.849
expect(await vester.claimable(user0.address)).lt("6860000000000000000");
expect(await esCec.balanceOf(user0.address)).eq(0);
expect(await cec.balanceOf(user0.address)).eq(cecAmount);
// @ts-ignore
await vester.connect(user0).withdraw();
expect(await esCec.balanceOf(user0.address)).gt(expandDecimals(989, 18));
expect(await esCec.balanceOf(user0.address)).lt(expandDecimals(990, 18));
expect(await cec.balanceOf(user0.address)).gt(expandDecimals(510, 18));
expect(await cec.balanceOf(user0.address)).lt(expandDecimals(512, 18));
expect(await vester.balanceOf(user0.address)).eq(0);
expect(await vester.getTotalVested(user0.address)).eq(0);
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(0);
expect(await vester.claimedAmounts(user0.address)).eq(0);
expect(await vester.claimable(user0.address)).eq(0);
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(0);
// @ts-ignore
await esCec.connect(user0).approve(vester.target, expandDecimals(1000, 18));
await esCec.mint(user0.address, expandDecimals(1000, 18));
// @ts-ignore
await vester.connect(user0).deposit(expandDecimals(1000, 18));
blockTime = await getBlockTime(provider);
await increaseTime(provider, 24 * 60 * 60);
await mineBlock(provider);
expect(await vester.balanceOf(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.getTotalVested(user0.address)).eq(expandDecimals(1000, 18));
expect(await vester.cumulativeClaimAmounts(user0.address)).eq(0);
expect(await vester.claimedAmounts(user0.address)).eq(0);
expect(await vester.claimable(user0.address)).gt("2730000000000000000"); // 1000 / 365 => ~2.739
expect(await vester.claimable(user0.address)).lt("2750000000000000000");
expect(await vester.pairAmounts(user0.address)).eq(0);
expect(await vester.lastVestingTimes(user0.address)).eq(blockTime);
// @ts-ignore
await vester.connect(user0).claim();
});
});
});