This page is incomplete. We're working to improve it for the next release. Stay tuned!
This contract can be used to migrate an ERC20 token from one
contract to another, where each token holder has to opt-in to the migration.
To opt-in, users must approve for this contract the number of tokens they
want to migrate. Once the allowance is set up, anyone can trigger the
migration to the new token contract. In this way, token holders "turn in"
their old balance and will be minted an equal amount in the new token.
The new token contract must be mintable. For the precise interface refer to
OpenZeppelin's ERC20Mintable, but the only functions that are needed are
mint(address, amount). The migrator will check
that it is a minter for the token.
The balance from the legacy token will be transferred to the migrator, as it
is migrated, and remain there forever.
Although this contract can be used in many different scenarios, the main
motivation was to provide a way to migrate ERC20 tokens into an upgradeable
version of it using ZeppelinOS. To read more about how this can be done
using this implementation, please follow the official documentation site of
Example of usage:
const migrator = await ERC20Migrator.new(legacyToken.address); await newToken.addMinter(migrator.address); await migrator.beginMigration(newToken.address);
constructor(contract IERC20 legacyToken)public
legacyToken() → contract IERC20public
Returns the legacy token that is being migrated.
newToken() → contract IERC20public
Returns the new token to which we are migrating.
beginMigration(contract ERC20Mintable newToken_)public
Begins the migration by setting which is the new token that will be minted. This contract must be a minter for the new token.
migrate(address account, uint256 amount)public
Transfers part of an account's balance in the old token to this contract, and mints the same amount of new tokens for that account.
Transfers all of an account's allowed balance in the old token to this contract, and mints the same amount of new tokens for that account.
Inspired by Jordi Baylina's MiniMeToken to record historical balances: https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol When a snapshot is made, the balances and totalSupply at the time of the snapshot are recorded for later access.
To make a snapshot, call the
snapshot function, which will emit the
Snapshot event and return a snapshot id.
To get the total supply from a snapshot, call the function
totalSupplyAt with the snapshot id.
To get the balance of an account from a snapshot, call the
balanceOfAt function with the snapshot id and the
balanceOfAt(address account, uint256 snapshotId)
_transfer(address from, address to, uint256 value)
_mint(address account, uint256 value)
_burn(address account, uint256 value)
transfer(address recipient, uint256 amount)
allowance(address owner, address spender)
approve(address spender, uint256 value)
transferFrom(address sender, address recipient, uint256 amount)
increaseAllowance(address spender, uint256 addedValue)
decreaseAllowance(address spender, uint256 subtractedValue)
_approve(address owner, address spender, uint256 value)
_burnFrom(address account, uint256 amount)
snapshot() → uint256public
balanceOfAt(address account, uint256 snapshotId) → uint256public
totalSupplyAt(uint256 snapshotId) → uint256public
_transfer(address from, address to, uint256 value)internal
_mint(address account, uint256 value)internal
_burn(address account, uint256 value)internal
A token holder contract that can release its token balance gradually like a typical vesting scheme, with a cliff and vesting period. Optionally revocable by the owner.
constructor(address beneficiary, uint256 start, uint256 cliffDuration, uint256 duration, bool revocable)
release(contract IERC20 token)
revoke(contract IERC20 token)
constructor(address beneficiary, uint256 start, uint256 cliffDuration, uint256 duration, bool revocable)public
Creates a vesting contract that vests its balance of any ERC20 token to the beneficiary, gradually in a linear fashion until start + duration. By then all of the balance will have vested.
beneficiary() → addresspublic
cliff() → uint256public
start() → uint256public
duration() → uint256public
revocable() → boolpublic
released(address token) → uint256public
revoked(address token) → boolpublic
release(contract IERC20 token)public
revoke(contract IERC20 token)public
TokensReleased(address token, uint256 amount)
Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number of elements in a mapping, issuing ERC721 ids, or counting request ids.
using Counters for Counters.Counter;
Since it is not possible to overflow a 256 bit integer with increments of one,
increment can skip the SafeMath
overflow check, thereby saving gas. This does assume however correct usage, in that the underlying
_value is never
current(struct Counters.Counter counter) → uint256internal
increment(struct Counters.Counter counter)internal
decrement(struct Counters.Counter counter)internal
SignatureBouncer allows users to submit a signature as a permission to do an action. If the signature is from one of the authorized signer addresses, the signature is valid. Note that SignatureBouncer offers no protection against replay attacks, users must add this themselves!
Signer addresses can be individual servers signing grants or different
users within a decentralized club that have permission to invite other
members. This technique is useful for whitelists and airdrops; instead of
putting all valid addresses on-chain, simply sign a grant of the form
:granteeAddress)) using a
valid signer address.
Then restrict access to your crowdsale/whitelist/airdrop using the
onlyValidSignature modifier (or implement your own using _isValidSignature).
In addition to
onlyValidSignatureAndData can be used to restrict access to only a given
method or a given method with given parameters respectively.
See the tests in SignatureBouncer.test.js for specific usage examples.
_isValidSignature(address account, bytes signature)
_isValidSignatureAndMethod(address account, bytes signature)
_isValidSignatureAndData(address account, bytes signature)
_isValidDataHash(bytes32 hash, bytes signature)
_isValidSignature(address account, bytes signature) → boolinternal
is the signature of
this + account from a signer?
_isValidSignatureAndMethod(address account, bytes signature) → boolinternal
is the signature of
this + account + methodId from a signer?
_isValidSignatureAndData(address account, bytes signature) → boolinternal
is the signature of
this + account + methodId + params(s) from a signer?
_isValidDataHash(bytes32 hash, bytes signature) → boolinternal
Internal function to convert a hash to an eth signed message and then recover the signature and check it against the signer role.
Signed math operations with safety checks that revert on error.
mul(int256 a, int256 b) → int256internal
Multiplies two signed integers, reverts on overflow.
div(int256 a, int256 b) → int256internal
Integer division of two signed integers truncating the quotient, reverts on division by zero.
sub(int256 a, int256 b) → int256internal
Subtracts two signed integers, reverts on overflow.
add(int256 a, int256 b) → int256internal
Adds two signed integers, reverts on overflow.