-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eth sent to Timelock will be locked in current implementation #150
Comments
One other possible solution is to disambiguate the values into something like valuesExecutor, valuesTimelock. Relevant functions // GovernorBravoDelegate
// SPDX-License-Identifier: BSD-3
/**
* @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold
* @param targets Target addresses for proposal calls
* @param valuesExecutor Eth values for proposal calls to be paid by executor,
* if non-zero, it will override valuesTimelock for the particular index
* @param valuesTimelock Eth values for proposal calls to be paid by timelock
* @param signatures Function signatures for proposal calls
* @param calldatas Calldatas for proposal calls
* @param description String description of the proposal
* @return Proposal id of new proposal
*/
function propose(address[] memory targets, uint[] memory valuesExecutor, uint[] memory valuesTimelock, string[] memory signatures, bytes[] memory calldatas, string memory description) public returns (uint) {
// Reject proposals before initiating as Governor
require(initialProposalId != 0, "GovernorBravo::propose: Governor Bravo not active");
require(comp.getPriorVotes(msg.sender, sub256(block.number, 1)) > proposalThreshold, "GovernorBravo::propose: proposer votes below proposal threshold");
require(targets.length == valuesExecutor.length && targets.length == valuesTimelock.length && targets.length == signatures.length && targets.length == calldatas.length, "GovernorBravo::propose: proposal function information arity mismatch");
require(targets.length != 0, "GovernorBravo::propose: must provide actions");
require(targets.length <= proposalMaxOperations, "GovernorBravo::propose: too many actions");
uint latestProposalId = latestProposalIds[msg.sender];
if (latestProposalId != 0) {
ProposalState proposersLatestProposalState = state(latestProposalId);
require(proposersLatestProposalState != ProposalState.Active, "GovernorBravo::propose: one live proposal per proposer, found an already active proposal");
require(proposersLatestProposalState != ProposalState.Pending, "GovernorBravo::propose: one live proposal per proposer, found an already pending proposal");
}
uint startBlock = add256(block.number, votingDelay);
uint endBlock = add256(startBlock, votingPeriod);
proposalCount++;
Proposal memory newProposal = Proposal({
id: proposalCount,
proposer: msg.sender,
eta: 0,
targets: targets,
valuesExecutor: valuesExecutor,
valuesTimelock: valuesTimelock,
signatures: signatures,
calldatas: calldatas,
startBlock: startBlock,
endBlock: endBlock,
forVotes: 0,
againstVotes: 0,
abstainVotes: 0,
canceled: false,
executed: false
});
proposals[newProposal.id] = newProposal;
latestProposalIds[newProposal.proposer] = newProposal.id;
emit ProposalCreated(newProposal.id, msg.sender, targets, valuesExecutor, valuesTimelock, signatures, calldatas, startBlock, endBlock, description);
return newProposal.id;
}
/**
* @notice Queues a proposal of state succeeded
* @param proposalId The id of the proposal to queue
*/
function queue(uint proposalId) external {
require(state(proposalId) == ProposalState.Succeeded, "GovernorBravo::queue: proposal can only be queued if it is succeeded");
Proposal storage proposal = proposals[proposalId];
uint eta = add256(block.timestamp, timelock.delay());
for (uint i = 0; i < proposal.targets.length; i++) {
queueOrRevertInternal(proposal.targets[i], proposal.valuesTimelock[i], proposal.signatures[i], proposal.calldatas[i], eta);
}
proposal.eta = eta;
emit ProposalQueued(proposalId, eta);
}
function queueOrRevertInternal(address target, uint value, string memory signature, bytes memory data, uint eta) internal {
require(!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta");
timelock.queueTransaction(target, value, signature, data, eta);
}
/**
* @notice Executes a queued proposal if eta has passed
* @param proposalId The id of the proposal to execute
*/
function execute(uint proposalId) external payable {
require(state(proposalId) == ProposalState.Queued, "GovernorBravo::execute: proposal can only be executed if it is queued");
Proposal storage proposal = proposals[proposalId];
proposal.executed = true;
for (uint i = 0; i < proposal.targets.length; i++) {
// timelock.executeTransaction.value(proposal.values[i])(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta);
timelock.executeTransaction.value(proposal.valuesExecutor[i])(proposal.targets[i], proposal.valuesTimelock[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta);
}
emit ProposalExecuted(proposalId);
}
/**
* @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold
* @param proposalId The id of the proposal to cancel
*/
function cancel(uint proposalId) external {
require(state(proposalId) != ProposalState.Executed, "GovernorBravo::cancel: cannot cancel executed proposal");
Proposal storage proposal = proposals[proposalId];
require(msg.sender == proposal.proposer || comp.getPriorVotes(proposal.proposer, sub256(block.number, 1)) < proposalThreshold, "GovernorBravo::cancel: proposer above threshold");
proposal.canceled = true;
for (uint i = 0; i < proposal.targets.length; i++) {
timelock.cancelTransaction(proposal.targets[i], proposal.valuesTimelock[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta);
}
emit ProposalCanceled(proposalId);
} // In GovernorBravoInterfaces
// SPDX-License-Identifier: BSD-3
pragma solidity ^0.5.16;
pragma experimental ABIEncoderV2;
contract GovernorBravoEvents {
/// @notice An event emitted when a new proposal is created
event ProposalCreated(uint id, address proposer, address[] targets, uint[] valuesExecutor, uint[] valuesTimelock, string[] signatures, bytes[] calldatas, uint startBlock, uint endBlock, string description);
}
/**
* @title Storage for Governor Bravo Delegate
* @notice For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new
* contract which implements GovernorBravoDelegateStorageV1 and following the naming convention
* GovernorBravoDelegateStorageVX.
*/
contract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {
struct Proposal {
/// @notice Unique id for looking up a proposal
uint id;
/// @notice Creator of the proposal
address proposer;
/// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
uint eta;
/// @notice the ordered list of target addresses for calls to be made
address[] targets;
/// @notice The ordered list of values (i.e. msg.value) to be made by the executor
uint[] valuesExecutor;
/// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
uint[] valuesTimelock;
/// @notice The ordered list of function signatures to be called
string[] signatures;
/// @notice The ordered list of calldata to be passed to each call
bytes[] calldatas;
/// @notice The block at which voting begins: holders must delegate their votes prior to this block
uint startBlock;
/// @notice The block at which voting ends: votes must be cast prior to this block
uint endBlock;
/// @notice Current number of votes in favor of this proposal
uint forVotes;
/// @notice Current number of votes in opposition to this proposal
uint againstVotes;
/// @notice Current number of votes for abstaining for this proposal
uint abstainVotes;
/// @notice Flag marking whether the proposal has been canceled
bool canceled;
/// @notice Flag marking whether the proposal has been executed
bool executed;
/// @notice Receipts of ballots for the entire set of voters
mapping (address => Receipt) receipts;
} |
Yes |
We've implemented a backwards compatible fix for this issue for OpenZeppelin's Governor, where we changed + Address.sendValue(payable(_timelock), msg.value);
for (uint256 i = 0; i < targets.length; ++i) {
- _timelock.executeTransaction{value: values[i]}(targets[i], values[i], "", calldatas[i], eta);
+ _timelock.executeTransaction(targets[i], values[i], "", calldatas[i], eta);
} See OpenZeppelin/openzeppelin-contracts#2849 for some discussion and alternatives. |
I think the approach we will go with is PR #174. We don't foresee a situation where the executor will actually be sending ETH in the future, so we will make |
yes i need help |
I would like to get my money out asap or a percentage i havent seen a dime yet |
I came across this problem while playing around with the new governance contracts.
Here's what I did
Setup the governance contracts (Comp, GovernorBravoDelegate, GovernorBravoDelegator, Timelock)
proxy
refers to GovernorBravoDelegator instance using GovernorBravoDelegate's abi.msg.sender
not from the timelock contractChanging this line on GovernorBravoDelegate will address the issue and allow for eth in the Timelock contract to be sent out.
The solution I found above is definitely not ideal, any other ideas appreciated.
The text was updated successfully, but these errors were encountered: