Token
source code
// tests
Token
implements an ERC20 compatible token with the addition of auth protected mint
and burn
methods, as well as EIP-2612
(permit
) signature based
delegation.
The token is fully compliant with the ERC20 interface specification.
Semantics
- The token is designed to be minimally surprising and avoids any additional checks or reverts that are not strictly essential for implementing the core transfer semantics.
- The token
decimals
is hardcoded to18
. - The token is immutable and cannot be upgraded once deployed.
mint(address usr, uint amt) auth
- Allows a ward of the token to mint
amt
tokens tousr
. - Reverts if the caller is not a ward.
- Reverts if
totalSupply
orbalanceOf[usr]
would overflow auint256
. - If execution succeeds, emits an event
Transfer(address(0), usr, amt)
.
burn(address usr, uint amt) auth
- Allows a ward of the token to burn
amt
tokens fromusr
. - Reverts if the caller is not a ward.
- Reverts if
totalSupply
orbalanceOf[usr]
would be less than 0. - If execution succeeds, emits an event
Transfer(usr, address(0), amt)
.
approve(address usr, uint amt) returns (bool)
- Allows
usr
to spendamt
of the callers tokens. - An existing approval from the caller to
usr
will be overridden. - Emits an event
Approval(msg.sender, usr, amt)
. - Returns
true
Note that compliance with the ERC20 standard has been prioritised here and this token implementation is vulnerable to the ERC20 approval race.
transfer(address usr, uint amt) returns (bool)
- Sends
amt
tokens from the caller tousr
. - Reverts if the caller does not have sufficient balance for the transfer.
- If execution succeeds, emits and event
Transfer(msg.sender, dst, amt)
. - If execution succeeds, returns
true
(or reverts otherwise).
transferFrom(address src, address dst, uint amt) returns (bool)
- Sends
amt
tokens fromsrc
todst
. - Reverts if the caller has not been approved for at least
amt
bysrc
. - Reverts if
src
does not have sufficient balance for the transfer. - If the caller has been approved for
type(uint).max
bysrc
, then the allowance fromsrc
to the caller will not be decreased. - If the caller is also
src
then the allowance fromsrc
to caller will not be decreased. This means that a call totransferFrom(address(this), usr, amt)
is semantically equivalent totransfer(usr, amt)
. - Aside from the above two cases, the allowance from
src
tocaller
will be decreased byamt
. - If execution succeeds, emits and event
Transfer(src, dst, amt)
. - If execution succeeds, returns
true
(or reverts otherwise).
Permit
The token implements EIP-2612
, and as such allows
delegation of control over token balances via a signed message. This has two main benefits:
- It allows the construction of "gassless" relayer based workflows where users can pay for interactions involving the token without having to hold ether.
- It allows users to both approve a contract on their tokens and then have the contract pull those tokens in a single transaction.
EIP-2612
adds 3 methods to the standard ERC20
ABI:
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external
function nonces(address owner) external view returns (uint)
function DOMAIN_SEPARATOR() external view returns (bytes32)
For a full description of the semantics, refer to the EIP.