@gooddollar/goodprotocol
Version:
GoodDollar Protocol
314 lines (295 loc) • 9.93 kB
text/typescript
import { ethers, upgrades } from "hardhat";
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import {
UBIScheme,
GoodReserveCDai,
GoodMarketMaker,
GoodFundManager
} from "../../types";
import {
createDAO,
deployUBI,
advanceBlocks,
increaseTime,
deployUniswap,
getStakingFactory
} from "../helpers";
const BN = ethers.BigNumber;
export const NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
export const NULL_HASH =
"0x0000000000000000000000000000000000000000000000000000000000000000";
const NETWORK = "test";
const MAX_INACTIVE_DAYS = 15;
export const BLOCK_INTERVAL = 30;
async function proposeAndRegister(
addr,
registrar,
proposalId,
absoluteVote,
avatarAddress,
fnd
) {
const transaction = await registrar.proposeScheme(
avatarAddress,
addr,
NULL_HASH,
"0x00000010",
NULL_HASH
);
proposalId = transaction.logs[0].args._proposalId;
const voteResult = await absoluteVote.vote(proposalId, 1, 0, fnd);
return voteResult.logs.some(e => e.event === "ExecuteProposal");
}
describe("UBIScheme - network e2e tests", () => {
let dai,
cDAI,
simpleStaking,
goodReserve,
goodFundManager,
goodDollar,
controller,
ubi,
firstClaimPool,
identity,
claimer,
fisherman,
founder,
signers,
schemeMock,
comp,
marketMaker: GoodMarketMaker;
let avatar,
registrar,
absoluteVote,
proposalId,
setReserve,
addMinter,
setDAOAddress,
nameService,
initializeToken,
daiUsdOracle,
gasFeeOracle,
daiEthOracle,
ethUsdOracle;
before(async function () {
[founder, claimer, fisherman, ...signers] = await ethers.getSigners();
schemeMock = signers.pop();
const cdaiFactory = await ethers.getContractFactory("cDAIMock");
const goodFundManagerFactory = await ethers.getContractFactory(
"GoodFundManager"
);
const goodCompoundStakingFactory = await getStakingFactory(
"GoodCompoundStakingV2"
);
const deployedDAO = await loadFixture(createDAO);
let {
controller: ctrl,
avatar: av,
gd,
identity,
identityDeployed,
daoCreator,
nameService: ns,
setDAOAddress: sda,
setSchemes,
marketMaker: mm,
daiAddress,
cdaiAddress,
reserve,
setReserveToken,
addWhitelisted,
COMP
} = deployedDAO;
dai = await ethers.getContractAt("DAIMock", daiAddress);
cDAI = await ethers.getContractAt("cDAIMock", cdaiAddress);
avatar = av;
marketMaker = mm;
controller = ctrl;
setDAOAddress = sda;
nameService = ns;
initializeToken = setReserveToken;
goodReserve = reserve as GoodReserveCDai;
const tokenUsdOracleFactory = await ethers.getContractFactory(
"BatUSDMockOracle"
);
const compUsdOracleFactory = await ethers.getContractFactory(
"CompUSDMockOracle"
);
const compUsdOracle = await compUsdOracleFactory.deploy();
daiUsdOracle = await tokenUsdOracleFactory.deploy();
const daiFactory = await ethers.getContractFactory("DAIMock");
comp = COMP;
const uniswap = await deployUniswap(comp, dai);
await setDAOAddress("UNISWAP_ROUTER", uniswap.router.address);
await setDAOAddress("COMP", comp.address);
simpleStaking = await goodCompoundStakingFactory
.deploy()
.then(async contract => {
await contract.init(
dai.address,
cDAI.address,
nameService.address,
"Good DAI",
"gDAI",
"172800",
daiUsdOracle.address,
compUsdOracle.address,
[]
);
return contract;
});
goodFundManager = (await upgrades.deployProxy(
goodFundManagerFactory,
[nameService.address],
{
kind: "uups"
}
)) as GoodFundManager;
console.log("Deployed goodfund manager", {
manager: goodFundManager.address
});
goodDollar = await ethers.getContractAt("IGoodDollar", gd);
const ubiScheme = await deployUBI(deployedDAO);
ubi = ubiScheme.ubiScheme;
firstClaimPool = ubiScheme.firstClaim;
await setDAOAddress("CDAI", cDAI.address);
await setDAOAddress("DAI", dai.address);
await goodReserve.setAddresses();
const ictrl = await ethers.getContractAt(
"Controller",
controller,
schemeMock
);
const currentBlockNumber = await ethers.provider.getBlockNumber();
const encodedData = goodFundManagerFactory.interface.encodeFunctionData(
"setStakingReward",
[
"1000",
simpleStaking.address,
currentBlockNumber - 5,
currentBlockNumber + 1000,
false
] // set 10 gd per block
);
const gasFeeMockFactory = await ethers.getContractFactory(
"GasPriceMockOracle"
);
gasFeeOracle = await gasFeeMockFactory.deploy();
const daiEthPriceMockFactory = await ethers.getContractFactory(
"DaiEthPriceMockOracle"
);
daiEthOracle = await daiEthPriceMockFactory.deploy();
const ethUsdOracleFactory = await ethers.getContractFactory(
"EthUSDMockOracle"
);
ethUsdOracle = await ethUsdOracleFactory.deploy();
await ictrl.genericCall(goodFundManager.address, encodedData, avatar, 0);
console.log("staking reward set...");
await setDAOAddress("ETH_USD_ORACLE", ethUsdOracle.address);
await setDAOAddress("GAS_PRICE_ORACLE", gasFeeOracle.address);
await setDAOAddress("DAI_ETH_ORACLE", daiEthOracle.address);
await setDAOAddress("MARKET_MAKER", marketMaker.address);
await setDAOAddress("FUND_MANAGER", goodFundManager.address);
let amount = 1e8;
await dai["mint(address,uint256)"](
founder.address,
ethers.utils.parseEther("1000")
);
dai.approve(simpleStaking.address, ethers.utils.parseEther("1000"));
await simpleStaking.stake(ethers.utils.parseEther("1000"), 0, false);
await cDAI["mint(address,uint256)"](
founder.address,
ethers.utils.parseUnits("1000", 8)
);
await cDAI.approve(goodReserve.address, amount);
await goodReserve.buy(amount, 0, NULL_ADDRESS);
let gdbalance = await goodDollar.balanceOf(founder.address);
await goodDollar.transfer(firstClaimPool.address, gdbalance.toString());
// transfers funds to the ubi
await cDAI.increasePriceWithMultiplier("10000"); // Generate some interests
await goodFundManager.collectInterest([simpleStaking.address], false);
await addWhitelisted(claimer.address, "claimer1");
});
it("should award a new user with the award amount on first time execute claim", async () => {
await increaseTime(86400);
let claimerBalance1 = await goodDollar.balanceOf(claimer.address);
let ce = await ubi.connect(claimer)["checkEntitlement()"]();
await ubi.connect(claimer).claim();
let claimerBalance2 = await goodDollar.balanceOf(claimer.address);
expect(claimerBalance2.sub(claimerBalance1).toNumber()).to.be.equal(
ce.toNumber()
);
});
it("should not be able to fish an active user", async () => {
let error = await ubi
.connect(fisherman)
.fish(claimer.address)
.catch(e => e);
await goodDollar.balanceOf(fisherman.address);
expect(error.message).to.have.string("can't fish");
});
it("should be able to fish inactive user", async () => {
await increaseTime(MAX_INACTIVE_DAYS * 86700);
let balance1 = await goodDollar.balanceOf(fisherman.address);
await ubi.connect(fisherman).fish(claimer.address);
let isFished = await ubi.fishedUsersAddresses(claimer.address);
let balance2 = await goodDollar.balanceOf(fisherman.address);
let dailyUbi = await ubi.dailyUbi();
expect(isFished).to.be.true;
expect(balance2.toNumber() - balance1.toNumber()).to.be.equal(
dailyUbi.toNumber()
);
});
it("should not be able to fish the same user twice", async () => {
let error = await ubi
.connect(fisherman)
.fish(claimer.address)
.catch(e => e);
expect(error.message).to.have.string("can't fish");
});
it("should recieves a claim reward when call claim after being fished", async () => {
let activeUsersCountBefore = await ubi.activeUsersCount();
let claimerBalanceBefore = await goodDollar.balanceOf(claimer.address);
await ubi.connect(claimer).claim();
let claimerBalanceAfter = await goodDollar.balanceOf(claimer.address);
let activeUsersCountAfter = await ubi.activeUsersCount();
expect(
activeUsersCountAfter.toNumber() - activeUsersCountBefore.toNumber()
).to.be.equal(1);
expect(
claimerBalanceAfter.toNumber() - claimerBalanceBefore.toNumber()
).to.be.equal(1000);
});
it("should be able to fish by calling fishMulti", async () => {
await increaseTime(MAX_INACTIVE_DAYS * 86700);
let amount = 1e8;
await dai["mint(address,uint256)"](
founder.address,
ethers.utils.parseEther("1000")
);
dai.approve(cDAI.address, ethers.utils.parseEther("1000"));
await cDAI["mint(address,uint256)"](
founder.address,
ethers.utils.parseUnits("1000", 8)
);
await cDAI.approve(goodReserve.address, amount);
await goodReserve.buy(amount, 0, NULL_ADDRESS);
let gdbalance = await goodDollar.balanceOf(founder.address);
await goodDollar.transfer(
firstClaimPool.address,
Math.floor(gdbalance.toNumber() / 2).toString()
);
await goodDollar.transfer(
ubi.address,
Math.floor(gdbalance.toNumber() / 2).toString()
);
let balanceBefore = await goodDollar.balanceOf(fisherman.address);
await ubi.connect(fisherman).fishMulti([claimer.address]);
let balanceAfter = await goodDollar.balanceOf(fisherman.address);
let dailyUbi = await ubi.dailyUbi();
expect(balanceAfter.toNumber() - balanceBefore.toNumber()).to.be.equal(
dailyUbi.toNumber()
);
});
});