Commit 8ecd7529 authored by Andreas Bigger's avatar Andreas Bigger

Update governance contracts to use the triple slash natspec styling.

parent d37d753d
...@@ -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);
} }
......
...@@ -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),
......
// 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);
......
// 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment