Address
0xdab396ccf3d84cf2d07c4454e10c8a6f5b008d2bCurrent Holdings
$0.00
TXs sent
not counted
First Active
2023-05-13
block 17,250,807
Last Active
84 days ago
block 26,860,704
Funded By
not identified
Net worth historyi
2 snapshots · to block 27,430,135coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
exact matchGFIsolc 0.6.12+commit.27d51765runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol";
/**
* @title GFI
* @notice GFI is Goldfinch's governance token.
* @author Goldfinch
*/
contract GFI is Context, AccessControl, ERC20Burnable, ERC20Pausable {
using SafeMath for uint256;
bytes32 public constant OWNER_ROLE = keccak256("OWNER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/// The maximum number of tokens that can be minted
uint256 public cap;
event CapUpdated(address indexed who, uint256 cap);
constructor(
address owner,
string memory name,
string memory symbol,
uint256 initialCap
) public ERC20(name, symbol) {
cap = initialCap;
_setupRole(MINTER_ROLE, owner);
_setupRole(PAUSER_ROLE, owner);
_setupRole(OWNER_ROLE, owner);
_setRoleAdmin(MINTER_ROLE, OWNER_ROLE);
_setRoleAdmin(PAUSER_ROLE, OWNER_ROLE);
_setRoleAdmin(OWNER_ROLE, OWNER_ROLE);
}
/**
* @notice create and send tokens to a specified address
* @dev this function will fail if the caller attempts to mint over the current cap
*/
function mint(address account, uint256 amount) public onlyMinter whenNotPaused {
require(mintingAmountIsWithinCap(amount), "Cannot mint more than cap");
_mint(account, amount);
}
/**
* @notice sets the maximum number of tokens that can be minted
* @dev the cap must be greater than the current total supply
*/
function setCap(uint256 _cap) external onlyOwner {
require(_cap >= totalSupply(), "Cannot decrease the cap below existing supply");
cap = _cap;
emit CapUpdated(_msgSender(), cap);
}
function mintingAmountIsWithinCap(uint256 amount) internal returns (bool) {
return totalSupply().add(amount) <= cap;
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() external onlyPauser {
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() external onlyPauser {
_unpause();
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal override(ERC20, ERC20Pausable) {
super._beforeTokenTransfer(from, to, amount);
}
modifier onlyOwner() {
require(hasRole(OWNER_ROLE, _msgSender()), "Must be owner");
_;
}
modifier onlyMinter() {
require(hasRole(MINTER_ROLE, _msgSender()), "Must be minter");
_;
}
modifier onlyPauser() {
require(hasRole(PAUSER_ROLE, _msgSender()), "Must be pauser");
_;
}
}