Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
8ecd7529
Commit
8ecd7529
authored
Jun 21, 2023
by
Andreas Bigger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update governance contracts to use the triple slash natspec styling.
parent
d37d753d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
74 additions
and
104 deletions
+74
-104
GovernanceToken.sol
...ontracts-bedrock/contracts/governance/GovernanceToken.sol
+20
-33
MintManager.sol
...es/contracts-bedrock/contracts/governance/MintManager.sol
+21
-40
GovernanceToken.t.sol
...es/contracts-bedrock/contracts/test/GovernanceToken.t.sol
+14
-0
MintManager.t.sol
packages/contracts-bedrock/contracts/test/MintManager.t.sol
+19
-31
No files found.
packages/contracts-bedrock/contracts/governance/GovernanceToken.sol
View file @
8ecd7529
...
@@ -6,34 +6,27 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
...
@@ -6,34 +6,27 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
/// @custom:predeploy 0x4200000000000000000000000000000000000042
* @custom:predeploy 0x4200000000000000000000000000000000000042
/// @title GovernanceToken
* @title GovernanceToken
/// @notice The Optimism token used in governance and supporting voting and delegation. Implements
* @notice The Optimism token used in governance and supporting voting and delegation. Implements
/// EIP 2612 allowing signed approvals. Contract is "owned" by a `MintManager` instance with
* EIP 2612 allowing signed approvals. Contract is "owned" by a `MintManager` instance with
/// permission to the `mint` function only, for the purposes of enforcing the token
* permission to the `mint` function only, for the purposes of enforcing the token inflation
/// inflation schedule.
* schedule.
*/
contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
/// @notice Constructs the GovernanceToken contract.
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") {}
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") {}
/**
/// @notice Allows the owner to mint tokens.
* @notice Allows the owner to mint tokens.
/// @param _account The account receiving minted tokens.
*
/// @param _amount The amount of tokens to mint.
* @param _account The account receiving minted tokens.
* @param _amount The amount of tokens to mint.
*/
function mint(address _account, uint256 _amount) public onlyOwner {
function mint(address _account, uint256 _amount) public onlyOwner {
_mint(_account, _amount);
_mint(_account, _amount);
}
}
/**
/// @notice Callback called after a token transfer.
* @notice Callback called after a token transfer.
/// @param from The account sending tokens.
*
/// @param to The account receiving tokens.
* @param from The account sending tokens.
/// @param amount The amount of tokens being transfered.
* @param to The account receiving tokens.
* @param amount The amount of tokens being transfered.
*/
function _afterTokenTransfer(
function _afterTokenTransfer(
address from,
address from,
address to,
address to,
...
@@ -42,22 +35,16 @@ contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
...
@@ -42,22 +35,16 @@ contract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {
super._afterTokenTransfer(from, to, amount);
super._afterTokenTransfer(from, to, amount);
}
}
/**
/// @notice Internal mint function.
* @notice Internal mint function.
/// @param to The account receiving minted tokens.
*
/// @param amount The amount of tokens to mint.
* @param to The account receiving minted tokens.
* @param amount The amount of tokens to mint.
*/
function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {
function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {
super._mint(to, amount);
super._mint(to, amount);
}
}
/**
/// @notice Internal burn function.
* @notice Internal burn function.
/// @param account The account that tokens will be burned from.
*
/// @param amount The amount of tokens that will be burned.
* @param account The account that tokens will be burned from.
* @param amount The amount of tokens that will be burned.
*/
function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {
function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {
super._burn(account, amount);
super._burn(account, amount);
}
}
...
...
packages/contracts-bedrock/contracts/governance/MintManager.sol
View file @
8ecd7529
...
@@ -4,57 +4,41 @@ pragma solidity 0.8.15;
...
@@ -4,57 +4,41 @@ pragma solidity 0.8.15;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./GovernanceToken.sol";
import "./GovernanceToken.sol";
/**
/// @title MintManager
* @title MintManager
/// @notice Set as `owner` of the governance token and responsible for the token inflation
* @notice Set as `owner` of the OP token and responsible for the token inflation schedule.
/// schedule. Contract acts as the token "mint manager" with permission to the `mint`
* Contract acts as the token "mint manager" with permission to the `mint` function only.
/// function only. Currently permitted to mint once per year of up to 2% of the total
* Currently permitted to mint once per year of up to 2% of the total token supply.
/// token supply. Upgradable to allow changes in the inflation schedule.
* Upgradable to allow changes in the inflation schedule.
*/
contract MintManager is Ownable {
contract MintManager is Ownable {
/**
/// @notice The GovernanceToken that the MintManager can mint tokens
* @notice The GovernanceToken that the MintManager can mint tokens
*/
GovernanceToken public immutable governanceToken;
GovernanceToken public immutable governanceToken;
/**
/// @notice The amount of tokens that can be minted per year.
* @notice The amount of tokens that can be minted per year. The value is a fixed
/// The value is a fixed point number with 4 decimals.
* point number with 4 decimals.
*/
uint256 public constant MINT_CAP = 20; // 2%
uint256 public constant MINT_CAP = 20; // 2%
/**
/// @notice The number of decimals for the MINT_CAP.
* @notice The number of decimals for the MINT_CAP.
*/
uint256 public constant DENOMINATOR = 1000;
uint256 public constant DENOMINATOR = 1000;
/**
/// @notice The amount of time that must pass before the MINT_CAP number of tokens can
* @notice The amount of time that must pass before the MINT_CAP number of tokens can
/// be minted again.
* be minted again.
*/
uint256 public constant MINT_PERIOD = 365 days;
uint256 public constant MINT_PERIOD = 365 days;
/**
/// @notice Tracks the time of last mint.
* @notice Tracks the time of last mint.
*/
uint256 public mintPermittedAfter;
uint256 public mintPermittedAfter;
/**
/// @notice Constructs the MintManager contract.
* @param _upgrader The owner of this contract
/// @param _upgrader The owner of this contract.
* @param _governanceToken The governance token this contract can mint
/// @param _governanceToken The governance token this contract can mint tokens of.
* tokens of
*/
constructor(address _upgrader, address _governanceToken) {
constructor(address _upgrader, address _governanceToken) {
transferOwnership(_upgrader);
transferOwnership(_upgrader);
governanceToken = GovernanceToken(_governanceToken);
governanceToken = GovernanceToken(_governanceToken);
}
}
/**
/// @notice Only the token owner is allowed to mint a certain amount of the
* @notice Only the token owner is allowed to mint a certain amount of OP per year.
/// governance token per year.
*
/// @param _account The account receiving minted tokens.
* @param _account Address to mint new tokens to.
/// @param _amount The amount of tokens to mint.
* @param _amount Amount of tokens to be minted.
*/
function mint(address _account, uint256 _amount) public onlyOwner {
function mint(address _account, uint256 _amount) public onlyOwner {
if (mintPermittedAfter > 0) {
if (mintPermittedAfter > 0) {
require(
require(
...
@@ -72,11 +56,8 @@ contract MintManager is Ownable {
...
@@ -72,11 +56,8 @@ contract MintManager is Ownable {
governanceToken.mint(_account, _amount);
governanceToken.mint(_account, _amount);
}
}
/**
/// @notice Upgrade the owner of the governance token to a new MintManager.
* @notice Upgrade the owner of the governance token to a new MintManager.
/// @param _newMintManager The MintManager to upgrade to.
*
* @param _newMintManager The MintManager to upgrade to.
*/
function upgrade(address _newMintManager) public onlyOwner {
function upgrade(address _newMintManager) public onlyOwner {
require(
require(
_newMintManager != address(0),
_newMintManager != address(0),
...
...
packages/contracts-bedrock/contracts/test/GovernanceToken.t.sol
View file @
8ecd7529
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { CommonTest } from "./CommonTest.t.sol";
// Target contract
import { GovernanceToken } from "../governance/GovernanceToken.sol";
import { GovernanceToken } from "../governance/GovernanceToken.sol";
contract GovernanceToken_Test is CommonTest {
contract GovernanceToken_Test is CommonTest {
...
@@ -9,12 +12,14 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -9,12 +12,14 @@ contract GovernanceToken_Test is CommonTest {
address constant rando = address(0x5678);
address constant rando = address(0x5678);
GovernanceToken internal gov;
GovernanceToken internal gov;
/// @dev Sets up the test suite.
function setUp() public virtual override {
function setUp() public virtual override {
super.setUp();
super.setUp();
vm.prank(owner);
vm.prank(owner);
gov = new GovernanceToken();
gov = new GovernanceToken();
}
}
/// @dev Tests that the constructor sets the correct initial state.
function test_constructor_succeeds() external {
function test_constructor_succeeds() external {
assertEq(gov.owner(), owner);
assertEq(gov.owner(), owner);
assertEq(gov.name(), "Optimism");
assertEq(gov.name(), "Optimism");
...
@@ -23,6 +28,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -23,6 +28,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 0);
assertEq(gov.totalSupply(), 0);
}
}
/// @dev Tests that the owner can successfully call `mint`.
function test_mint_fromOwner_succeeds() external {
function test_mint_fromOwner_succeeds() external {
// Mint 100 tokens.
// Mint 100 tokens.
vm.prank(owner);
vm.prank(owner);
...
@@ -33,6 +39,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -33,6 +39,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 100);
assertEq(gov.totalSupply(), 100);
}
}
/// @dev Tests that `mint` reverts when called by a non-owner.
function test_mint_fromNotOwner_reverts() external {
function test_mint_fromNotOwner_reverts() external {
// Mint 100 tokens as rando.
// Mint 100 tokens as rando.
vm.prank(rando);
vm.prank(rando);
...
@@ -44,6 +51,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -44,6 +51,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 0);
assertEq(gov.totalSupply(), 0);
}
}
/// @dev Tests that the owner can successfully call `burn`.
function test_burn_succeeds() external {
function test_burn_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
@@ -58,6 +66,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -58,6 +66,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 50);
assertEq(gov.totalSupply(), 50);
}
}
/// @dev Tests that the owner can successfully call `burnFrom`.
function test_burnFrom_succeeds() external {
function test_burnFrom_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
@@ -76,6 +85,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -76,6 +85,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 50);
assertEq(gov.totalSupply(), 50);
}
}
/// @dev Tests that `transfer` correctly transfers tokens.
function test_transfer_succeeds() external {
function test_transfer_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
@@ -91,6 +101,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -91,6 +101,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 100);
assertEq(gov.totalSupply(), 100);
}
}
/// @dev Tests that `approve` correctly sets allowances.
function test_approve_succeeds() external {
function test_approve_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
@@ -104,6 +115,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -104,6 +115,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.allowance(rando, owner), 50);
assertEq(gov.allowance(rando, owner), 50);
}
}
/// @dev Tests that `transferFrom` correctly transfers tokens.
function test_transferFrom_succeeds() external {
function test_transferFrom_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
@@ -123,6 +135,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -123,6 +135,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.totalSupply(), 100);
assertEq(gov.totalSupply(), 100);
}
}
/// @dev Tests that `increaseAllowance` correctly increases allowances.
function test_increaseAllowance_succeeds() external {
function test_increaseAllowance_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
@@ -140,6 +153,7 @@ contract GovernanceToken_Test is CommonTest {
...
@@ -140,6 +153,7 @@ contract GovernanceToken_Test is CommonTest {
assertEq(gov.allowance(rando, owner), 100);
assertEq(gov.allowance(rando, owner), 100);
}
}
/// @dev Tests that `decreaseAllowance` correctly decreases allowances.
function test_decreaseAllowance_succeeds() external {
function test_decreaseAllowance_succeeds() external {
// Mint 100 tokens to rando.
// Mint 100 tokens to rando.
vm.prank(owner);
vm.prank(owner);
...
...
packages/contracts-bedrock/contracts/test/MintManager.t.sol
View file @
8ecd7529
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { CommonTest } from "./CommonTest.t.sol";
import { MintManager } from "../governance/MintManager.sol";
// Target contract dependencies
import { GovernanceToken } from "../governance/GovernanceToken.sol";
import { GovernanceToken } from "../governance/GovernanceToken.sol";
// Target contract
import { MintManager } from "../governance/MintManager.sol";
contract MintManager_Initializer is CommonTest {
contract MintManager_Initializer is CommonTest {
address constant owner = address(0x1234);
address constant owner = address(0x1234);
address constant rando = address(0x5678);
address constant rando = address(0x5678);
GovernanceToken internal gov;
GovernanceToken internal gov;
MintManager internal manager;
MintManager internal manager;
/// @dev Sets up the test suite.
function setUp() public virtual override {
function setUp() public virtual override {
super.setUp();
super.setUp();
...
@@ -26,9 +32,7 @@ contract MintManager_Initializer is CommonTest {
...
@@ -26,9 +32,7 @@ contract MintManager_Initializer is CommonTest {
}
}
contract MintManager_constructor_Test is MintManager_Initializer {
contract MintManager_constructor_Test is MintManager_Initializer {
/**
/// @dev Tests that the constructor properly configures the contract.
* @notice Tests that the constructor properly configures the contract.
*/
function test_constructor_succeeds() external {
function test_constructor_succeeds() external {
assertEq(manager.owner(), owner);
assertEq(manager.owner(), owner);
assertEq(address(manager.governanceToken()), address(gov));
assertEq(address(manager.governanceToken()), address(gov));
...
@@ -36,9 +40,7 @@ contract MintManager_constructor_Test is MintManager_Initializer {
...
@@ -36,9 +40,7 @@ contract MintManager_constructor_Test is MintManager_Initializer {
}
}
contract MintManager_mint_Test is MintManager_Initializer {
contract MintManager_mint_Test is MintManager_Initializer {
/**
/// @dev Tests that the mint function properly mints tokens when called by the owner.
* @notice Tests that the mint function properly mints tokens when called by the owner.
*/
function test_mint_fromOwner_succeeds() external {
function test_mint_fromOwner_succeeds() external {
// Mint once.
// Mint once.
vm.prank(owner);
vm.prank(owner);
...
@@ -48,9 +50,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
...
@@ -48,9 +50,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
assertEq(gov.balanceOf(owner), 100);
assertEq(gov.balanceOf(owner), 100);
}
}
/**
/// @dev Tests that the mint function reverts when called by a non-owner.
* @notice Tests that the mint function reverts when called by a non-owner.
*/
function test_mint_fromNotOwner_reverts() external {
function test_mint_fromNotOwner_reverts() external {
// Mint from rando fails.
// Mint from rando fails.
vm.prank(rando);
vm.prank(rando);
...
@@ -58,10 +58,8 @@ contract MintManager_mint_Test is MintManager_Initializer {
...
@@ -58,10 +58,8 @@ contract MintManager_mint_Test is MintManager_Initializer {
manager.mint(owner, 100);
manager.mint(owner, 100);
}
}
/**
/// @dev Tests that the mint function properly mints tokens when called by the owner a second
* @notice Tests that the mint function properly mints tokens when called by the owner a second
/// time after the mint period has elapsed.
* time after the mint period has elapsed.
*/
function test_mint_afterPeriodElapsed_succeeds() external {
function test_mint_afterPeriodElapsed_succeeds() external {
// Mint once.
// Mint once.
vm.prank(owner);
vm.prank(owner);
...
@@ -79,10 +77,8 @@ contract MintManager_mint_Test is MintManager_Initializer {
...
@@ -79,10 +77,8 @@ contract MintManager_mint_Test is MintManager_Initializer {
assertEq(gov.balanceOf(owner), 102);
assertEq(gov.balanceOf(owner), 102);
}
}
/**
/// @dev Tests that the mint function always reverts when called before the mint period has
* @notice Tests that the mint function always reverts when called before the mint period has
/// elapsed, even if the caller is the owner.
* elapsed, even if the caller is the owner.
*/
function test_mint_beforePeriodElapsed_reverts() external {
function test_mint_beforePeriodElapsed_reverts() external {
// Mint once.
// Mint once.
vm.prank(owner);
vm.prank(owner);
...
@@ -100,9 +96,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
...
@@ -100,9 +96,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
assertEq(gov.balanceOf(owner), 100);
assertEq(gov.balanceOf(owner), 100);
}
}
/**
/// @dev Tests that the owner cannot mint more than the mint cap.
* @notice Tests that the owner cannot mint more than the mint cap.
*/
function test_mint_moreThanCap_reverts() external {
function test_mint_moreThanCap_reverts() external {
// Mint once.
// Mint once.
vm.prank(owner);
vm.prank(owner);
...
@@ -123,9 +117,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
...
@@ -123,9 +117,7 @@ contract MintManager_mint_Test is MintManager_Initializer {
}
}
contract MintManager_upgrade_Test is MintManager_Initializer {
contract MintManager_upgrade_Test is MintManager_Initializer {
/**
/// @dev Tests that the owner can upgrade the mint manager.
* @notice Tests that the owner can upgrade the mint manager.
*/
function test_upgrade_fromOwner_succeeds() external {
function test_upgrade_fromOwner_succeeds() external {
// Upgrade to new manager.
// Upgrade to new manager.
vm.prank(owner);
vm.prank(owner);
...
@@ -135,9 +127,7 @@ contract MintManager_upgrade_Test is MintManager_Initializer {
...
@@ -135,9 +127,7 @@ contract MintManager_upgrade_Test is MintManager_Initializer {
assertEq(gov.owner(), rando);
assertEq(gov.owner(), rando);
}
}
/**
/// @dev Tests that the upgrade function reverts when called by a non-owner.
* @notice Tests that the upgrade function reverts when called by a non-owner.
*/
function test_upgrade_fromNotOwner_reverts() external {
function test_upgrade_fromNotOwner_reverts() external {
// Upgrade from rando fails.
// Upgrade from rando fails.
vm.prank(rando);
vm.prank(rando);
...
@@ -145,10 +135,8 @@ contract MintManager_upgrade_Test is MintManager_Initializer {
...
@@ -145,10 +135,8 @@ contract MintManager_upgrade_Test is MintManager_Initializer {
manager.upgrade(rando);
manager.upgrade(rando);
}
}
/**
/// @dev Tests that the upgrade function reverts when attempting to update to the zero
* @notice Tests that the upgrade function reverts when attempting to update to the zero
/// address, even if the caller is the owner.
* address, even if the caller is the owner.
*/
function test_upgrade_toZeroAddress_reverts() external {
function test_upgrade_toZeroAddress_reverts() external {
// Upgrade to zero address fails.
// Upgrade to zero address fails.
vm.prank(owner);
vm.prank(owner);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment