{"id":18542771,"url":"https://github.com/coinbase/extended-optimism-mintable-token","last_synced_at":"2025-04-23T19:45:27.037Z","repository":{"id":223759184,"uuid":"671677904","full_name":"coinbase/extended-optimism-mintable-token","owner":"coinbase","description":"Mintable ERC20-compliant token contracts with additional features, compatible with the Superchain","archived":false,"fork":false,"pushed_at":"2024-04-04T15:50:57.000Z","size":971,"stargazers_count":7,"open_issues_count":6,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-30T02:51:12.284Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coinbase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-27T22:10:08.000Z","updated_at":"2024-12-06T05:05:08.000Z","dependencies_parsed_at":"2024-11-06T20:10:39.496Z","dependency_job_id":"e006347d-bdd5-44a5-9e0a-3b56fbbb70c7","html_url":"https://github.com/coinbase/extended-optimism-mintable-token","commit_stats":null,"previous_names":["coinbase/extended-optimism-mintable-token"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Fextended-optimism-mintable-token","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Fextended-optimism-mintable-token/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Fextended-optimism-mintable-token/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Fextended-optimism-mintable-token/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coinbase","download_url":"https://codeload.github.com/coinbase/extended-optimism-mintable-token/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250502252,"owners_count":21441180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T20:10:37.075Z","updated_at":"2025-04-23T19:45:27.011Z","avatar_url":"https://github.com/coinbase.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ExtendedOptimismMintableToken\nThis repository implements the [`ExtendedOptimismMintableToken.sol`](./src/ExtendedOptimismMintableToken.sol). The Extended Optimism Mintable Token contract is an ERC-20 compatible token, \nand is based on Optimism's [`OptimismMintableERC20`](https://github.com/ethereum-optimism/optimism/blob/0f07717bf06c2278bbccc9c62cad30731beeb322/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20.sol) contract. It allows minting/burning of tokens by a specified bridge, pausing all activity, freezing of individual\naddresses (\"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](https://eips.ethereum.org/EIPS/eip-3009) and using OpenZeppelin's upgradeable [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) implementation. We describe this functionality further under [Functionality](#functionality). Finally, it uses OpenZeppelin's [AccessControl](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v4.7.3/contracts/access/AccessControlUpgradeable.sol) 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).\n\n### UpgradeableOptimismMintableERC20\nThe `ExtendedOptimismMintableToken` inherits from the `UpgradeableOptimismMintableERC20` contract, which itself is based off of Optimism's [OptimismMintableERC20](https://github.com/ethereum-optimism/optimism/blob/0f07717bf06c2278bbccc9c62cad30731beeb322/packages/contracts-bedrock/contracts/universal/OptimismMintableERC20.sol) contract. The `UpgradeableOptimismMintableERC20` contains the following changes from Optimism's `OptimismMintableERC20`:\n * OpenZeppelin's [`ERC20Upgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v4.7.3/contracts/token/ERC20/ERC20Upgradeable.sol) contract is used in place of their [`ERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.3/contracts/token/ERC20/ERC20.sol) contract to support upgradeability.\n * OpenZeppelin's [`IERC165Upgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v4.7.3/contracts/utils/introspection/IERC165Upgradeable.sol) contract is used in place of their [`IERC165`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.3/contracts/utils/introspection/IERC165.sol) contract to support upgradeability.\n * `supportsInterface` is marked as `public virtual` to allow inheriting contracts to both override and call it.\n * Marks `mint` and `burn` as `public` instead of `external` to allow inheriting contracts to call them.\n* An `initialize` initializer function was added to support the initialization of `ERC20Upgradeable` configuration.\n* A `decimals` variable was added to the constructor.\n* A storage gap was added to simplify state management in the event that state variables are added to `UpgradeableOptimismMintableERC20` in the future.\n\n### Commands and Setup\nRequirements:\n- Node \u003e= v12\n- Yarn\n- The required versions of the Optimism repo and Foundry are specified in the .env file\n\n* Run `make install-foundry` to install [`Foundry` at this linked commit](https://github.com/foundry-rs/foundry/commit/3b1129b5bc43ba22a9bcf4e4323c5a9df0023140). \n* Run `make build` to install dependencies.\n* Run `make tests` to run tests.\n* Run `make coverage` to get code coverage.\n* Set the required .env variables and run `make deploy` to simulate Base Mainnet token deployment locally.\n\n### Deployment\n* **Note**: To initialize the `ExtendedOptimismMintableToken` contract, you need to call the `initialize` method inherited from `UpgradeableOptimismMintableERC20`, and then  `ExtendedOptimismMintableToken`'s `initializeV2` method.\n* Configure the following variables in `.env`:\n    * `DEPLOYER` - the address deploying the token implementation and proxy contract.\n    * `ADMIN` - the address to be the `admin` of the token's proxy contract. Not to be confused with the `DEFAULT_ROLE_ADMIN` env variable and role specified below, which administrates the `blacklister` and `pauser` roles along with itself.\n    * `L2_BRIDGE` - the address of the [`L2StandardBridge`](https://github.com/ethereum-optimism/optimism/blob/0f07717bf06c2278bbccc9c62cad30731beeb322/packages/contracts-bedrock/contracts/L2/L2StandardBridge.sol) contract which is able to mint and burn the token being deployed.\n    * `REMOTE_TOKEN` - the L1 address of the L2 bridged token being deployed.\n    * `NAME` - the `ERC20` [`name`](https://eips.ethereum.org/EIPS/eip-20#name) of the bridged token. This is also used for the `EIP-712` domain separator [`name`](https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator).\n    * `SYMBOL` - the `ERC20` [`symbol`](https://eips.ethereum.org/EIPS/eip-20#symbol) of the bridged token.\n    * `DECIMALS` - the `ERC20` [`decimals`](https://eips.ethereum.org/EIPS/eip-20#decimals) of the bridged token.\n    * `PAUSER` - the only address for the role that can pause the contract, which prevents all transfers, minting, and burning\n    * `BLACKLISTER` - the only address for the role that can call `blacklist(address)`, which prevents all transfers to or from that address, and `unBlacklist(address)`\n    * `DEFAULT_ROLE_ADMIN` - the address for the role which can re-assign itself and the `PAUSER` and `BLACKLISTER` roles. This role can NOT change the `ADMIN` address, which administrates the proxy contract.\n* Run `make deploy` to simulate Base Mainnet token deployment locally.\n\nThese scripts can be found in the `script/` directory:\n- [`DeployExtendedOptimismMintableToken.s.sol`](script/DeployExtendedOptimismMintableToken.s.sol) to deploy and configure a totally new `ExtendedOptimismMintableToken` implementation and corresponding proxy contracts\n- [`UpgradeToExtendedOptimismMintableToken.s.sol.s.sol`](script/UpgradeToExtendedOptimismMintableToken.s.sol) to upgrade an already deployed `UpgradeableOptimismMintableERC20` to an `ExtendedOptimismMintableToken` \n- [`DeployExtendedOptimismMintableTokenImpl.s.sol`](script/DeployExtendedOptimismMintableTokenImpl.s.sol) to deploy and configure an `ExtendedOptimismMintableToken` implementation contract\n\nThese scripts are tested in [`test/script`](test/script) directory.\n\n## Functionality \n\n### Issuing and Destroying tokens\nThe `ExtendedOptimismMintableToken` allows the `BRIDGE` address to create (`mint`) and destroy (`burn``) tokens.\n\n#### Minting\nAs on Optimism's `OptimismMintableERC20` contract, the `BRIDGE` mints tokens via the `mint` method. It specifies the\n`amount` of tokens to create, and a `_to` address which will own the newly\ncreated tokens. The balance of the `_to` address and `totalSupply` will each\nincrease by `amount`. \n\n- Only the `BRIDGE` may call `mint`.\n- Minting fails when the contract is `paused`.\n- Minting fails when the `BRIDGE` or `_to` address is blacklisted.\n- Minting emits a `Mint(_to, amount)` event and a\n  `Transfer(0x00, _to, amount)` event.\n\n#### Burning\nAs on Optimism's `OptimismMintableERC20` contract, the `BRIDGE` burns tokens via the `burn` method. It specifies the\nThe `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 \n`amount` of tokens to burn. The `_from` address must have a `balance` greater than\nor equal to the `amount`. The abillity to burn tokens is restricted to the `BRIDGE` address.\n\n- Only the `BRIDGE` address may call burn.\n\n- Burning fails when the contract is paused.\n- Burning fails when the calling address is blacklisted.\n- Burning fails when the `_from` address is blacklisted.\n\n- Burning emits a `Burn(_from_, amount)` event, and a\n  `Transfer(_from_, 0x00, amount)` event.\n\n### Blacklisting\n\nAddresses can be blacklisted. A blacklisted address will be unable to participate in the approval, \nincrease or decrease of allowances and will be unable to transfer, mint, or burn tokens.\n\n#### Adding a blacklisted address\n\nCoinbase blacklists an address via the `blacklist` method. The specified `account`\nwill be added to the blacklist.\n\n- Only the `blacklister` role may call `blacklist`.\n- Blacklisting emits a `Blacklist(account)` event\n\n#### Removing a blacklisted address\n\nCoinbase removes an address from the blacklist via the `unblacklist` method. The\nspecified `account` will be removed from the blacklist.\n\n- Only the `blacklister` role may call `unblacklist`.\n- Unblacklisting emits an `UnBlacklist(account)` event.\n\n### Pausing\n\nThe entire contract can be paused in case a serious bug is found or there is a\nserious key compromise. All transfers, minting, and burning will\nbe prevented while the contract is paused. Other functionality, such as\nmodifying the blacklist, changing roles, and upgrading will\nremain operational as those methods may be required to fix or mitigate the issue\nthat caused Coinbase to pause the contract.\n\n#### Pause\n\nCoinbase will pause the contract via the `pause` method. This method will set the\npaused flag to true.\n\n- Only the `pauser` role may call pause.\n\n- Pausing emits a `Pause()` event\n\n#### Unpause\n\nCoinbase will unpause the contract via the `unpause` method. This method will set\nthe `paused` flag to false. All functionality will be restored when the contract\nis unpaused.\n\n- Only the `pauser` role may call unpause.\n\n- Unpausing emits an `Unpause()` event\n\n### Gas Abstraction\n\n#### EIP-3009\nThe `ExtendedOptimismMintableToken` implements [EIP-3009](https://eips.ethereum.org/EIPS/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.\n\n#### EIP-2612\nThe `ExtendedOptimismMintableToken` uses OpenZeppelin's [EIP-2612](https://eips.ethereum.org/EIPS/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.\n\n### Upgrading\n\nThe Extended OptimismMintable Token uses the  Unstructured-Storage Proxy pattern\n[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`](./src/ExtendedOptimismMintableToken.sol) is the implementation, the\nactual token address will be a Proxy contract\n(using the code from Optimism's [Proxy.sol](https://github.com/ethereum-optimism/optimism/blob/0f07717bf06c2278bbccc9c62cad30731beeb322/packages/contracts-bedrock/contracts/universal/Proxy.sol)) which will forward all\ncalls to `ExtendedOptimismMintableToken` via delegatecall. This pattern allows Coinbase to upgrade the\nlogic of any deployed tokens seamlessly.\n\n- Coinbase will upgrade the token via a call to `upgradeTo` or `upgradeToAndCall`\n  if initialization is required for the new version.\n- Only the Proxy contract's `admin` role may call `upgradeTo` or `upgradeToAndCall`.\n- For upgrades, if an initializer method is used, set a constant version in the `reinitializer` modifier 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 introduced `reinitializer` methods are not meant to re-execute the same initialization code used in previous versions.\n\n### Reassigning Roles\n\nThe roles (`blacklister`, `pauser`) described above may be reassigned. The `DEFAULT_ROLE_ADMIN` role has the ability to\nreassign 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.\n\n- `changeRolesAdmin` updates the `DEFAULT_ROLE_ADMIN` role to a new address.\n- `changeRolesAdmin` may only be called by the `DEFAULT_ROLE_ADMIN` role.\n\n### Convention for function parameter styling\nIn general, function parameters should be named, are not prefixed with underscores and are written in camelCase.\n\nWe 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. \n\n### Optimism Citation\nThis work uses software from The Optimism Monorepo:\n```\ntitle: The Optimism Monorepo\nauthors:\n- name: The Optimism Collective\nversion: 1.0.0\nyear: 2020\nurl: https://github.com/ethereum-optimism/optimism\nrepository: https://github.com/ethereum-optimism/optimism\nlicense: MIT\n```\n\n### CENTRE code references\nWhere this code indicates it uses code from the CENTRE codebase, it references\nthis commit [https://github.com/centrehq/centre-tokens/commit/0d3cab14ebd133a83fc834dbd48d0468bdf0b391](https://github.com/centrehq/centre-tokens/commit/0d3cab14ebd133a83fc834dbd48d0468bdf0b391)\n\nI.e. from the CENTRE Fiat Token codebase, we specifically reference:\n* [Blacklistable.sol](https://github.com/centrehq/centre-tokens/blob/0d3cab14ebd133a83fc834dbd48d0468bdf0b391/contracts/v1/Blacklistable.sol)\n* [EIP3009.sol](https://github.com/centrehq/centre-tokens/blob/0d3cab14ebd133a83fc834dbd48d0468bdf0b391/contracts/v2/EIP3009.sol) \n* [AbstractFiatTokenV1.sol](https://github.com/centrehq/centre-tokens/blob/0d3cab14ebd133a83fc834dbd48d0468bdf0b391/contracts/v1/AbstractFiatTokenV1.sol) ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoinbase%2Fextended-optimism-mintable-token","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoinbase%2Fextended-optimism-mintable-token","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoinbase%2Fextended-optimism-mintable-token/lists"}