248 lines
12 KiB
TypeScript
248 lines
12 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,
|
|
false
|
|
);
|
|
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("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();
|
|
});
|
|
});
|
|
});
|