@gooddollar/goodprotocol
Version:
GoodDollar Protocol
162 lines (134 loc) • 7.43 kB
text/typescript
import { ethers, upgrades } from "hardhat";
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import { UBIScheme } from "../../types";
import { createDAO, deployUBI, advanceBlocks, increaseTime } from "../helpers";
const BN = ethers.BigNumber;
export const NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
const MAX_INACTIVE_DAYS = 3;
const ONE_DAY = 86400;
describe("UBIScheme cycle", () => {
let goodDollar, firstClaimPool;
let reputation;
let root, acct, claimer1, claimer2, claimer3, signers, nameService, genericCall, ubiScheme: UBIScheme;
before(async () => {
[] = await ethers.getSigners();
const deployedDAO = await loadFixture(createDAO);
let {
nameService: ns,
genericCall: gn,
reputation: rep,
setDAOAddress,
setSchemes,
addWhitelisted,
gd
} = deployedDAO;
nameService = ns;
genericCall = gn;
reputation = rep;
goodDollar = await ethers.getContractAt("IGoodDollar", gd);
let ubi = await deployUBI(deployedDAO);
ubiScheme = ubi.ubiScheme as UBIScheme;
firstClaimPool = ubi.firstClaim;
// setDAOAddress("GDAO_CLAIMERS", cd.address);
addWhitelisted(claimer1.address, "claimer1");
await addWhitelisted(claimer2.address, "claimer2");
// await increaseTime(60 * 60 * 24);
});
it("should deploy the ubi with default cycle of 30 days", async () => {
expect(await ubiScheme.cycleLength()).to.equal(30);
});
it("should not be able to change cycleLength if not avatar", async () => {
let error = await ubiScheme.setCycleLength(1).catch(e => e);
expect(error.message).to.have.string("only avatar can call this method");
});
it("should be able to change cycleLength if avatar", async () => {
// initializing the ubi
let encodedCall = ubiScheme.interface.encodeFunctionData("setCycleLength", [8]);
await genericCall(ubiScheme.address, encodedCall);
expect(await ubiScheme.cycleLength()).to.be.equal(8);
});
it("should start the ubi cycle at noon", async () => {
const newUbi = await firstClaimPool.ubi();
let periodStart = await ubiScheme.periodStart().then(_ => _.toNumber());
let startDate = new Date(periodStart * 1000);
expect(startDate.toISOString()).to.have.string("T12:00:00.000Z");
expect(newUbi.toString()).to.be.equal(ubiScheme.address);
});
it("should set ubischeme", async () => {
// initializing the ubi
let encodedCall = firstClaimPool.interface.encodeFunctionData("setUBIScheme", [ubiScheme.address]);
await genericCall(firstClaimPool.address, encodedCall);
// await firstClaimPool.start();
});
it("should calculate cycle on first day", async () => {
await increaseTime(2 * ONE_DAY); //make sure
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait();
await ubiScheme.connect(claimer2).claim();
let cycleLength = await ubiScheme.cycleLength();
let currentCycle = await ubiScheme.currentCycleLength();
let balance = await goodDollar.balanceOf(ubiScheme.address);
expect(currentCycle.toNumber()).to.be.gt(0);
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
expect(cycleEvent.args.day.toNumber()).to.be.a("number");
expect(cycleEvent.args.pool).to.be.equal(balance);
expect(cycleEvent.args.cycleLength).to.be.equal(cycleLength);
expect(cycleEvent.args.dailyUBIPool).to.be.equal(balance.div(cycleLength));
});
it("should have calculated dailyCyclePool and dailyUbi correctly", async () => {
increaseTime(ONE_DAY);
let transaction = await ubiScheme.connect(claimer2).claim();
expect(await goodDollar.balanceOf(claimer2.address).then(_ => _.toNumber())).to.be.equal(
1000 + (await ubiScheme.dailyUbi().then(_ => _.toNumber()))
); //first day 10G$ (1000 wei), second claim 125000 wei daily pool divided by 2 active users = 625000
expect(await ubiScheme.dailyCyclePool().then(_ => _.toNumber())).to.be.equal(125000);
expect(await ubiScheme.currentDayInCycle().then(_ => _.toNumber())).to.be.equal(1); //1 day passed
});
it("should calculate next cycle even if day passed without claims(setDay)", async () => {
increaseTime(ONE_DAY * 9);
expect(await ubiScheme.currentDayInCycle().then(_ => _.toNumber())).to.be.equal(10); //10 days passed total
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait(); //claims in new ubi cycle
let dailyClaimAmount = (await ubiScheme.dailyCyclePool()).div(1000); //initialy we have by default min 1000 active users
expect(await goodDollar.balanceOf(claimer1.address)).to.be.equal(dailyClaimAmount.add(1000)); //intial 10 from first claim pool + daily
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
expect(cycleEvent).to.be.not.empty;
expect(await ubiScheme.currentDayInCycle().then(_ => _.toNumber())).to.be.equal(0); //new cycle started
//intial balance on cycle start 1000000 - 125(one user that claimed) = 999875, divide by cycle length (8) = 124984
expect(cycleEvent.args.dailyUBIPool).to.be.equal(124984);
});
it("should calculate cycle early if we can increase current daily pool", async () => {
//increase ubi pool balance
let encoded = goodDollar.interface.encodeFunctionData("mint", [ubiScheme.address, 400000]);
await genericCall(goodDollar.address, encoded);
let balance = await goodDollar.balanceOf(ubiScheme.address);
const cycleLength = await ubiScheme.cycleLength();
const curDailyPool = await ubiScheme.dailyCyclePool();
//verify new daily pool IS gonna be larger than current
expect(balance.div(cycleLength)).to.be.gt(curDailyPool);
const estimated = await ubiScheme.estimateNextDailyUBI();
await increaseTime(ONE_DAY); //make sure
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait();
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
const dailyUBI = await ubiScheme.dailyUbi();
expect(dailyUBI).to.eq(estimated); //the estimated before actual calculation should be correct, ie equal to actual dailyUBI calculated after first claim.
expect(cycleEvent).to.be.not.empty;
expect(cycleEvent.args.day.toNumber()).to.be.a("number");
expect(cycleEvent.args.pool).to.be.equal(balance);
expect(cycleEvent.args.cycleLength).to.be.equal(cycleLength);
expect(cycleEvent.args.dailyUBIPool).to.be.equal(balance.div(cycleLength));
});
it("should not calculate cycle early if not possible to increase daily ubi pool", async () => {
//increase ubi pool balance
let encoded = goodDollar.interface.encodeFunctionData("mint", [ubiScheme.address, 100]);
await genericCall(goodDollar.address, encoded);
let balance = await goodDollar.balanceOf(ubiScheme.address);
const curCycleLen = await ubiScheme.cycleLength();
const curDailyPool = await ubiScheme.dailyCyclePool();
//verify new daily pool is not gonna be larger than current
expect(balance.div(curCycleLen)).to.be.lt(curDailyPool);
await increaseTime(ONE_DAY); //make sure
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait();
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
expect(cycleEvent).to.be.undefined;
});
});