import { expect } from "chai";
import hre from "hardhat";
const { ethers } = hre;
import { time } from "@nomicfoundation/hardhat-network-helpers";
describe("FeeCollector", function () {
let raacToken, feeCollector, veRAACToken;
let owner, user1, user2, treasury, repairFund, emergencyAdmin;
let defaultFeeType;
const BASIS_POINTS = 10000;
const WEEK = 7 * 24 * 3600;
const ONE_YEAR = 365 * 24 * 3600;
const INITIAL_MINT = ethers.parseEther("10000");
const SWAP_TAX_RATE = 100;
const BURN_TAX_RATE = 50;
beforeEach(async function () {
[owner, user1, user2, repairFund, emergencyAdmin] = await ethers.getSigners();
const RAACToken = await ethers.getContractFactory("RAACToken");
raacToken = await RAACToken.deploy(owner.address, SWAP_TAX_RATE, BURN_TAX_RATE);
await raacToken.waitForDeployment();
const VeRAACToken = await ethers.getContractFactory("veRAACToken");
veRAACToken = await VeRAACToken.deploy(await raacToken.getAddress());
await veRAACToken.waitForDeployment();
const Treasury = await ethers.getContractFactory("Treasury");
treasury = await Treasury.deploy(owner.address);
const FeeCollector = await ethers.getContractFactory("FeeCollector");
feeCollector = await FeeCollector.deploy(
await raacToken.getAddress(),
await veRAACToken.getAddress(),
treasury.getAddress(),
repairFund.address,
owner.address
);
await feeCollector.waitForDeployment();
await raacToken.setFeeCollector(await feeCollector.getAddress());
await raacToken.manageWhitelist(await feeCollector.getAddress(), true);
await raacToken.manageWhitelist(await veRAACToken.getAddress(), true);
await raacToken.setMinter(owner.address);
await veRAACToken.setMinter(owner.address);
await feeCollector.grantRole(await feeCollector.FEE_MANAGER_ROLE(), owner.address);
await feeCollector.grantRole(await feeCollector.EMERGENCY_ROLE(), emergencyAdmin.address);
await feeCollector.grantRole(await feeCollector.DISTRIBUTOR_ROLE(), owner.address);
await raacToken.mint(user1.address, INITIAL_MINT);
await raacToken.mint(user2.address, INITIAL_MINT);
await raacToken.connect(user1).approve(await feeCollector.getAddress(), ethers.MaxUint256);
await raacToken.connect(user2).approve(await feeCollector.getAddress(), ethers.MaxUint256);
await raacToken.connect(user1).approve(await veRAACToken.getAddress(), ethers.MaxUint256);
await raacToken.connect(user2).approve(await veRAACToken.getAddress(), ethers.MaxUint256);
defaultFeeType = {
veRAACShare: 5000,
burnShare: 1000,
repairShare: 1000,
treasuryShare: 3000
};
for (let i = 0; i < 8; i++) {
await feeCollector.connect(owner).updateFeeType(i, defaultFeeType);
}
const taxRate = SWAP_TAX_RATE + BURN_TAX_RATE;
const grossMultiplier = BigInt(BASIS_POINTS * BASIS_POINTS) / BigInt(BASIS_POINTS * BASIS_POINTS - taxRate * BASIS_POINTS);
const protocolFeeGross = ethers.parseEther("50") * grossMultiplier / BigInt(10000);
const lendingFeeGross = ethers.parseEther("30") * grossMultiplier / BigInt(10000);
const swapTaxGross = ethers.parseEther("20") * grossMultiplier / BigInt(10000);
await feeCollector.connect(user1).collectFee(protocolFeeGross, 0);
await feeCollector.connect(user1).collectFee(lendingFeeGross, 1);
await feeCollector.connect(user1).collectFee(swapTaxGross, 6);
await veRAACToken.connect(user1).lock(ethers.parseEther("1000"), ONE_YEAR);
await time.increase(WEEK);
await veRAACToken.connect(user2).lock(ethers.parseEther("500"), ONE_YEAR);
});
it("incorrectly tranfers funds to the Treasury contract", async () => {
for (let feeType = 0; feeType < 8; feeType++) {
await feeCollector.connect(user1).collectFee(ethers.parseEther("1000"), feeType);
}
await expect(feeCollector.connect(owner).distributeCollectedFees()).to.emit(feeCollector, "FeeDistributed");
const balance = await raacToken.balanceOf(treasury.getAddress());
await expect(treasury.connect(owner).withdraw(raacToken.getAddress(), balance, owner.address))
.to.be.revertedWithCustomError(treasury, "InsufficientBalance");
});
});
The issue leads to funds getting stuck.