Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions packages/govern-token/contracts/GovernToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ contract GovernToken is IERC20, Initializable {
mapping (address => uint256) override public balanceOf;
mapping (address => mapping (address => uint256)) override public allowance;

bool public transfersRestricted;
mapping (address => bool) internal isWhitelisted;

// ERC-2612, ERC-3009 state
mapping (address => uint256) public nonces;
mapping (address => mapping (bytes32 => bool)) public authorizationState;
Expand All @@ -45,18 +48,26 @@ contract GovernToken is IERC20, Initializable {
event Transfer(address indexed from, address indexed to, uint256 value);
event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
event ChangeMinter(address indexed minter);
event RestrictedTransfers(bool transfersRestricted);
event SetWhitelisted(address indexed entity, bool indexed whitelisted);

modifier onlyMinter {
require(msg.sender == minter, "token: not minter");
_;
}

constructor(address _initialMinter, string memory _name, string memory _symbol, uint8 _decimals) public {
initialize(_initialMinter, _name, _symbol, _decimals);
modifier canTransact(address entity, string memory inOrOut) {
require(!transfersRestricted || isWhitelisted[entity], string(abi.encodePacked("token: bouncer ", inOrOut)));
_;
}

constructor(address _initialMinter, bool _transfersRestricted, string memory _name, string memory _symbol, uint8 _decimals) public {
initialize(_initialMinter, _transfersRestricted,_name, _symbol, _decimals);
}

function initialize(address _initialMinter, string memory _name, string memory _symbol, uint8 _decimals) public onlyInit("token") {
function initialize(address _initialMinter, bool _transfersRestricted, string memory _name, string memory _symbol, uint8 _decimals) public onlyInit("token") {
_changeMinter(_initialMinter);
_setTransfersRestricted(_transfersRestricted);
name = _name;
symbol = _symbol;
decimals = _decimals;
Expand All @@ -80,6 +91,11 @@ contract GovernToken is IERC20, Initializable {
emit ChangeMinter(newMinter);
}

function _setTransfersRestricted(bool _transfersRestricted) internal {
transfersRestricted = _transfersRestricted;
emit RestrictedTransfers(_transfersRestricted);
}

function _mint(address to, uint256 value) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
Expand All @@ -98,7 +114,11 @@ contract GovernToken is IERC20, Initializable {
emit Approval(owner, spender, value);
}

function _transfer(address from, address to, uint256 value) private {
function _transfer(address from, address to, uint256 value)
canTransact(from, "in")
canTransact(to, "out")
private
{
require(to != address(this) && to != address(0), "token: bad to");

// Balance is implicitly checked with SafeMath's underflow protection
Expand Down Expand Up @@ -132,6 +152,15 @@ contract GovernToken is IERC20, Initializable {
_changeMinter(newMinter);
}

function setTransfersRestricted(bool _transfersRestricted) external onlyMinter {
_setTransfersRestricted(_transfersRestricted);
}

function setWhitelisted(address _entity, bool _whitelisted) external onlyMinter {
isWhitelisted[_entity] = _whitelisted;
emit SetWhitelisted(_entity, _whitelisted);
}

function burn(uint256 value) external returns (bool) {
_burn(msg.sender, value);
return true;
Expand Down
7 changes: 5 additions & 2 deletions packages/govern-token/contracts/GovernTokenFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ contract GovernTokenFactory {
GovernMinter minter
) {
if (!_useProxies) {
(token, minter) = _deployContracts(_initialMinter, _tokenName, _tokenSymbol, _tokenDecimals);
(token, minter) = _deployContracts(_initialMinter, false, _tokenName, _tokenSymbol, _tokenDecimals);
} else {
token = GovernToken(tokenBase.clone(abi.encodeWithSelector(
token.initialize.selector,
address(this),
false,
_tokenName,
_tokenSymbol,
_tokenDecimals
Expand Down Expand Up @@ -77,6 +78,7 @@ contract GovernTokenFactory {

(GovernToken token, GovernMinter minter) = _deployContracts(
address(this),
false,
"GovernToken base",
"GTB",
0
Expand All @@ -94,14 +96,15 @@ contract GovernTokenFactory {

function _deployContracts(
address _initialMinter,
bool _transfersRestricted,
string memory _tokenName,
string memory _tokenSymbol,
uint8 _tokenDecimals
) internal returns (
GovernToken token,
GovernMinter minter
) {
token = new GovernToken(address(this), _tokenName, _tokenSymbol, _tokenDecimals);
token = new GovernToken(address(this), _transfersRestricted, _tokenName, _tokenSymbol, _tokenDecimals);
minter = new GovernMinter(GovernToken(token), address(_initialMinter), MerkleDistributor(distributorBase));
}
}