import { expect } from 'chai' import hre from "hardhat"; import { ZeroAddress, getBytes, solidityPackedKeccak256, formatEther, JsonRpcProvider, } from 'ethers' import { loadFixture, } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { expandDecimals, increaseTime, mineBlock, reportGasUsed } from './shared/utilities'; const secondsOneDay = BigInt(24 * 60 * 60); const secondsPerYear = 365 * 24 * 60 * 60; // 1.5 / (365*24*60*60) const rewardPerSecond = BigInt(1.5 * 10 ** 18) / BigInt(secondsPerYear) ; // 47564688000 console.log('rewardPerSecond: ', rewardPerSecond.toString()) const blockTime = async (provider: any) => { const block = await provider.getBlock('latest') return block ? block.timestamp : 0 } const showLog = async (tag: string, stakedCecTracker: any, esCec: any, address: string) => { console.log(tag+'\t', 'stake amount:', formatEther(await stakedCecTracker.stakedAmounts(address)), 'claimable: ', formatEther(await stakedCecTracker.claimable(address)), 'claimableReward: ', formatEther(await stakedCecTracker.claimableReward(address)), 'esCec balance: ', formatEther(await esCec.balanceOf(address)), ) } describe('RewardRouter', function() { async function deployOneContract() { // Contracts are deployed using the first signer/account by default const [owner, user0, user1, user2] = await hre.ethers.getSigners(); const chainId = hre.network.config.chainId const Cec = await hre.ethers.getContractFactory("MintableBaseToken"); const cec = await Cec.deploy("test cec", "cec"); const EsToken = await hre.ethers.getContractFactory("EsToken"); const esCec = await EsToken.deploy("test esCec", "esCec"); const RewardTracker = await hre.ethers.getContractFactory("RewardTracker"); const stakedCecTracker = await RewardTracker.deploy(esCec.target, cec.target, rewardPerSecond, 18); const Vester = await hre.ethers.getContractFactory("Vester"); const vester = await Vester.deploy( "Vested CEC", "veCEC", secondsPerYear, esCec.target, cec.target, stakedCecTracker.target, ZeroAddress, false ); await stakedCecTracker.setInPrivateStakingMode(true) await esCec.setInPrivateTransferMode(true) const RewardRouter = await hre.ethers.getContractFactory("RewardRouter"); const rewardRouter = await RewardRouter.deploy( cec.target, stakedCecTracker.target, vester.target, ); await esCec.setMinter(owner.address, true) await esCec.setHandler(owner.address, true) await esCec.mint(stakedCecTracker.target, expandDecimals(50000, 18)) await stakedCecTracker.setHandler(rewardRouter.target, true) await esCec.setMinter(vester.target, true) await esCec.setHandler(stakedCecTracker.target, true) return { owner, user0, user1, user2, chainId, cec, esCec, stakedCecTracker, vester, rewardRouter }; } describe("Deployment", function () { it('should deploy RewardRouter', async function() { const { chainId } = await loadFixture(deployOneContract); // expect((await nftClaimer.mintConfig()).mintPrice).to.equal(100); }); }) describe("Staking CEC", function () { it("stakeCecForAccount, stakeCec, stakeEsCec, unstakeCec, unstakeEsCec, claimEsCec", async () => { const {owner, user0, user1, user2, chainId, cec, esCec, stakedCecTracker, vester, rewardRouter} = await loadFixture(deployOneContract); const wallet = owner const provider = wallet.provider; await cec.setMinter(wallet.address, true) await cec.mint(user0.address, expandDecimals(1500, 18)) expect(await cec.balanceOf(user0.address)).eq(expandDecimals(1500, 18)) // @ts-ignore await cec.connect(user0).approve(stakedCecTracker.target, expandDecimals(1000, 18)) // @ts-ignore await expect(rewardRouter.connect(user0).batchStakeCecForAccount([user1.address], [expandDecimals(1000, 18)])) .to.be.revertedWith("Governable: forbidden") await rewardRouter.setGov(user0.address) // @ts-ignore await rewardRouter.connect(user0).batchStakeCecForAccount([user1.address], [expandDecimals(800, 18)]) let startTime = await blockTime(provider) console.log('startTime: ', startTime) expect(await cec.balanceOf(user0.address)).eq(expandDecimals(700, 18)) await cec.mint(user1.address, expandDecimals(200, 18)) expect(await cec.balanceOf(user1.address)).eq(expandDecimals(200, 18)) let nowTime = await blockTime(provider) console.log('nowTime: ', nowTime) let reward = BigInt(800) * BigInt(nowTime - startTime) * rewardPerSecond //@ts-ignore expect(await stakedCecTracker.claimable(user1.address)).eq(reward) // @ts-ignore await cec.connect(user1).approve(stakedCecTracker.target, expandDecimals(200, 18)) // @ts-ignore await rewardRouter.connect(user1).stakeCec(expandDecimals(200, 18)) let preTime = nowTime nowTime = await blockTime(provider) console.log('nowTime: ', nowTime) let _reward = BigInt(800) * BigInt(nowTime - preTime) * rewardPerSecond reward += _reward expect(await stakedCecTracker.claimable(user1.address)).eq(reward) expect(await cec.balanceOf(user1.address)).eq(0) expect(await stakedCecTracker.stakedAmounts(user0.address)).eq(0) expect(await stakedCecTracker.stakedAmounts(user1.address)).eq(expandDecimals(1000, 18)) await showLog('init', stakedCecTracker, esCec, user1.address) await increaseTime(provider, Number(secondsOneDay)) await mineBlock(provider) await showLog('1day', stakedCecTracker, esCec, user1.address) expect(await stakedCecTracker.claimable(user0.address)).eq(0) console.log('blockTime: ', await blockTime(provider)) preTime = nowTime nowTime = await blockTime(provider) console.log('nowTime: ', nowTime) _reward = BigInt(1000) * BigInt(nowTime - preTime) * rewardPerSecond reward += _reward expect(await stakedCecTracker.claimable(user1.address)).eq(reward) await increaseTime(provider, 20) await mineBlock(provider) // await timelock.processMint(esCec.target, tokenManager.address, expandDecimals(500, 18)) // await esCec.connect(tokenManager).transferFrom(tokenManager.address, user2.address, expandDecimals(500, 18)) await cec.mint(user2.address, expandDecimals(500, 18)) // @ts-ignore await cec.connect(user2).approve(stakedCecTracker.target, expandDecimals(500, 18)) // @ts-ignore await rewardRouter.connect(user2).stakeCec(expandDecimals(500, 18)) let startTime2 = await blockTime(provider) expect(await stakedCecTracker.stakedAmounts(user0.address)).eq(0) expect(await stakedCecTracker.stakedAmounts(user1.address)).eq(expandDecimals(1000, 18)) expect(await stakedCecTracker.stakedAmounts(user2.address)).eq(expandDecimals(500, 18)) await increaseTime(provider, Number(secondsOneDay)) await mineBlock(provider) expect(await stakedCecTracker.claimable(user0.address)).eq(0) preTime = nowTime nowTime = await blockTime(provider) console.log('nowTime: ', nowTime) _reward = BigInt(1000) * BigInt(nowTime - preTime) * rewardPerSecond reward += _reward expect(await stakedCecTracker.claimable(user1.address)).eq(reward) let preTime2 = startTime2 let nowTime2 = await blockTime(provider) let reward2 = BigInt(500) * BigInt(nowTime2 - preTime2) * rewardPerSecond expect(await stakedCecTracker.claimable(user2.address)).eq(reward2) await showLog('2day', stakedCecTracker, esCec, user1.address) expect(await esCec.balanceOf(user1.address)).eq(0) // @ts-ignore await rewardRouter.connect(user1).claim() preTime = nowTime nowTime = await blockTime(provider) console.log('nowTime: ', nowTime) _reward = BigInt(1000) * BigInt(nowTime - preTime) * rewardPerSecond reward += _reward expect(await esCec.balanceOf(user1.address)).eq(reward) expect(await stakedCecTracker.claimable(user1.address)).eq(0) expect(await esCec.balanceOf(user2.address)).eq(0) // @ts-ignore await rewardRouter.connect(user2).claim() preTime = nowTime2 nowTime2 = await blockTime(provider) console.log('nowTime: ', nowTime) reward2 = BigInt(500) * BigInt(nowTime2 - preTime2) * rewardPerSecond expect(await esCec.balanceOf(user2.address)).eq(reward2) await increaseTime(provider, Number(secondsOneDay)) await mineBlock(provider) await increaseTime(provider, Number(secondsOneDay)) await mineBlock(provider) await showLog('claim cec 2day', stakedCecTracker, esCec, user1.address) //@ts-ignore await rewardRouter.connect(user1).claim() }) }) })