all files / contracts/ FloatToken.sol

79.17% Statements 19/24
50% Branches 1/2
50% Functions 6/12
79.17% Lines 19/24
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161                                                                                                14× 14× 14× 14× 14× 14×   14× 14×   14× 14× 14×   14×     14×                             96×                               96×   96×                                   96×             96×                                 96×                                        
// SPDX-License-Identifier: BUSL-1.1
 
pragma solidity 0.8.3;
 
import "@openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol";
 
import "./interfaces/IFloatToken.sol";
 
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
 
/**
 @title FloatToken
 @notice The Float Token is the governance token for the Float Capital protocol
 */
contract FloatToken is
  IFloatToken,
  Initializable,
  ERC20Upgradeable,
  ERC20BurnableUpgradeable,
  PausableUpgradeable,
  AccessControlUpgradeable,
  ERC20PermitUpgradeable,
  ERC20VotesUpgradeable,
  UUPSUpgradeable
{
  bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
  bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
  bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
 
  /**
   @notice Initialize the Float Token with relevant
   @dev This function is called `initialize` to differentiate it from `initialize(string,string)` in the parent contract which should NOT be called to initialize this contract. 
   @param name The name of the Float governance token
   @param symbol The ticker representing the token
   @param stakerAddress The staker contract that controls minting of the token
   */
  function initialize(
    string calldata name,
    string calldata symbol,
    address stakerAddress
  ) external initializer {
    __ERC20_init(name, symbol);
    __ERC20Burnable_init();
    __Pausable_init();
    __AccessControl_init();
    __ERC20Permit_init(name);
    __UUPSUpgradeable_init();
 
    renounceRole(DEFAULT_ADMIN_ROLE, msg.sender);
    renounceRole(MINTER_ROLE, msg.sender);
 
    _setupRole(DEFAULT_ADMIN_ROLE, stakerAddress);
    _setupRole(MINTER_ROLE, stakerAddress);
    _setupRole(PAUSER_ROLE, msg.sender);
 
    _setupRole(UPGRADER_ROLE, msg.sender);
 
    // Token starts as paused
    _pause();
  }
 
  /*╔═══════════════════════════════════════════════════════════════════╗
    ║    FUNCTIONS INHERITED BY ERC20PresetMinterPauserUpgradeable      ║
    ╚═══════════════════════════════════════════════════════════════════╝*/
 
  /** 
  @notice Mints an amount of Float tokens for an address.
  @dev Can only be called by addresses with a MINTER_ROLE. 
        This should correspond to the Staker contract.
  @param to The address for which to mint the tokens for.
  @param amount Amount of synthetic tokens to mint in wei.
  */
  function mint(address to, uint256 amount) external override(IFloatToken) onlyRole(MINTER_ROLE) {
    _mint(to, amount);
  }
 
  /**
   @notice modify token functionality so that a pausing this token doesn't affect minting
   @dev Pause functionality in the open zeppelin ERC20PresetMinterPauserUpgradeable comes from the below function.
    We override it to exclude anyone with the minter role (ie the Staker contract)
   @param from address tokens are being sent from
   @param to address tokens are being sent to
   @param amount amount of tokens being sent
   */
  function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
  ) internal virtual override {
    Erequire(!paused() || hasRole(MINTER_ROLE, _msgSender()), "Paused and not minter");
 
    super._beforeTokenTransfer(from, to, amount);
  }
 
  function pause() external onlyRole(PAUSER_ROLE) {
    _pause();
  }
 
  function unpause() external onlyRole(PAUSER_ROLE) {
    _unpause();
  }
 
  function _authorizeUpgrade(address newImplementation) internal override onlyRole(UPGRADER_ROLE) {}
 
  function _afterTokenTransfer(
    address from,
    address to,
    uint256 amount
  ) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {
    super._afterTokenTransfer(from, to, amount);
  }
 
  function _mint(address to, uint256 amount)
    internal
    override(ERC20Upgradeable, ERC20VotesUpgradeable)
  {
    super._mint(to, amount);
  }
 
  function _burn(address account, uint256 amount)
    internal
    override(ERC20Upgradeable, ERC20VotesUpgradeable)
  {
    super._burn(account, amount);
  }
 
  function totalSupply()
    public
    view
    virtual
    override(ERC20Upgradeable, IFloatToken)
    returns (uint256)
  {
    return ERC20Upgradeable.totalSupply();
  }
 
  function transfer(address recipient, uint256 amount)
    public
    virtual
    override(ERC20Upgradeable, IFloatToken)
    returns (bool)
  {
    return ERC20Upgradeable.transfer(recipient, amount);
  }
 
  function burnFrom(address account, uint256 amount)
    public
    virtual
    override(ERC20BurnableUpgradeable, IFloatToken)
  {
    ERC20BurnableUpgradeable.burnFrom(account, amount);
  }
}