This repository implements the ExtendedOptimismMintableToken.sol. The Extended Optimism Mintable Token contract is an ERC-20 compatible token,
and is based on Optimism's OptimismMintableERC20 contract. It allows minting/burning of tokens by a specified bridge, pausing all activity, freezing of individual
addresses ("blacklisting"), and a way to upgrade the contract so that bugs can be fixed or features added. It also supports gas abstraction functionality by implementing EIP-3009 and using OpenZeppelin's upgradeable EIP-2612 implementation. We describe this functionality further under Functionality. Finally, it uses OpenZeppelin's AccessControl pattern to use role-based access control for the pausing and blacklisting capabilities, designating a role to manage each, along with a DEFAULT_ROLE_ADMIN role to manage those roles (detailed further below).
The ExtendedOptimismMintableToken inherits from the UpgradeableOptimismMintableERC20 contract, which itself is based off of Optimism's OptimismMintableERC20 contract. The UpgradeableOptimismMintableERC20 contains the following changes from Optimism's OptimismMintableERC20:
- OpenZeppelin's
ERC20Upgradeablecontract is used in place of theirERC20contract to support upgradeability. - OpenZeppelin's
IERC165Upgradeablecontract is used in place of theirIERC165contract to support upgradeability. supportsInterfaceis marked aspublic virtualto allow inheriting contracts to both override and call it.- Marks
mintandburnaspublicinstead ofexternalto allow inheriting contracts to call them. - An
initializeinitializer function was added to support the initialization ofERC20Upgradeableconfiguration. - A
decimalsvariable was added to the constructor. - A storage gap was added to simplify state management in the event that state variables are added to
UpgradeableOptimismMintableERC20in the future.
Requirements:
- Node >= v12
- Yarn
- The required versions of the Optimism repo and Foundry are specified in the .env file
- Run
make install-foundryto installFoundryat this linked commit. - Run
make buildto install dependencies. - Run
make teststo run tests. - Run
make coverageto get code coverage. - Set the required .env variables and run
make deployto simulate Base Mainnet token deployment locally.
- Note: To initialize the
ExtendedOptimismMintableTokencontract, you need to call theinitializemethod inherited fromUpgradeableOptimismMintableERC20, and thenExtendedOptimismMintableToken'sinitializeV2method. - Configure the following variables in
.env:DEPLOYER- the address deploying the token implementation and proxy contract.ADMIN- the address to be theadminof the token's proxy contract. Not to be confused with theDEFAULT_ROLE_ADMINenv variable and role specified below, which administrates theblacklisterandpauserroles along with itself.L2_BRIDGE- the address of theL2StandardBridgecontract which is able to mint and burn the token being deployed.REMOTE_TOKEN- the L1 address of the L2 bridged token being deployed.NAME- theERC20nameof the bridged token. This is also used for theEIP-712domain separatorname.SYMBOL- theERC20symbolof the bridged token.DECIMALS- theERC20decimalsof the bridged token.PAUSER- the only address for the role that can pause the contract, which prevents all transfers, minting, and burningBLACKLISTER- the only address for the role that can callblacklist(address), which prevents all transfers to or from that address, andunBlacklist(address)DEFAULT_ROLE_ADMIN- the address for the role which can re-assign itself and thePAUSERandBLACKLISTERroles. This role can NOT change theADMINaddress, which administrates the proxy contract.
- Run
make deployto simulate Base Mainnet token deployment locally.
These scripts can be found in the script/ directory:
DeployExtendedOptimismMintableToken.s.solto deploy and configure a totally newExtendedOptimismMintableTokenimplementation and corresponding proxy contractsUpgradeToExtendedOptimismMintableToken.s.sol.s.solto upgrade an already deployedUpgradeableOptimismMintableERC20to anExtendedOptimismMintableTokenDeployExtendedOptimismMintableTokenImpl.s.solto deploy and configure anExtendedOptimismMintableTokenimplementation contract
These scripts are tested in test/script directory.
The ExtendedOptimismMintableToken allows the BRIDGE address to create (mint) and destroy (`burn``) tokens.
As on Optimism's OptimismMintableERC20 contract, the BRIDGE mints tokens via the mint method. It specifies the
amount of tokens to create, and a _to address which will own the newly
created tokens. The balance of the _to address and totalSupply will each
increase by amount.
- Only the
BRIDGEmay callmint. - Minting fails when the contract is
paused. - Minting fails when the
BRIDGEor_toaddress is blacklisted. - Minting emits a
Mint(_to, amount)event and aTransfer(0x00, _to, amount)event.
As on Optimism's OptimismMintableERC20 contract, the BRIDGE burns tokens via the burn method. It specifies the
The BRIDGE specifies the address _from whose tokens are burned (i.e. whose balance of the token, along with the totalSupply of the token, are reduced by amount) and the
amount of tokens to burn. The _from address must have a balance greater than
or equal to the amount. The abillity to burn tokens is restricted to the BRIDGE address.
-
Only the
BRIDGEaddress may call burn. -
Burning fails when the contract is paused.
-
Burning fails when the calling address is blacklisted.
-
Burning fails when the
_fromaddress is blacklisted. -
Burning emits a
Burn(_from_, amount)event, and aTransfer(_from_, 0x00, amount)event.
Addresses can be blacklisted. A blacklisted address will be unable to participate in the approval, increase or decrease of allowances and will be unable to transfer, mint, or burn tokens.
Coinbase blacklists an address via the blacklist method. The specified account
will be added to the blacklist.
- Only the
blacklisterrole may callblacklist. - Blacklisting emits a
Blacklist(account)event
Coinbase removes an address from the blacklist via the unblacklist method. The
specified account will be removed from the blacklist.
- Only the
blacklisterrole may callunblacklist. - Unblacklisting emits an
UnBlacklist(account)event.
The entire contract can be paused in case a serious bug is found or there is a serious key compromise. All transfers, minting, and burning will be prevented while the contract is paused. Other functionality, such as modifying the blacklist, changing roles, and upgrading will remain operational as those methods may be required to fix or mitigate the issue that caused Coinbase to pause the contract.
Coinbase will pause the contract via the pause method. This method will set the
paused flag to true.
-
Only the
pauserrole may call pause. -
Pausing emits a
Pause()event
Coinbase will unpause the contract via the unpause method. This method will set
the paused flag to false. All functionality will be restored when the contract
is unpaused.
-
Only the
pauserrole may call unpause. -
Unpausing emits an
Unpause()event
The ExtendedOptimismMintableToken implements EIP-3009, with the additional requirement that transfers via this functionality not be called with blacklisted from or to addresses, nor while the contract is paused.
The ExtendedOptimismMintableToken uses OpenZeppelin's EIP-2612 upgradeable implementation, and adds the requirement that permit not be called with blacklisted owner or spender addresses, nor while the contract is paused.
The Extended OptimismMintable Token uses the Unstructured-Storage Proxy pattern
[https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies]. The contracts use storage gaps to simplify state management in the event that state variables are added to in future upgrades. ExtendedOptimismMintableToken.sol is the implementation, the
actual token address will be a Proxy contract
(using the code from Optimism's Proxy.sol) which will forward all
calls to ExtendedOptimismMintableToken via delegatecall. This pattern allows Coinbase to upgrade the
logic of any deployed tokens seamlessly.
- Coinbase will upgrade the token via a call to
upgradeToorupgradeToAndCallif initialization is required for the new version. - Only the Proxy contract's
adminrole may callupgradeToorupgradeToAndCall. - For upgrades, if an initializer method is used, set a constant version in the
reinitializermodifier that is incremented from the previous upgrade's version. This prevents the initializer method from being called multiple times. Failing to follow this guidance could introduce vulnerabilities. Additionally, note subsequently introducedreinitializermethods are not meant to re-execute the same initialization code used in previous versions.
The roles (blacklister, pauser) described above may be reassigned. The DEFAULT_ROLE_ADMIN role has the ability to
reassign itself and the blacklister and pauser roles. It cannot re-assign the Proxy contract's admin role. The BRIDGE address is immutable, in keeping with the OptimismMintableERC20 contract.
changeRolesAdminupdates theDEFAULT_ROLE_ADMINrole to a new address.changeRolesAdminmay only be called by theDEFAULT_ROLE_ADMINrole.
In general, function parameters should be named, are not prefixed with underscores and are written in camelCase.
We have deviated from this guideline in the following cases. Where referencing code from other codebases, we have followed their parameter styling convention (ex. prefixing parameters with an underscore in the mint and burn methods as the Optimism repo does for their OptimismMintableERC20 contract, OpenZeppelin ERC20 methods, etc). For consistency, in methods like initializeV2 where one parameter (_name) is prefixed with an underscore (in this case to differentiate it from the storage variable it's meant to fill), we prefix the other parameters for the same function with an underscore. Parameter names in renounceRole on ExtendedOptimismMintableToken are not named as they would be unused - in this case, the parameters are included to override the same-named method from the AccessControlUpgradable contract.
This work uses software from The Optimism Monorepo:
title: The Optimism Monorepo
authors:
- name: The Optimism Collective
version: 1.0.0
year: 2020
url: https://github.com/ethereum-optimism/optimism
repository: https://github.com/ethereum-optimism/optimism
license: MIT
Where this code indicates it uses code from the CENTRE codebase, it references this commit https://github.com/centrehq/centre-tokens/commit/0d3cab14ebd133a83fc834dbd48d0468bdf0b391
I.e. from the CENTRE Fiat Token codebase, we specifically reference: