Mints itself according to some predefined schedule. The schedule is
expressed as a rainVM script and the
claim function is world-callable.
Intended behaviour is to avoid sybils infinitely minting by putting the
claim functionality behind a
ITier contract. The emissions contract
ReadOnlyTier and every time a claim is processed it
logs the block number of the claim against every tier claimed. So the block
numbers in the tier report for
EmissionsERC20 are the last time that tier
was claimed against this contract. The simplest way to make use of this
information is to take the max block for the underlying tier and the last
claim and then diff it against the current block number.
test/Claim/EmissionsERC20.sol.ts for examples, including providing
staggered rewards where more tokens are minted for higher tier accounts.
Initialize(address sender, bool allowDelegatedClaims)
Contract has initialized.
Constructs the emissions schedule source, opcodes and ERC20 to mint.
initialize(struct EmissionsERC20Config config_) (external)
applyOp(bytes context_, struct State state_, uint256 opcode_, uint256 operand_) (internal)
Every contract that implements
RainVM should override
that useful opcodes are available to script writers.
For an example of a simple and efficient
applyOp implementation that
dispatches over several opcode packs see
Implementing contracts are encouraged to handle the dispatch with
unchecked math as the dispatch is a critical performance path and
default solidity checked math can significantly increase gas cost for
each opcode dispatched. Consider that a single zipmap could loop over
dozens of opcode dispatches internally.
Stack is modified by reference NOT returned.
report(address account_) → uint256 (public)
Reports from the claim contract function differently to most tier
contracts. When the report is uninitialized it is
intent is that the claim report is compatible with an "every" selectLte
against tiers that might be gating claims. It's important that we use
every for this check as the underlying tier doing the gating MUST be
respected on every claim even for users that have previously claimed as
they could have lost tiers since their last claim.
The standard "uninitialized is 0xFF.." logic can be simulated in a rain
REPORT(this, account) IF(ISZERO(DUP(0)), never, DUP(0)) if
desired by the deployer (adjusting the DUP index to taste).
Returns the earliest block the account has held each tier for continuously. This is encoded as a uint256 with blocks represented as 8x concatenated uint32. I.e. Each 4 bytes of the uint256 represents a u32 tier start time. The low bits represent low tiers and high bits the high tiers. Implementing contracts should return 0xFFFFFFFF for lost and never-held tiers.
calculateClaim(address claimant_) → uint256 (public)
Calculates the claim without processing it.
Read only method that may be useful downstream both onchain and
offchain if a claimant wants to check the claim amount before deciding
whether to process it.
As this is read only there are no checks against delegated claims. It
is possible to return a value from
calculateClaim and to not be able
to process the claim with
msg.sender is not the
claim(address claimant_, bytes data_) (external)
Processes the claim for
allowDelegatedClaimsif it is
msg.sendermust also be
- Takes the return from
calculateClaimand mints for
- Records the current block as the claim-tier for this contract.
- emits a
Claimevent as per