Optimistic
1. Summary
The PWN Optimistic governance is based on the Aragon's optimistic token voting plugin. The main changes we've made to the plugin are to use our Epoch Clock instead of block numbers, removed minimal proposer voting power and added ability to cancel proposals.
2. Important links
3. Contract details
PWNOptimisticGovernancePlugin.sol is written in Solidity version 0.8.17
Features
Create and Execute Optimistic proposals
Ability to veto a proposal
Inherited contracts, implemented Interfaces and ERCs
Functions
createProposal
Overview
Function to create a new optimistic proposal.
This function takes five arguments:
bytes calldata
_metadata
- Metadata of the proposalIDAO.Action[] calldata
_actions
- Actions to be executed after the proposal passes. (Learn more about IDAO.Action struct)uint256
_allowFailureMap
- Allows proposal to succeed even if an action reverts. Uses bitmap representation. If the bit at indexx
is 1, the tx succeeds even if the action atx
failed. Passing 0 will be treated as atomic execution.uint64
_startDate
- The start date of the proposal vote. If 0, the current timestamp is used and the vote starts immediately.uint64
_endDate
- The end date of the proposal vote. If 0,_startDate + minDuration
is used.
Implementation
function createProposal(
bytes calldata _metadata,
IDAO.Action[] calldata _actions,
uint256 _allowFailureMap,
uint64 _startDate,
uint64 _endDate
) external auth(PROPOSER_PERMISSION_ID) returns (uint256 proposalId) {
uint256 snapshotEpoch = epochClock.currentEpoch();
uint256 totalVotingPower_ = totalVotingPower(snapshotEpoch);
if (totalVotingPower_ == 0) {
revert NoVotingPower();
}
(_startDate, _endDate) = _validateProposalDates(_startDate, _endDate);
proposalId = _createProposal({
_creator: _msgSender(),
_metadata: _metadata,
_startDate: _startDate,
_endDate: _endDate,
_actions: _actions,
_allowFailureMap: _allowFailureMap
});
// store proposal related information
Proposal storage proposal_ = proposals[proposalId];
proposal_.parameters.startDate = _startDate;
proposal_.parameters.endDate = _endDate;
proposal_.parameters.snapshotEpoch = snapshotEpoch.toUint64();
proposal_.parameters.minVetoVotingPower = _applyRatioCeiled(
totalVotingPower_,
minVetoRatio()
);
// save gas
if (_allowFailureMap != 0) {
proposal_.allowFailureMap = _allowFailureMap;
}
for (uint256 i; i < _actions.length; ) {
proposal_.actions.push(_actions[i]);
unchecked {
++i;
}
}
}
veto
Overview
Function to register a veto for the given proposal.
This function takes one argument:
uint256
proposalId
Implementation
function veto(uint256 _proposalId) public {
address _voter = _msgSender();
(bool canVeto_, uint256 votingPower) = _canVeto(_proposalId, _voter);
if (!canVeto_) {
revert ProposalVetoingForbidden({ proposalId: _proposalId, account: _voter });
}
// write the updated tally
Proposal storage proposal_ = proposals[_proposalId];
proposal_.vetoTally += votingPower;
proposal_.vetoVoters[_voter] = true;
emit VetoCast({
proposalId: _proposalId,
voter: _voter,
votingPower: votingPower
});
}
execute
Overview
Function to execute the given proposal.
This function takes one argument:
uint256
proposalId
Implementation
function execute(uint256 _proposalId) public {
if (!canExecute(_proposalId)) {
revert ProposalExecutionForbidden(_proposalId);
}
proposals[_proposalId].executed = true;
_executeProposal(
dao(),
_proposalId,
proposals[_proposalId].actions,
proposals[_proposalId].allowFailureMap
);
}
cancel
Overview
Function to cancel the given proposal.
This function takes one argument:
uint256
proposalId
Implementation
function cancel(uint256 _proposalId) external auth(CANCELLER_PERMISSION_ID) {
if (!canCancel(_proposalId)) {
revert ProposalCancellationForbidden(_proposalId);
}
proposals[_proposalId].cancelled = true;
emit ProposalCancelled(_proposalId);
}
Events
event OptimisticGovernanceSettingsUpdated(uint32 minVetoRatio, uint64 minDuration);
event VetoCast(uint256 indexed proposalId, address indexed voter, uint256 votingPower);
event ProposalCancelled(uint256 indexed proposalId);
OptimisticGovernanceSettingsUpdated
OptimisticGovernanceSettingsUpdated event is emitted when the optimistic governance settings are updated.
This event has two parameters:
uint32
minVetoRatio
- Veto threshold valueuint64
minDuration
- Minimum duration of the proposal vote in seconds
VetoCast
VetoCast event is emitted when a veto is cast by a voter.
This event has three parameters:
uint256 indexed
proposalId
address indexed
voter
uint256
votingPower
- Amount of voting power that supports the veto
ProposalCancelled
ProposalCancelled event is emitted when a proposal is cancelled.
This event has one parameter:
uint256 indexed
proposalId
Errors
error DateOutOfBounds(uint64 limit, uint64 actual);
error MinDurationOutOfBounds(uint64 limit, uint64 actual);
error ProposalVetoingForbidden(uint256 proposalId, address account);
error ProposalExecutionForbidden(uint256 proposalId);
error ProposalCancellationForbidden(uint256 proposalId);
error NoVotingPower();
DateOutOfBounds
DateOutOfBounds error is thrown when a date is out of bounds.
This error has two parameters:
uint64
limit
uint64
actual
MinDurationOutOfBounds
MinDurationOutOfBounds error is thrown when the minimum duration value is out of bounds (less than 3 days or greater than 1 year).
This error has two parameters:
uint64
limit
uint64
actual
ProposalVetoingForbidden
ProposalVetoingForbidden error is thrown when an account is not allowed to cast a veto. This can happen in the case the challenge period:
has not started
has ended
was cancelled
was executed
the account doesn't have vetoing powers.
This error has two parameters:
uint256
proposalId
address
account
ProposalExecutionForbidden
ProposalExecutionForbidden error is thrown when the proposal execution is forbidden.
This error has one parameter:
uint256
proposalId
Last updated