uint256 public constant VOTE_DELAY = 10 days;
uint256 public constant MIN_VOTE_DELAY = 1 days;
uint256 public constant MAX_VOTE_DELAY = 10 days;
function vote(address gauge, uint256 weight) external override whenNotPaused {
if (!isGauge(gauge)) revert GaugeNotFound();
if (weight > WEIGHT_PRECISION) revert InvalidWeight();
uint256 votingPower = veRAACToken.balanceOf(msg.sender);
if (votingPower == 0) revert NoVotingPower();
uint256 oldWeight = userGaugeVotes[msg.sender][gauge];
userGaugeVotes[msg.sender][gauge] = weight;
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
emit WeightUpdated(gauge, oldWeight, weight);
}
pragma solidity ^0.8.19;
import {Test} from "forge-std/Test.sol";
import {console2} from "forge-std/console2.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC20Mock} from "../../contracts/mocks/core/tokens/ERC20Mock.sol";
import {GaugeController} from "../../contracts/core/governance/gauges/GaugeController.sol";
import {RAACGauge} from "../../contracts/core/governance/gauges/RAACGauge.sol";
import {RWAGauge} from "../../contracts/core/governance/gauges/RWAGauge.sol";
import {veRAACToken} from "../../contracts/core/tokens/veRAACToken.sol";
import {IGaugeController} from "../../contracts/interfaces/core/governance/gauges/IGaugeController.sol";
contract FoundryTest is Test {
ERC20Mock public raacToken;
ERC20Mock public stakingToken;
ERC20Mock public rewardToken;
veRAACToken public veToken;
GaugeController public controller;
RAACGauge public raacGauge;
RWAGauge public rwaGauge;
address public admin = address(this);
address public alice = address(0x1);
address public bob = address(0x2);
address public carol = address(0x3);
uint256 public constant INITIAL_SUPPLY = 1_000_000e18;
uint256 public constant LOCK_AMOUNT = 100_000e18;
uint256 public constant YEAR = 365 days;
function setUp() public {
raacToken = new ERC20Mock("RAAC Token", "RAAC");
rewardToken = new ERC20Mock("Reward Token", "RWD");
veToken = new veRAACToken(address(raacToken));
controller = new GaugeController(address(veToken));
raacGauge = new RAACGauge(address(rewardToken), address(veToken), address(controller));
rwaGauge = new RWAGauge(address(rewardToken), address(veToken), address(controller));
raacToken.mint(alice, INITIAL_SUPPLY);
raacToken.mint(bob, INITIAL_SUPPLY);
rewardToken.mint(address(controller), INITIAL_SUPPLY * 10);
vm.startPrank(admin);
controller.addGauge(address(raacGauge), IGaugeController.GaugeType.RAAC, 0);
controller.addGauge(address(rwaGauge), IGaugeController.GaugeType.RWA, 0);
vm.stopPrank();
vm.startPrank(alice);
raacToken.approve(address(veToken), type(uint256).max);
veToken.approve(address(raacGauge), type(uint256).max);
vm.stopPrank();
vm.startPrank(bob);
raacToken.approve(address(veToken), type(uint256).max);
veToken.approve(address(raacGauge), type(uint256).max);
vm.stopPrank();
}
function test_NoVotingDelay() public {
vm.startPrank(alice);
veToken.lock(LOCK_AMOUNT, YEAR);
controller.vote(address(raacGauge), 8000);
controller.vote(address(raacGauge), 2000);
controller.vote(address(raacGauge), 10000);
vm.stopPrank();
}
}
mapping(address => mapping(address => uint256)) public lastUserVoteTime;
function vote(address gauge, uint256 weight) external override whenNotPaused {
if (!isGauge(gauge)) revert GaugeNotFound();
if (weight > WEIGHT_PRECISION) revert InvalidWeight();
uint256 lastVoteTime = lastUserVoteTime[msg.sender][gauge];
if (block.timestamp < lastVoteTime + VOTE_DELAY) {
revert VoteDelayNotElapsed();
}
uint256 votingPower = veRAACToken.balanceOf(msg.sender);
if (votingPower == 0) revert NoVotingPower();
uint256 oldWeight = userGaugeVotes[msg.sender][gauge];
userGaugeVotes[msg.sender][gauge] = weight;
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
lastUserVoteTime[msg.sender][gauge] = block.timestamp;
emit WeightUpdated(gauge, oldWeight, weight);
}