As we can see, to calculate the new gauge weight, the old user weight should be subtracted from the current gauge total weight.
The votingPower
is the current veRAACToken
balance of the user. This can be a problem if a user votes multiple times for the same gauge because in this case the newGaugeWeight
would be less than it should be.
import { time } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import hre from "hardhat";
const { ethers } = hre;
describe("GaugeControllerPoC", () => {
let gaugeController;
let rwaGauge;
let raacGauge;
let veRAACToken;
let rewardToken;
let owner;
let gaugeAdmin;
let user1;
let user2;
let user3;
beforeEach(async () => {
[owner, gaugeAdmin, user1, user2, user3] = await ethers.getSigners();
const MockToken = await ethers.getContractFactory("MockToken");
veRAACToken = await MockToken.deploy("veRAAC Token", "veRAAC", 18);
await veRAACToken.waitForDeployment();
const veRAACAddress = await veRAACToken.getAddress();
rewardToken = await MockToken.deploy("Reward Token", "REWARD", 18);
await rewardToken.waitForDeployment();
const rewardTokenAddress = await rewardToken.getAddress();
const GaugeController = await ethers.getContractFactory("GaugeController");
gaugeController = await GaugeController.deploy(veRAACAddress);
await gaugeController.waitForDeployment();
const gaugeControllerAddress = await gaugeController.getAddress();
const RWAGauge = await ethers.getContractFactory("RWAGauge");
rwaGauge = await RWAGauge.deploy(
rewardTokenAddress,
veRAACAddress,
gaugeControllerAddress
);
await rwaGauge.waitForDeployment();
const RAACGauge = await ethers.getContractFactory("RAACGauge");
raacGauge = await RAACGauge.deploy(
rewardTokenAddress,
veRAACAddress,
gaugeControllerAddress
);
await raacGauge.waitForDeployment();
const GAUGE_ADMIN_ROLE = await gaugeController.GAUGE_ADMIN();
await gaugeController.grantRole(GAUGE_ADMIN_ROLE, gaugeAdmin.address);
await gaugeController.connect(gaugeAdmin).addGauge(
await rwaGauge.getAddress(),
0,
0
);
await gaugeController.connect(gaugeAdmin).addGauge(
await raacGauge.getAddress(),
1,
0
);
await rwaGauge.grantRole(await rwaGauge.CONTROLLER_ROLE(), owner.address);
await raacGauge.grantRole(await raacGauge.CONTROLLER_ROLE(), owner.address);
});
it("incorreclty calculates new gauge weight", async () => {
await veRAACToken.mint(user1.address, ethers.parseEther("1"));
await veRAACToken.mint(user2.address, ethers.parseEther("1"));
await gaugeController.connect(user1).vote(await rwaGauge.getAddress(), 4000);
await gaugeController.connect(user2).vote(await rwaGauge.getAddress(), 10000);
await veRAACToken.mint(user1.address, ethers.parseEther("0.1"));
await gaugeController.connect(user1).vote(await rwaGauge.getAddress(), 4500);
const newGaugeWeight = await gaugeController.getGaugeWeight(await rwaGauge.getAddress());
expect(newGaugeWeight).to.equal(ethers.parseEther("1.455"));
});
});
The issue disrupts the weight calculation functionality and leads to unfair rewards distribution across the gauges.
To ensure accurate weight calculations, store each user's voting power at the time of their vote in a dedicated storage data structure, similar to how userGaugeVotes
are stored.