/* Copyright 2021 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ import { decimalStr, fromWei } from '../utils/Converter'; import { logGas } from '../utils/Log'; import { DODOMineV2Context, getDODOMineContext } from '../utils/DODOMineV2Context'; import { assert } from 'chai'; import { Contract } from 'web3-eth-contract'; let account0: string; let account1: string; let projector: string; async function init(ctx: DODOMineV2Context): Promise { projector = ctx.Deployer; account0 = ctx.SpareAccounts[0]; account1 = ctx.SpareAccounts[1]; //For User await ctx.mintTestToken(account0, ctx.ERC20, decimalStr("1000")); await ctx.mintTestToken(account1, ctx.ERC20, decimalStr("500")); //For Project await ctx.mintTestToken(projector, ctx.REWARD_1, decimalStr("1000000")); await ctx.mintTestToken(projector, ctx.REWARD_2, decimalStr("1000000")); await ctx.approveProxy(account0, ctx.ERC20Mine.options.address, ctx.ERC20); await ctx.approveProxy(account1, ctx.ERC20Mine.options.address, ctx.ERC20); } async function addRewardToken(ctx: DODOMineV2Context, token: Contract, start: number, end: number, rewardPerBlock: string) { await ctx.ERC20Mine.methods.addRewardToken( token.options.address, rewardPerBlock, start, end ).send(ctx.sendParam(projector)); let idx = await ctx.ERC20Mine.methods.getIdByRewardToken(token.options.address).call(); let rewardInfo = await ctx.ERC20Mine.methods.rewardTokenInfos(idx).call(); await token.methods.transfer(rewardInfo.rewardVault, decimalStr("10000")).send(ctx.sendParam(projector)); } async function stakeInfo(ctx: DODOMineV2Context, user: string, logInfo?: string) { console.log(logInfo) let totalSupply = await ctx.ERC20Mine.methods.totalSupply().call(); let balance = await ctx.ERC20Mine.methods.balanceOf(user).call(); console.log("totalSupply:" + fromWei(totalSupply, "ether") + " balance:" + fromWei(balance, "ether")); } async function getRewardInfo(ctx: DODOMineV2Context, idx: number, user: string, logInfo?: string) { let erc20Mine = ctx.ERC20Mine let obj = await erc20Mine.methods.rewardTokenInfos(idx).call(); let curBlock = await ctx.Web3.eth.getBlockNumber(); console.log(logInfo); // console.log("Static-Data: rewardToken:" + obj.rewardToken + " rewardVault:" + obj.rewardVault + " rewardPerBlock:" + fromWei(obj.rewardPerBlock, "ether")); console.log("Dynamic-Data: start:" + obj.startBlock + " end:" + obj.endBlock + " accRewardPerShare:" + fromWei(obj.accRewardPerShare, "ether") + " lastRewardBlock:" + obj.lastRewardBlock + " curBlock:" + curBlock); var pendingReward = null; if (user != null) { pendingReward = await erc20Mine.methods.getPendingReward(user, idx).call(); console.log("User-pendingReward:" + fromWei(pendingReward, "ether")); } return [obj, pendingReward]; } describe("erc20Mine", () => { let snapshotId: string; let ctx: DODOMineV2Context; before(async () => { ctx = await getDODOMineContext(null); await init(ctx); }); beforeEach(async () => { snapshotId = await ctx.EVM.snapshot(); }); afterEach(async () => { await ctx.EVM.reset(snapshotId); }); describe("baseMine", () => { // ======= Ownable ========= it("addRewardToken", async () => { let erc20Mine = ctx.ERC20Mine; var curBlock = await ctx.Web3.eth.getBlockNumber(); await erc20Mine.methods.addRewardToken( ctx.REWARD_1.options.address, decimalStr("0"), curBlock + 2, curBlock + 1000 ).send(ctx.sendParam(projector)); let [rewardTokenInfo,] = await getRewardInfo(ctx, 0, null, ""); assert(rewardTokenInfo.rewardPerBlock, decimalStr("0")) }); it("removeRewardToken", async () => { let erc20Mine = ctx.ERC20Mine; var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 10, curBlock + 110, decimalStr("0")); await addRewardToken(ctx, ctx.REWARD_2, curBlock + 10, curBlock + 110, decimalStr("0")); let [rewardTokenInfo,] = await getRewardInfo(ctx, 0, null, ""); await erc20Mine.methods.removeRewardToken( rewardTokenInfo.rewardToken ).send(ctx.sendParam(projector)); [rewardTokenInfo,] = await getRewardInfo(ctx, 0, null, ""); assert(rewardTokenInfo.rewardToken, ctx.REWARD_2.options.address) }); // =========================== }) describe("erc20Mine", () => { it("deposit", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 2, curBlock + 102, decimalStr("10")); await stakeInfo(ctx, account0, "UserStakeInfo - Before"); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - Before"); //增加区块 await ctx.increBlock(3); // curBlock = await ctx.Web3.eth.getBlockNumber(); // console.log("deposit curBlock:", curBlock) await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("5") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("5") ), ctx.sendParam(account0), "deposit"); await stakeInfo(ctx, account0, "UserStakeInfo - After"); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After - 1"); //增加区块 await ctx.increBlock(3); let [obj, pendingReward] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After - 2"); assert.equal(obj.accRewardPerShare, "2666666666666666666"); assert.equal(pendingReward, "49999999999999999990"); }); it("withdraw", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 2, curBlock + 102, decimalStr("10")); // await stakeInfo(ctx, account0, "UserStakeInfo - Before"); // await getRewardInfo(ctx, 0, account0, "UserRewardInfo - Before"); //增加区块 await ctx.increBlock(3); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("20") ), ctx.sendParam(account0), "deposit - account0"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account1), "deposit - account1"); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After - 1"); await ctx.increBlock(3); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After - 2"); await logGas(await ctx.ERC20Mine.methods.withdraw( decimalStr("10") ), ctx.sendParam(account0), "withdraw"); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After - 3"); await logGas(await ctx.ERC20Mine.methods.withdraw( decimalStr("10") ), ctx.sendParam(account0), "withdraw"); //增加区块 await ctx.increBlock(3); let [obj, pendingReward] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After - 4"); assert.equal(obj.accRewardPerShare, "2333333333333333333"); assert.equal(pendingReward, "41666666666666666660"); }); it("getReward", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 2, curBlock + 102, decimalStr("10")); await stakeInfo(ctx, account0, "UserStakeInfo - Before"); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - Before"); //增加区块 await ctx.increBlock(3); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account1), "deposit"); //增加区块 await ctx.increBlock(3); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); await logGas(await ctx.ERC20Mine.methods.claimReward(0), ctx.sendParam(account0), "claimReward - 0"); let rewardBalance = await ctx.REWARD_1.methods.balanceOf(account0).call(); assert.equal(rewardBalance, "30000000000000000000"); }); it("getRewardAll", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 5, curBlock + 103, decimalStr("10")); await addRewardToken(ctx, ctx.REWARD_2, curBlock + 5, curBlock + 103, decimalStr("5")); await stakeInfo(ctx, account0, "UserStakeInfo - Before"); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - Before"); //增加区块 await ctx.increBlock(10); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account1), "deposit"); //增加区块 await ctx.increBlock(3); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); await logGas(await ctx.ERC20Mine.methods.claimAllRewards(), ctx.sendParam(account0), "claimReward - 0"); let rewardBalance0 = await ctx.REWARD_1.methods.balanceOf(account0).call(); let rewardBalance1 = await ctx.REWARD_2.methods.balanceOf(account0).call(); assert.equal(rewardBalance0, "30000000000000000000"); assert.equal(rewardBalance1, "15000000000000000000"); }); it("setReward - beforeStart", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 10, curBlock + 100, decimalStr("10")); await ctx.ERC20Mine.methods.setReward(0, decimalStr("5")).send(ctx.sendParam(projector)); //增加区块 await ctx.increBlock(10); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account1), "deposit"); //增加区块 await ctx.increBlock(3); await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); await logGas(await ctx.ERC20Mine.methods.claimReward(0), ctx.sendParam(account0), "claimReward - 0"); let rewardBalance = await ctx.REWARD_1.methods.balanceOf(account0).call(); assert.equal(rewardBalance, "15000000000000000000"); }) it("setReward - ing", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 2, curBlock + 100, decimalStr("10")); //增加区块 await ctx.increBlock(3); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account1), "deposit"); //增加区块 await ctx.increBlock(3); let [, pendingReward] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); assert.equal(pendingReward, "25000000000000000000"); await ctx.ERC20Mine.methods.setReward(0, decimalStr("5")).send(ctx.sendParam(projector)); //增加区块 await ctx.increBlock(3); [, pendingReward] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); await logGas(await ctx.ERC20Mine.methods.claimReward(0), ctx.sendParam(account0), "claimReward - 0"); let rewardBalance = await ctx.REWARD_1.methods.balanceOf(account0).call(); assert.equal(rewardBalance, "40000000000000000000"); }) // it("setReward - after", async () => { // var curBlock = await ctx.Web3.eth.getBlockNumber(); // await addRewardToken(ctx, ctx.REWARD_1, curBlock + 2, curBlock + 10, decimalStr("10")); // //增加区块 // await ctx.increBlock(3); // await logGas(await ctx.ERC20Mine.methods.deposit( // decimalStr("10") // ), ctx.sendParam(account0), "deposit"); // await logGas(await ctx.ERC20Mine.methods.deposit( // decimalStr("10") // ), ctx.sendParam(account1), "deposit"); // //增加区块 // await ctx.increBlock(3); // let [, pendingReward] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); // assert.equal(pendingReward, "25000000000000000000"); // await ctx.ERC20Mine.methods.setReward(0, decimalStr("5")).send(ctx.sendParam(projector)); // //增加区块 // await ctx.increBlock(3); // [, pendingReward] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); // await logGas(await ctx.ERC20Mine.methods.claimReward(0), ctx.sendParam(account0), "claimReward - 0"); // let rewardBalance = await ctx.REWARD_1.methods.balanceOf(account0).call(); // assert.equal(rewardBalance, "25000000000000000000"); // }) it("setEndBlock", async () => { var curBlock = await ctx.Web3.eth.getBlockNumber(); await addRewardToken(ctx, ctx.REWARD_1, curBlock + 2, curBlock + 100, decimalStr("10")); //增加区块 await ctx.increBlock(3); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account0), "deposit"); await logGas(await ctx.ERC20Mine.methods.deposit( decimalStr("10") ), ctx.sendParam(account1), "deposit"); //增加区块 await ctx.increBlock(3); await ctx.ERC20Mine.methods.setEndBlock(0, curBlock + 120).send(ctx.sendParam(projector)); let [obj,] = await getRewardInfo(ctx, 0, account0, "UserRewardInfo - After"); assert(obj.endBlock - curBlock - 100, "20"); }) }) });