Skip to content

Commit

Permalink
Merge pull request #765 from fei-protocol/release/v2.9.0
Browse files Browse the repository at this point in the history
Release/v2.9.0
  • Loading branch information
Joeysantoro authored May 6, 2022
2 parents e71269c + bf92ca9 commit e0ea123
Show file tree
Hide file tree
Showing 248 changed files with 25,759 additions and 22,706 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ Fei makes use of Forge as a smart contract development framework alongside Hardh
## Documentation
See the [docs](https://docs.fei.money)

## Release Process
Every Thursday, do the following for the weekly release:

1) Update the current release branch's fixed hardhat block to something within the last hour
2) Clean the release branch if necessary:
- fix any failing tests
- clear out proposals-config
3) Merge the release branch into master. Create a release via the github UI, using the version number of the release branch.
4) Merge master back into develop to ensure that any fixes added are pulled back into develop, and so that the hardcoded fork block is set correctly for the most recent release.
5) Create a new branch off of develop of the format release/major.minor.patch, using an incremented minor version number

For hotfix releases or bugfixes to master, branch off of master, add in the necessary fixes, and merge back into master.
Then tag that commit with a new release number (increment the patch version number here).
Finally merge master back into develop.

## License
Fei Protocol is under [the AGPL v3 license](https://github.com/fei-protocol/fei-protocol-core/tree/7160dda163d45e6d6c7092ef021c365e0031a71f/LICENSE.md)

2 changes: 1 addition & 1 deletion contracts/.prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"files": "*.sol",
"options": {
"printWidth": 80,
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
Expand Down
9 changes: 7 additions & 2 deletions contracts/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ library Constants {

uint256 public constant ONE_YEAR = 365.25 days;

/// @notice the denominator for basis points granularity (10,000) expressed as an int data type
int256 public constant BP_INT = int256(BASIS_POINTS_GRANULARITY);

/// @notice WETH9 address
IWETH public constant WETH =
IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IWETH public constant WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);

/// @notice USD stand-in address
address public constant USD = 0x1111111111111111111111111111111111111111;
Expand All @@ -21,4 +23,7 @@ library Constants {

/// @notice number of decimals in ETH, 18
uint256 public constant ETH_DECIMALS = 18;

/// @notice max-uint
uint256 public constant MAX_UINT = type(uint256).max;
}
11 changes: 2 additions & 9 deletions contracts/core/Core.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,9 @@ contract Core is ICore, Permissions, Initializable {
/// @notice sends TRIBE tokens from treasury to an address
/// @param to the address to send TRIBE to
/// @param amount the amount of TRIBE to send
function allocateTribe(address to, uint256 amount)
external
override
onlyGovernor
{
function allocateTribe(address to, uint256 amount) external override onlyGovernor {
IERC20 _tribe = tribe;
require(
_tribe.balanceOf(address(this)) >= amount,
"Core: Not enough Tribe"
);
require(_tribe.balanceOf(address(this)) >= amount, "Core: Not enough Tribe");

_tribe.transfer(to, amount);

Expand Down
57 changes: 10 additions & 47 deletions contracts/core/Permissions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import "./IPermissions.sol";
contract Permissions is IPermissions, AccessControlEnumerable {
bytes32 public constant override BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant override MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant override PCV_CONTROLLER_ROLE =
keccak256("PCV_CONTROLLER_ROLE");
bytes32 public constant override PCV_CONTROLLER_ROLE = keccak256("PCV_CONTROLLER_ROLE");
bytes32 public constant override GOVERN_ROLE = keccak256("GOVERN_ROLE");
bytes32 public constant override GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");

Expand All @@ -26,30 +25,20 @@ contract Permissions is IPermissions, AccessControlEnumerable {
}

modifier onlyGovernor() {
require(
isGovernor(msg.sender),
"Permissions: Caller is not a governor"
);
require(isGovernor(msg.sender), "Permissions: Caller is not a governor");
_;
}

modifier onlyGuardian() {
require(
isGuardian(msg.sender),
"Permissions: Caller is not a guardian"
);
require(isGuardian(msg.sender), "Permissions: Caller is not a guardian");
_;
}

/// @notice creates a new role to be maintained
/// @param role the new role id
/// @param adminRole the admin role id for `role`
/// @dev can also be used to update admin of existing role
function createRole(bytes32 role, bytes32 adminRole)
external
override
onlyGovernor
{
function createRole(bytes32 role, bytes32 adminRole) external override onlyGovernor {
_setRoleAdmin(role, adminRole);
}

Expand All @@ -67,11 +56,7 @@ contract Permissions is IPermissions, AccessControlEnumerable {

/// @notice grants controller role to address
/// @param pcvController new controller
function grantPCVController(address pcvController)
external
override
onlyGovernor
{
function grantPCVController(address pcvController) external override onlyGovernor {
grantRole(PCV_CONTROLLER_ROLE, pcvController);
}

Expand Down Expand Up @@ -101,11 +86,7 @@ contract Permissions is IPermissions, AccessControlEnumerable {

/// @notice revokes pcvController role from address
/// @param pcvController ex pcvController
function revokePCVController(address pcvController)
external
override
onlyGovernor
{
function revokePCVController(address pcvController) external override onlyGovernor {
revokeRole(PCV_CONTROLLER_ROLE, pcvController);
}

Expand All @@ -124,15 +105,8 @@ contract Permissions is IPermissions, AccessControlEnumerable {
/// @notice revokes a role from address
/// @param role the role to revoke
/// @param account the address to revoke the role from
function revokeOverride(bytes32 role, address account)
external
override
onlyGuardian
{
require(
role != GOVERN_ROLE,
"Permissions: Guardian cannot revoke governor"
);
function revokeOverride(bytes32 role, address account) external override onlyGuardian {
require(role != GOVERN_ROLE, "Permissions: Guardian cannot revoke governor");

// External call because this contract is appointed as a governor and has access to revoke
this.revokeRole(role, account);
Expand All @@ -155,26 +129,15 @@ contract Permissions is IPermissions, AccessControlEnumerable {
/// @notice checks if address is a controller
/// @param _address address to check
/// @return true _address is a controller
function isPCVController(address _address)
external
view
override
returns (bool)
{
function isPCVController(address _address) external view override returns (bool) {
return hasRole(PCV_CONTROLLER_ROLE, _address);
}

/// @notice checks if address is a governor
/// @param _address address to check
/// @return true _address is a governor
// only virtual for testing mock override
function isGovernor(address _address)
public
view
virtual
override
returns (bool)
{
function isGovernor(address _address) public view virtual override returns (bool) {
return hasRole(GOVERN_ROLE, _address);
}

Expand Down
31 changes: 21 additions & 10 deletions contracts/core/TribeRoles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,30 @@ library TribeRoles {
/// @notice can mint FEI arbitrarily
bytes32 internal constant MINTER = keccak256("MINTER_ROLE");

/// @notice Manages lower level - Admin and Minor - roles. Able to grant and revoke these
bytes32 internal constant ROLE_ADMIN = keccak256("ROLE_ADMIN");

/*///////////////////////////////////////////////////////////////
Admin Roles
//////////////////////////////////////////////////////////////*/

/// @notice has access to all admin functionality on pods
bytes32 internal constant POD_ADMIN = keccak256("POD_ADMIN");

/// @notice capable of granting and revoking other TribeRoles from having veto power over a pod
bytes32 internal constant POD_VETO_ADMIN = keccak256("POD_VETO_ADMIN");

/// @notice can manage the majority of Tribe protocol parameters. Sets boundaries for MINOR_PARAM_ROLE.
bytes32 internal constant PARAMETER_ADMIN = keccak256("PARAMETER_ADMIN");

/// @notice manages the Collateralization Oracle as well as other protocol oracles.
bytes32 internal constant ORACLE_ADMIN = keccak256("ORACLE_ADMIN_ROLE");

/// @notice manages TribalChief incentives and related functionality.
bytes32 internal constant TRIBAL_CHIEF_ADMIN =
keccak256("TRIBAL_CHIEF_ADMIN_ROLE");
bytes32 internal constant TRIBAL_CHIEF_ADMIN = keccak256("TRIBAL_CHIEF_ADMIN_ROLE");

/// @notice admin of PCVGuardian
bytes32 internal constant PCV_GUARDIAN_ADMIN =
keccak256("PCV_GUARDIAN_ADMIN_ROLE");
bytes32 internal constant PCV_GUARDIAN_ADMIN = keccak256("PCV_GUARDIAN_ADMIN_ROLE");

/// @notice admin of all Minor Roles
bytes32 internal constant MINOR_ROLE_ADMIN = keccak256("MINOR_ROLE_ADMIN");
Expand All @@ -61,29 +68,33 @@ library TribeRoles {

/// @notice manages meta-governance actions, like voting & delegating.
/// Also used to vote for gauge weights & similar liquid governance things.
bytes32 internal constant METAGOVERNANCE_VOTE_ADMIN =
keccak256("METAGOVERNANCE_VOTE_ADMIN");
bytes32 internal constant METAGOVERNANCE_VOTE_ADMIN = keccak256("METAGOVERNANCE_VOTE_ADMIN");

/// @notice allows to manage locking of vote-escrowed tokens, and staking/unstaking
/// governance tokens from a pre-defined contract in order to eventually allow voting.
/// Examples: ANGLE <> veANGLE, AAVE <> stkAAVE, CVX <> vlCVX, CRV > cvxCRV.
bytes32 internal constant METAGOVERNANCE_TOKEN_STAKING =
keccak256("METAGOVERNANCE_TOKEN_STAKING");
bytes32 internal constant METAGOVERNANCE_TOKEN_STAKING = keccak256("METAGOVERNANCE_TOKEN_STAKING");

/// @notice manages whitelisting of gauges where the protocol's tokens can be staked
bytes32 internal constant METAGOVERNANCE_GAUGE_ADMIN =
keccak256("METAGOVERNANCE_GAUGE_ADMIN");
bytes32 internal constant METAGOVERNANCE_GAUGE_ADMIN = keccak256("METAGOVERNANCE_GAUGE_ADMIN");

/*///////////////////////////////////////////////////////////////
Minor Roles
//////////////////////////////////////////////////////////////*/
bytes32 internal constant POD_METADATA_REGISTER_ROLE = keccak256("POD_METADATA_REGISTER_ROLE");

/// @notice capable of poking existing LBP auctions to exchange tokens.
bytes32 internal constant LBP_SWAP_ROLE = keccak256("SWAP_ADMIN_ROLE");

/// @notice capable of engaging with Votium for voting incentives.
bytes32 internal constant VOTIUM_ROLE = keccak256("VOTIUM_ADMIN_ROLE");

/// @notice capable of adding an address to multi rate limited
bytes32 internal constant ADD_MINTER_ROLE = keccak256("ADD_MINTER_ROLE");

/// @notice capable of changing parameters within non-critical ranges
bytes32 internal constant MINOR_PARAM_ROLE = keccak256("MINOR_PARAM_ROLE");

/// @notice capable of changing PCV Deposit and Global Rate Limited Minter in the PSM
bytes32 internal constant PSM_ADMIN_ROLE = keccak256("PSM_ADMIN_ROLE");
}
61 changes: 11 additions & 50 deletions contracts/dao/governor/FeiDAO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,22 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20VotesComp.sol";

// Forked functionality from https://github.com/unlock-protocol/unlock/blob/master/smart-contracts/contracts/UnlockProtocolGovernor.sol

contract FeiDAO is
GovernorCompatibilityBravo,
GovernorVotesComp,
GovernorTimelockCompound
{
contract FeiDAO is GovernorCompatibilityBravo, GovernorVotesComp, GovernorTimelockCompound {
uint256 private _votingDelay = 1; // reduce voting delay to 1 block
uint256 private _votingPeriod = 13000; // extend voting period to 48h
uint256 private _quorum = 25_000_000e18;
uint256 private _proposalThreshold = 2_500_000e18;

address private _guardian;
uint256 private _eta;
address public constant BACKUP_GOVERNOR =
0x4C895973334Af8E06fd6dA4f723Ac24A5f259e6B;
address public constant BACKUP_GOVERNOR = 0x4C895973334Af8E06fd6dA4f723Ac24A5f259e6B;
uint256 public constant ROLLBACK_DEADLINE = 1635724800; // Nov 1, 2021 midnight UTC

constructor(
ERC20VotesComp tribe,
ICompoundTimelock timelock,
address guardian
)
GovernorVotesComp(tribe)
GovernorTimelockCompound(timelock)
Governor("Fei DAO")
{
) GovernorVotesComp(tribe) GovernorTimelockCompound(timelock) Governor("Fei DAO") {
_guardian = guardian;
}

Expand All @@ -42,10 +33,7 @@ contract FeiDAO is
event QuorumUpdated(uint256 oldQuorum, uint256 newQuorum);
event VotingDelayUpdated(uint256 oldVotingDelay, uint256 newVotingDelay);
event VotingPeriodUpdated(uint256 oldVotingPeriod, uint256 newVotingPeriod);
event ProposalThresholdUpdated(
uint256 oldProposalThreshold,
uint256 newProposalThreshold
);
event ProposalThresholdUpdated(uint256 oldProposalThreshold, uint256 newProposalThreshold);
event RollbackQueued(uint256 eta);
event Rollback();

Expand Down Expand Up @@ -84,16 +72,10 @@ contract FeiDAO is
emit QuorumUpdated(oldQuorum, newQuorum);
}

function setProposalThreshold(uint256 newProposalThreshold)
public
onlyGovernance
{
function setProposalThreshold(uint256 newProposalThreshold) public onlyGovernance {
uint256 oldProposalThreshold = _proposalThreshold;
_proposalThreshold = newProposalThreshold;
emit ProposalThresholdUpdated(
oldProposalThreshold,
newProposalThreshold
);
emit ProposalThresholdUpdated(oldProposalThreshold, newProposalThreshold);
}

/// @notice one-time option to roll back the DAO to old GovernorAlpha
Expand All @@ -107,13 +89,7 @@ contract FeiDAO is
_eta = eta;

ICompoundTimelock _timelock = ICompoundTimelock(payable(timelock()));
_timelock.queueTransaction(
timelock(),
0,
"setPendingAdmin(address)",
abi.encode(BACKUP_GOVERNOR),
eta
);
_timelock.queueTransaction(timelock(), 0, "setPendingAdmin(address)", abi.encode(BACKUP_GOVERNOR), eta);

emit RollbackQueued(eta);
}
Expand All @@ -124,13 +100,7 @@ contract FeiDAO is
require(_guardian == address(0), "FeiDAO: no queue");

ICompoundTimelock _timelock = ICompoundTimelock(payable(timelock()));
_timelock.executeTransaction(
timelock(),
0,
"setPendingAdmin(address)",
abi.encode(BACKUP_GOVERNOR),
_eta
);
_timelock.executeTransaction(timelock(), 0, "setPendingAdmin(address)", abi.encode(BACKUP_GOVERNOR), _eta);

emit Rollback();
}
Expand All @@ -139,7 +109,7 @@ contract FeiDAO is
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesComp)
override(Governor, IGovernor)
returns (uint256)
{
return super.getVotes(account, blockNumber);
Expand All @@ -159,11 +129,7 @@ contract FeiDAO is
uint256[] memory values,
bytes[] memory calldatas,
string memory description
)
public
override(IGovernor, Governor, GovernorCompatibilityBravo)
returns (uint256)
{
) public override(IGovernor, Governor, GovernorCompatibilityBravo) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}

Expand All @@ -186,12 +152,7 @@ contract FeiDAO is
return super._cancel(targets, values, calldatas, descriptionHash);
}

function _executor()
internal
view
override(Governor, GovernorTimelockCompound)
returns (address)
{
function _executor() internal view override(Governor, GovernorTimelockCompound) returns (address) {
return super._executor();
}

Expand Down
Loading

0 comments on commit e0ea123

Please sign in to comment.