Files
protocol/contracts/governance/src/IZeroExVotes.sol
Elena bcbfbfa16c Decentralised governance of 0x protocol and treasury (#641)
* Install open zeppelin contracts

* Init foundry in governance

* Add wrapped ZRX token

* Add governance contracts testing to CI

* Set optimizer runs to default

* Upgrade to patched version of openzeppelin/contracts

* Test stakingakng / unwrapping ZRX

* Init npm package

* Lint fix, removing lib from gitignore

* Add openzeppelin contracts git submodule for foundry

* Add vanilla governor contract

* Fix reference paths to imported packages

* Temporarily switch to using a mocked version of ZRX

* Ignore foundry's lib in link checker

* Fix a conflict in gitignore between forge lib adn built lib

* Upload governance code coverage report to coveralls

* Flesh out test scenarios for wrapping/unwrapping

* Add basic ERC20 name and symbol tests

* Wire in basic timelock controller and governor test setup

* Test basic governor properties

* Add basic voting power delegation tests

* Add proposal execution happy path test

* Split ERC20Votes logic between wrapped token
and ZeroExVotes contracts

* Exclude BaseTest from coverage in coveralls

* Add protocol specific governor with produciton governance settings

* Add a dedicated instance for the treasury governor
This is currently using the default 1 token 1 vote mechanism but will be migrated

* Add test for updating governance settings
for voting delay, voting period and proposal threshold

* Create seperate timelock contract instance for treasury and protocol

* Test updating the timlock min delay

* Set timelock delay to 2 days for protocol and 1 sec for treasury

* Remove timelock from treasury governor

* Refactor _checkpointsLookup to return entire Checkpoint
instad of just number of votes

* Update the totalSupply checkpoints updating logic

* Quadratic voting power transfers and delegations

* Fix workflow yaml

* Initialise ZeroExVotes behind a ERC1967Proxy
Test it cannot be reinitialised

* Remove obsoleted console.logs from test

* Storage pack Checkpoint enum

* Remove keeping track of total balances for voting

* Switch to using the foundry artifact in test

* Fix rebase issue

* Add timelock control over the treasury governor

* Add test for wrapped token transfer

* Emit separate events for changing linear and quadratic voting power

* Add the ability to cancel a proposal

* Limit the governors' cancel function to security council only

* Eject security council after a proposal is cancelled

* Add ability for governance to set the security council

* Merge the governors test suites into one reusable set of tests

* Add an empty test function to base test contract
to remove it from coverage reports. Fudge but no other way to ignore it in report

* Security council can rollback protocol upgrades

* Upgrade to solidity 0.8.19

* Move IZeroExGovernor to src

* Abstract Security council interface into its own

* Emit events when assigning and ejecting the security council

* Use a cast to bytes4 instead of LibBytes

Co-authored-by: duncancmt <1207590+duncancmt@users.noreply.github.com>

* Writing total supply checkpoints and setup of
quorum percentage of quadratic total supply for treasure governor

* Add test for transferring tokens when delegating

* Rename IZeroExSecurityCouncil to ISecurityCouncil

* Add security council restrictions to governors

* Remove obsolete overflow check

* Improve test coverage

* Upgrade open-zeppelin contracts to 4.8.2

* Test delegation by signature

* Test non security council requests
to rollback protocol changes cannot be executed

* Better revert messages

* Test correct interfaces are supported

* Remove obsoleted funciton

* Further test delegation by signature scenario

* Split the delegation functionality tests

* Add test for initialisation of voting contract

* Add test for reading checkpoints

* Update code comments

* Fix compilation warnings

* Run smt checker

* Add checkpoint tests

* Rename parameter in moveEntireVotingPower to match the one in movePartialVotingPower

* Switch moveEntireVotingPower to a more generic moveVotingPower implementation
as in the open-zeppelin contracts

* Install foundry earlier in CI

* Switch movePartialVotingPower to the generic moveVotingPower implementation

* Write totalSupplyCheckpoints via the generic _writeCheckpoint

* Add threshold for quadratic voting power

* Remove autoinserted code by OZ

* Add openzeppelin/contracts-upgradable

* Add initializable base to Voting contract

* Fix terminogy error in natspec

* Fix code comment

* Remove obsoleted overrides and add a missing modifier to moveVotingPower

* Remove amount check

Co-authored-by: duncancmt <1207590+duncancmt@users.noreply.github.com>

* Fix a calculation error and clean tests

* Update thresholds for treasury governor

* Fix testShouldNotBeAbleToDelegateWithSignatureAfterExpiry

* Update from @duncancmt

without "memory-safe" the IR optimizer produces significantly worse code and it disables the stack limit evader

Co-authored-by: duncancmt <1207590+duncancmt@users.noreply.github.com>

* Add onlyProxy to initializer

* Fix quadratic voting weight base

* Rename voting parameter for clarity

* Make addresses immutable (#680)

* Make addresses immutable

* Fix linting issues

---------

Co-authored-by: elenadimitrova <elena@arenabg.com>

* Prevent griefing by a malicious ZeroExVotes upgrade (#681)

* Gas optimization

* Minimal change to prevent malicious ZeroExVotes from griefing

* Add demonstration of griefing upgrade

* Fix rebase issues with tests

* Fix prettier issues

* Add checks to test

---------

Co-authored-by: elenadimitrova <elena@arenabg.com>

* Rename SecurityCouncil contract

* Add timestamp to delegator balance updates

* Make quadraticThreshold `immutable` for gas efficiency

* Remove the logic for ejecting security council

* Switch balance timestamp to be a block number

* Test votes migration for adding a new vote weight mechanism (#674)

* Add Emacs files to .gitignore

* Make some functions unproected to demonstrate a migration

* Add example (broken) migration

* Add migration test for voting logic

* Try to simplify tests

* Fix compilation errors

* Fix underflow test with new logic

* Flesh out migration test for voting

* Replace cube root library

* Fix stack too deep in coverage

---------

Co-authored-by: elenadimitrova <elena@arenabg.com>

* Change test case to testFail

* Update contracts/governance/test/ZeroExVotesMigration.sol

Co-authored-by: duncancmt <1207590+duncancmt@users.noreply.github.com>

---------

Co-authored-by: duncancmt <1207590+duncancmt@users.noreply.github.com>
Co-authored-by: Duncan Townsend <git@duncancmt.com>
2023-03-22 15:03:05 +02:00

133 lines
4.8 KiB
Solidity

// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2023 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.8.19;
interface IZeroExVotes {
struct Checkpoint {
uint32 fromBlock;
uint96 votes;
uint96 quadraticVotes;
}
/**
* @dev Emitted when a token transfer or delegate change,
* results in changes to a delegate's quadratic number of votes.
*/
event DelegateQuadraticVotesChanged(
address indexed delegate,
uint256 previousQuadraticBalance,
uint256 newQuadraticBalance
);
/**
* @dev Emitted when a token transfer or delegate change, results in changes to a delegate's number of votes.
*/
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);
/**
* @dev Emitted when the total supply of the token is changed due to minting and burning which results in
* the total supply checkpoint being writtenor updated.
*/
event TotalSupplyChanged(uint256 totalSupplyVotes, uint256 totalSupplyQuadraticVotes);
/**
* @dev Get the `pos`-th checkpoint for `account`.
*/
function checkpoints(address account, uint32 pos) external view returns (Checkpoint memory);
/**
* @dev Get number of checkpoints for `account`.
*/
function numCheckpoints(address account) external view returns (uint32);
/**
* @dev Gets the current votes balance for `account`
*/
function getVotes(address account) external view returns (uint256);
/**
* @dev Gets the current quadratic votes balance for `account`
*/
function getQuadraticVotes(address account) external view returns (uint256);
/**
* @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);
/**
* @dev Retrieve the number of quadratic votes for `account` at the end of `blockNumber`.
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastQuadraticVotes(address account, uint256 blockNumber) external view returns (uint256);
/**
* @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is but NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);
/**
* @dev Retrieve the sqrt of `totalSupply` at the end of `blockNumber`. Note, this value is the square root of the
* sum of all balances.
* It is but NOT the sum of all the sqrt of the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastQuadraticTotalSupply(uint256 blockNumber) external view returns (uint256);
/**
* @dev Moves the voting power corresponding to `amount` number of tokens from `src` to `dst`.
* Note that if the delegator isn't delegating to anyone before the function call `src` = address(0)
* @param src the delegatee we are moving voting power away from
* @param dst the delegatee we are moving voting power to
* @param srcBalance balance of the delegator whose delegatee is `src`. This is value _after_ the transfer.
* @param dstBalance balance of the delegator whose delegatee is `dst`. This is value _after_ the transfer.
* @param srcBalanceLastUpdated block number when balance of `src` was last updated.
* @param dstBalanceLastUpdated block number when balance of `dst` was last updated.
* @param amount The amount of tokens transferred from the source delegate to destination delegate.
*/
function moveVotingPower(
address src,
address dst,
uint256 srcBalance,
uint256 dstBalance,
uint96 srcBalanceLastUpdated,
uint96 dstBalanceLastUpdated,
uint256 amount
) external returns (bool);
function writeCheckpointTotalSupplyMint(uint256 accountBalance, uint256 amount) external returns (bool);
function writeCheckpointTotalSupplyBurn(uint256 accountBalance, uint256 amount) external returns (bool);
}