Circle’s FiatToken contract is an ERC-20 compatible token. It allows minting/burning of tokens by multiple entities, pausing all activity, freezing of individual addresses, and a way to upgrade the contract so that bugs can be fixed or features added.
The FiatToken
has a number of roles (addresses) which control different
functionality:
masterMinter
- adds and removes minters and increases their minting
allowanceminters
- create and destroy tokenspauser
- pause the contract, which prevents all transfers, minting, and
burningblacklister
- prevent all transfers to or from a particular address, and
prevents that address from minting or burningowner
- re-assign any of the roles except for admin
admin
- manage the proxy-level functionalities such as switching the
implementation contractrescuer
- transfer any ERC-20 tokens that are locked up in the contractCircle will control the address of all roles.
The FiatToken
implements the standard methods of the ERC-20 interface with
some changes:
transfer
or transferFrom
, and
will be unable to receive tokens.
approve
was not allowed for blacklisted addresses in FiatToken versions
<2.2 but available in versions 2.2+. See “Blacklisting”
section for more details.transfer
, transferFrom
, and approve
will fail if the contract has been
paused.The FiatToken contract allows multiple entities to create and destroy tokens. These entities will have to be members of Circle, and will be vetted by Circle before they are allowed to create new tokens.
Each minter
has a minterAllowance
, which Circle configures. The
minterAllowance
is how many tokens that minter may issue, and as a minter
issues tokens, its minterAllowance
declines. Circle will periodically reset
the minterAllowance
as long as a minter
remains in good standing with Circle
and maintains adequate reserves for the tokens it has issued. The
minterAllowance
is to limit the damage if any particular minter
is
compromised.
Circle adds minters via the configureMinter
method. When a minter is
configured a minterAllowance
is specified, which is the number of tokens that
address is allowed to mint. As a minter
mints tokens, the minterAllowance
will decline.
masterMinter
role may call configureMinter.The minters
will need their allowance reset periodically to allow them to
continue minting. When a minter
’s allowance is low, Circle can make another
call to configureMinter
to reset the minterAllowance
to a higher value.
Circle removes minters via the removeMinter
method. This will remove the
minter
from the list of minters
and set its minterAllowance
to 0. Once a
minter
is removed it will no longer be able to mint or burn tokens.
masterMinter
role may call removeMinter
.A minter
mints tokens via the mint
method. The minter
specifies the
amount
of tokens to create, and a _to
address which will own the newly
created tokens. A minter
may only mint an amount less than or equal to its
minterAllowance
. The minterAllowance
will decrease by the amount of tokens
minted, and the balance of the _to
address and totalSupply
will each
increase by amount
.
Only a minter
may call mint
.
paused
.minter
or _to
address is blacklisted.Mint(minter, _to, amount)
event and a
Transfer(0x00, _to, amount)
event.A minter
burns tokens via the burn
method. The minter
specifies the
amount
of tokens to burn, and the minter
must have a balance
greater than
or equal to the amount
. Burning tokens is restricted to minter
addresses to
avoid accidental burning of tokens by end users. A minter
with a
minterAllowance
of 0 is allowed to burn tokens. A minter
can only burn
tokens which it owns. When a minter burns tokens, its balance and the
totalSupply are reduced by amount
.
Burning tokens will not increase the minterAllowance of the address doing the burning.
Only a minter may call burn.
Burning fails when the minter is blacklisted.
Burn(minter, amount)
event, and a
Transfer(minter, 0x00, amount)
event.Addresses can be blacklisted. A blacklisted address will be unable to transfer tokens, mint, or burn tokens.
In FiatToken versions <2.2, A blacklisted address is unable to call approve
,
increaseAllowance
, decreaseAllowance
, or authorize future pull payments
using permit
. Nor can it be authorized to pull payments from other addresses.
This has been changed in v2.2 where a blacklisted address can perform the above
functions. But they are still blocked from transferring the assets in any way.
and therefore any operations on modifying the allowance of blacklisted addresses
are considered meaningless.
Circle blacklists an address via the blacklist
method. The specified account
will be added to the blacklist.
blacklister
role may call blacklist
.Blacklist(account)
eventCircle removes an address from the blacklist via the unblacklist
method. The
specified account
will be removed from the blacklist.
blacklister
role may call unblacklist
.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, burning, and adding minters will be prevented while the contract is paused. Other functionality, such as modifying the blacklist, removing minters, changing roles, and upgrading will remain operational as those methods may be required to fix or mitigate the issue that caused Circle to pause the contract.
Circle will pause the contract via the pause
method. This method will set the
paused flag to true.
Only the pauser
role may call pause.
Pausing emits a Pause()
event
Circle 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 pauser
role may call unpause.
Unpausing emits an Unpause()
event
The contract is compatible with
ERC-2612. Users may update their
ERC-20 allowances by signing a permit
message and passing the signed message
to a relayer who will execute the on-chain transaction, instead of submitting a
transaction themselves.
The contract is compatible with ERC-3009. Users may transfer assets to another user by signing an EIP-3009 authorization and passing the authorization to a relayer who will execute the authorization on chain, instead of submitting a transaction themselves.
The contract supports signature validation via:
The FiatTokenProxy contract uses the zeppelinos Unstructured-Storage Proxy
pattern
[https://github.com/zeppelinos/zos-lib/blob/8a16ef3ad17ec7430e3a9d2b5e3f39b8204f8c8d/contracts/upgradeability/AdminUpgradeabilityProxy.sol].
FiatTokenV2_2.sol is the implementation,
the actual token will be a Proxy contract
(FiatTokenProxy.sol) which will forward
all calls to FiatToken
via delegatecall. This pattern allows Circle to upgrade
the logic of any deployed tokens seamlessly.
upgradeTo
or upgradeToAndCall
if initialization is required for the new version.admin
role may call upgradeTo
or upgradeToAndCall
.The roles outlined above may be reassigned. The owner
role has the ability to
reassign all roles (including itself) except for the admin
role.
changeAdmin
updates the admin
role to a new address.changeAdmin
may only be called by the admin
role.updateMasterMinter
updates the masterMinter
role to a new address.updateMasterMinter
may only be called by the owner
role.updatePauser
updates the pauser
role to a new address.updatePauser
may only be called by the owner
role.updateBlacklister
updates the blacklister
role to a new address.updateBlacklister
may only be called by the owner
role.transferOwnership
updates the owner
role to a new address.transferOwnership
may only be called by the owner
role.updateRescuer
updates the rescuer
role to a new address.updateRescuer
may only be called by the owner
role.