Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Error: VM Exception while processing transaction: reverted with reason string 'Governor: proposal not successful' #14

Open
vivekascoder opened this issue Aug 1, 2022 · 3 comments
Assignees

Comments

@vivekascoder
Copy link

Can someone tell me why this issue arises?

These are my tests

const { ethers, network } = require("hardhat");
const {
  VOTING_DELAY,
  VOTING_PERIOD,
  PROPOSAL_DESCRIPTION,
  NEW_STORE_VALUE,
  FUNC,
  DEVELOPMENT_CHAINS,
  MIN_DELAY,
  QUORUM_PERCENTAGE,
  PROPOSAL_FILE,
} = require("../globals");
const fs = require("fs");

let caller;
let deployer;
let governorAddress;
let governorTokenAddress;
let timelockAddress;
let boxAddress;
let proposalIdString;

const setCaller = async () => {
  const accs = await ethers.getSigners();
  caller = accs[0];
  deployer = accs[1];
};

const getLatestBlock = async () => {
  return await ethers.provider.getBlockNumber();
};

async function moveTime(amount) {
  await network.provider.send("evm_increaseTime", [amount]);
  console.log(`🕞 Moved forward in time ${amount} seconds`);
}

async function moveBlocks(amount) {
  console.log("Moving blocks...");
  for (let index = 0; index < amount; index++) {
    await network.provider.request({
      method: "evm_mine",
      params: [],
    });
  }
  console.log(`Moved ${amount} blocks`);
}

const propose = async (args, functionToCall, proposalDescription) => {
  // Deploying governor token contract.
  const GovernorToken = await ethers.getContractFactory("GovernanceToken");
  const governorToken = await GovernorToken.connect(deployer).deploy();
  governorTokenAddress = governorToken.address;

  // Deploying Timelock contract.
  const Timelock = await ethers.getContractFactory("Timelock");
  const timelock = await Timelock.connect(deployer).deploy(MIN_DELAY, [], []);

  //   Governor contract.
  const Governor = await ethers.getContractFactory("DAO");
  const governor = await Governor.connect(deployer).deploy(
    governorToken.address,
    timelock.address,
    QUORUM_PERCENTAGE,
    VOTING_PERIOD,
    VOTING_DELAY
  );
  governorAddress = governor.address;

  // Giving governor the rights to propose something on the timelock contract.
  const proposerRole = await timelock.PROPOSER_ROLE();
  const executorRole = await timelock.EXECUTOR_ROLE();
  await (await timelock.grantRole(proposerRole, governor.address)).wait(1);
  await (await timelock.grantRole(executorRole, governor.address)).wait(1);

  // Box Contract.
  const Box = await ethers.getContractFactory("Box");
  const box = await Box.connect(deployer).deploy();
  boxAddress = box.address;

  const encodedFunctionCall = box.interface.encodeFunctionData(
    functionToCall,
    args
  );
  console.log(`Proposing ${functionToCall} on ${box.address} with ${args}`);
  console.log(`Proposal Description:\n  ${proposalDescription}`);

  // Check the existing value in Box contract.
  console.log("Box :: Value: ", await box.retrieve());

  const proposeTx = await governor.propose(
    [box.address],
    [0],
    [encodedFunctionCall],
    proposalDescription
  );
  console.log("⛏ Block Number: ", await getLatestBlock());
  if (DEVELOPMENT_CHAINS.includes(network.name)) {
    console.log("Jumping blocks.");
    await moveBlocks(VOTING_DELAY + 1);
  }
  const proposeReciept = await proposeTx.wait(1);
  const proposalId = proposeReciept.events[0].args.proposalId;
  proposalIdString = proposalId;
  console.log(`Proposed with proposal ID:\n  ${proposalId}`);

  const proposalState = await governor.state(proposalId);
  const proposalSnapShot = await governor.proposalSnapshot(proposalId);
  const proposalDeadline = await governor.proposalDeadline(proposalId);
  // save the proposalId
  let proposals = JSON.parse(fs.readFileSync(PROPOSAL_FILE, "utf8"));
  console.log("Network Chain Id: ", network.config.chainId);
  proposals[network.config.chainId.toString()].push(proposalId.toString());
  fs.writeFileSync(PROPOSAL_FILE, JSON.stringify(proposals));

  // The state of the proposal. 1 is not passed. 0 is passed.
  console.log(`Current Proposal State: ${proposalState}`);
  // What block # the proposal was snapshot
  console.log(`Current Proposal Snapshot: ${proposalSnapShot}`);
  // The block number the proposal voting expires
  console.log(`Current Proposal Deadline: ${proposalDeadline}`);

  console.log("⛏ Block Number: ", await getLatestBlock());
  const latestBlock = await getLatestBlock();
  const power = await governorToken.getVotes(deployer.address);
  console.log("💪🏻 Power: ", power);
  console.table([
    { name: "Caller", balance: await governorToken.balanceOf(caller.address) },
    {
      name: "Deployer",
      balance: await governorToken.balanceOf(deployer.address),
    },
  ]);
};

const vote = async (proposalId, voteWay, reason) => {
  console.log("⛏ Block Number: ", await getLatestBlock());
  console.log("Voting started.");
  const Governor = await ethers.getContractFactory("DAO");
  console.log("Governor Address: ", governorAddress);
  const governor = await Governor.attach(governorAddress);
  const GovernanceToken = await ethers.getContractFactory("GovernanceToken");
  const governanceToken = await GovernanceToken.attach(governorTokenAddress);
  await (
    await governanceToken.connect(deployer).delegate(deployer.address)
  ).wait(1);
  const voteTx = await governor
    .connect(deployer)
    .castVoteWithReason(proposalId, voteWay, reason);
  const voteTx1 = await governor
    .connect(caller)
    .castVoteWithReason(proposalId, voteWay, reason);
  await voteTx1.wait(1);

  const voteTxReceipt = await voteTx.wait(1);
  console.log(voteTxReceipt.events[0].args.reason);
  const proposalState = await governor.state(proposalId);

  const voteBalance = await governanceToken.getVotes(deployer.address);
  console.log(`Vote Balance: ${voteBalance}`);
  console.log(`Current Proposal State: ${proposalState}`);
  if (DEVELOPMENT_CHAINS.includes(network.name)) {
    console.log(`📦 Moving ${VOTING_PERIOD + 1} blocks`);
    await moveBlocks(VOTING_PERIOD + 1);
  }

  // Logging the proposal state.
  console.log(`📝 State of proposal: ${await governor.state(proposalId)}`);
  console.log(`Proposal Votes:`, await governor.proposalVotes(proposalId));
};

const queueAndExecute = async () => {
  console.log("Block Number", await getLatestBlock());
  console.log("🛳 Queue and Execute");

  const Box = await ethers.getContractFactory("Box");
  const box = Box.attach(boxAddress);
  const encodedFunctionCall = box.interface.encodeFunctionData(FUNC, [
    NEW_STORE_VALUE,
  ]);
  const descriptionHash = ethers.utils.keccak256(
    ethers.utils.toUtf8Bytes(PROPOSAL_DESCRIPTION)
  );
  const Governor = await ethers.getContractFactory("DAO");
  const governor = await Governor.attach(governorAddress);
  const queueTx = await governor.queue(
    [box.address],
    [0],
    [encodedFunctionCall],
    descriptionHash
  );
  await queueTx.wait(1);
};

const main = async () => {
  await setCaller();
  await propose([NEW_STORE_VALUE], FUNC, PROPOSAL_DESCRIPTION);
  await vote(proposalIdString, 1, "I like the proposal that's it.");
  await queueAndExecute();
};

main()
  .then(() => process.exit(0))
  .catch((e) => {
    console.error(e);
    process.exit(1);
  });
@r0ushann
Copy link

hey! can you assign me the issue?
thank you!

@nachoddiaz
Copy link

hey, I have the same issue. ¿How how is the problem solving going?

@Oznerol92
Copy link

Oznerol92 commented Apr 13, 2023

I think one problem is that you forgot to delegate like here

const delegate = async (governanceTokenAddress: string, delegatedAccount: string) => {
const governanceToken = await ethers.getContractAt("GovernanceToken", governanceTokenAddress)
const transactionResponse = await governanceToken.delegate(delegatedAccount)
await transactionResponse.wait(1)
console.log(`Checkpoints: ${await governanceToken.numCheckpoints(delegatedAccount)}`)
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants