diff --git a/docs/develop/mainnet.md b/docs/develop/mainnet.md index 5d5a72f..878b170 100644 --- a/docs/develop/mainnet.md +++ b/docs/develop/mainnet.md @@ -79,7 +79,7 @@ or their assigned withdrawal account receives a part of the transaction fees. To learn about how to [register your smart contracts](https://academy.evmos.org/articles/advanced/incentives-registration), head over to our Academy. If you are curious on how this is implemented on the protocol, -check out the [revenue module specification](./../protocol/modules/incentives). +check out the [revenue module specification](./../protocol/modules/revenue). ## Community diff --git a/docs/protocol/evmos-cli/proposal-draft.md b/docs/protocol/evmos-cli/proposal-draft.md index f388d46..0e47aa0 100644 --- a/docs/protocol/evmos-cli/proposal-draft.md +++ b/docs/protocol/evmos-cli/proposal-draft.md @@ -44,11 +44,11 @@ To create a draft proposal using the `evmosd tx gov draft-proposal` command, fol ✔ other Use the arrow keys to navigate: ↓ ↑ → ← ? Select proposal message type:: - ↑ /evmos.erc20.v1.MsgUpdateParams - ▸ /evmos.incentives.v1.MsgUpdateParams - /evmos.inflation.v1.MsgUpdateParams - /evmos.recovery.v1.MsgUpdateParams - ↓ /evmos.revenue.v1.MsgCancelRevenue + ↑ /evmos.erc20.v1.MsgConvertERC20 + /evmos.erc20.v1.MsgUpdateParams + ▸ /evmos.inflation.v1.MsgUpdateParams + /evmos.revenue.v1.MsgCancelRevenue + ↓ /evmos.revenue.v1.MsgRegisterRevenue ``` 3. Follow the on-screen instructions to complete the process. diff --git a/docs/protocol/metrics.md b/docs/protocol/metrics.md index ccd4147..75ef9c4 100644 --- a/docs/protocol/metrics.md +++ b/docs/protocol/metrics.md @@ -22,8 +22,6 @@ and display them in a [Grafana](https://grafana.com/) dashboard. | :--------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | :------- | :-------- | | `feemarket_base_fee` | Amount of base fee per EIP-1559 block | token | gauge | | `feemarket_block_gas` | Amount of gas used in an EIP-1559 block | token | gauge | -| `recovery_ibc_on_recv_total` | Total number of recoveries using the ibc `onRecvPacket` callback | recovery | counter | -| `recovery_ibc_on_recv_token_total` | Total amount of tokens recovered using the ibc `onRecvPacket` callback | token | counter | | `erc20_ibc_on_recv_total` | Total amount of times an IBC coin was autoconverted to an ERC20 token in the ibc `onRecvPacket` callback | transfer | counter | | `erc20_ibc_err_total` | Total amount of times an IBC coin autoconvertion to ERC20 token failed during an ibc transaction | transfer | counter | | `erc20_ibc_transfer_total` | Total amount of times an IBC coin or its ERC20 representation was transferred via ibc (outgoing transaction) | transfer | counter | @@ -36,7 +34,6 @@ and display them in a [Grafana](https://grafana.com/) dashboard. | `tx_msg_ethereum_tx_gas_limit_per_gas_used` | Ratio of gas limit to gas used for an ethereum tx | ratio | gauge | | `tx_msg_ethereum_tx_incentives_total` | Total number of txs with an incentivized contract processed via the EVM | tx | counter | | `tx_msg_ethereum_tx_incentives_gas_used_total` | Total amount of gas used by txs with an incentivized contract processed via the EVM | gas | counter | -| `incentives_distribute_reward_total` | Total amount of rewards that are distributed to all incentives' participants | token | counter | | `inflation_allocate_total` | Total amount of tokens allocated through inflation | token | counter | | `inflation_allocate_staking_total` | Total amount of tokens allocated through inflation to staking | token | counter | | `inflation_allocate_incentives_total` | Total amount of tokens allocated through inflation to incentives | token | counter | diff --git a/docs/protocol/module-accounts.md b/docs/protocol/module-accounts.md index 00d62ba..a585426 100644 --- a/docs/protocol/module-accounts.md +++ b/docs/protocol/module-accounts.md @@ -11,10 +11,8 @@ Below is a table of modules, their respective wallet addresses and permissions: | Name | Address | Permissions | | :---------------------- | :-------------------------------------------------- | :----------------- | -| `claims` | [evmos15cvq3ljql6utxseh0zau9m8ve2j8erz89m5wkz](https://www.mintscan.io/evmos/account/evmos15cvq3ljql6utxseh0zau9m8ve2j8erz89m5wkz) | `none` | | `erc20` | [evmos1glht96kr2rseywuvhhay894qw7ekuc4qg9z5nw](https://www.mintscan.io/evmos/account/evmos1glht96kr2rseywuvhhay894qw7ekuc4qg9z5nw) | `minter` `burner` | | `fee_collector` | [evmos17xpfvakm2amg962yls6f84z3kell8c5ljcjw34](https://www.mintscan.io/evmos/account/evmos17xpfvakm2amg962yls6f84z3kell8c5ljcjw34) | `none` | -| `incentives` | [evmos1krxwf5e308jmclyhfd9u92kp369l083wn67k4q](https://www.mintscan.io/evmos/account/evmos1krxwf5e308jmclyhfd9u92kp369l083wn67k4q) | `minter` `burner` | | `inflation` | [evmos1d4e35hk3gk4k6t5gh02dcm923z8ck86qygxf38](https://www.mintscan.io/evmos/account/evmos1d4e35hk3gk4k6t5gh02dcm923z8ck86qygxf38) | `minter` | | `transfer` | [evmos1yl6hdjhmkf37639730gffanpzndzdpmhv788dt](https://www.mintscan.io/evmos/account/evmos1yl6hdjhmkf37639730gffanpzndzdpmhv788dt) | `minter` `burner` | | `bonded_tokens_pool` | [evmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3h6cprl](https://www.mintscan.io/evmos/account/evmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3h6cprl) | `burner` `staking` | diff --git a/docs/protocol/modules/claims.md b/docs/protocol/modules/claims.md deleted file mode 100644 index 468b420..0000000 --- a/docs/protocol/modules/claims.md +++ /dev/null @@ -1,493 +0,0 @@ - -# `claims` - -## Abstract - -This document specifies the internal `x/claims` module of the Evmos Hub. - -The `x/claims` module is part of the Evmos [Rektdrop](https://evmos.blog/the-evmos-rektdrop-abbe931ba823) -and aims to increase the distribution of the network tokens to a large number of users. - -Users are assigned with an initial amount of tokens from the airdrop allocation, -and then are able to automatically claim higher percentages as they perform certain tasks on-chain. - -For the Evmos Rektdrop, users are required to claim their airdrop by participating in core network activities. -A Rektdrop recipient has to perform the following activities to get the allocated tokens: - -* 25% is claimed by staking -* 25% is claimed by voting in governance -* 25% is claimed by using the EVM (deploy or interact with contract, transfer EVMOS through a web3 wallet) -* 25% is claimed by sending or receiving an IBC transfer - -Furthermore, these claimable assets 'expire' if not claimed. -Users have two months (`DurationUntilDecay`) to claim their full airdrop amount. -After two months, the reward amount available will decline over 1 month (`DurationOfDecay`) in real time, -until it hits `0%` at 3 months from launch (`DurationUntilDecay + DurationOfDecay`). - -# Contents - -1. **[Concepts](#concepts)** -2. **[State](#state)** -3. **[State Transitions](#state-transitions)** -4. **[Hooks](#hooks)** -5. **[Events](#events)** -6. **[Parameters](#parameters)** -7. **[Clients](#clients)** - -## Concepts - -### Rektdrop - -The Evmos [Rektdrop](https://evmos.blog/the-evmos-rektdrop-abbe931ba823) is the genesis airdrop -for the EVMOS token to Cosmos Hub, Osmosis and Ethereum users. - -> The end goal of Evmos is to bring together the Cosmos and Ethereum community -and thus the Rektdrop has been designed to reward past participation in both networks under this theme of “getting rekt”. - -The Rektdrop is the first airdrop that: - -- Implements the [gasdrop](https://www.sunnya97.com/blog/gasdrop) mechanism by Sunny Aggarwal -- Covers the most number of chains and applications involved in an airdrop -- Airdrops to bridge users -- Includes reparations for users in exploits and negative market externalities (i.e. MEV) - -The snapshot of the airdrop was on **November 25th, 2021 at 19:00 UTC** - -### Actions - -An `Action` corresponds to a given transaction that the user must perform to receive the allocated tokens from the airdrop. - -There are 4 types of actions, each of which release 25% of their remaining corresponding airdrop allocation. -The 4 actions are as follows (`ActionUnspecified` is not considered for claiming): - -```go -// UNSPECIFIED defines an invalid action. NOT claimable -ActionUnspecified Action = 0 -// VOTE defines a proposal vote. -ActionVote Action = 1 -// DELEGATE defines an staking delegation. -ActionDelegate Action = 2 -// EVM defines an EVM transaction. -ActionEVM Action = 3 -// IBC Transfer defines a fungible token transfer transaction via IBC. -ActionIBCTransfer Action = 4 -``` - -These actions are monitored by registering claim post transaction **hooks** to the governance, staking, and EVM modules. -Once the user performs an action, the `x/claims` module will unlock the corresponding portion of the assets -and transfer them to the balance of the user. - -These actions can be performed in any order and the claims module will not grant any additional tokens -after the corresponding action is performed. - -#### Vote Action - -After voting on a proposal, the corresponding proportion will be airdropped -to the user's balance by performing a transfer from the claim escrow account (`ModuleAccount`) to the user. - -#### Staking (i.e Delegate) Action - -After staking Evmos tokens (i.e delegating), the corresponding proportion will be airdropped to the user's balance -by performing a transfer from the claim escrow account (`ModuleAccount`) to the user. - -#### EVM Action - -If the user deploys or interacts with a smart contract (via an application or wallet integration), -the corresponding proportion will be airdropped to the user's balance by performing a transfer -from the claim escrow account (`ModuleAccount`) to the user. -This also applies when the user performs a transfer using Metamask or another web3 wallet of their preference. - -#### IBC Transfer Action - -If a user submits an IBC transfer to a recipient on a counterparty chain -or receives an IBC transfer from a counterparty chain, -the corresponding proportion will be airdropped to the user's balance submitting or receiving the transfer. - -### Claim Records - -A Claims Records is the metadata of claim data per address. -It keeps track of all the actions performed by the the user as well as the total amount of tokens allocated to them. -All users that have an address with a corresponding `ClaimRecord` are eligible to claim the airdrop. - -### Claiming Process - -As described in the [Actions](#actions) section, a user must submit transactions -to receive the allocated tokens from the airdrop. -However, since Evmos only supports Ethereum keys and not default Tendermint keys, -this process differs for Ethereum and Cosmos eligible users. - -#### Ethereum Users - -Evmos shares the coin type (`60`) and key derivation (Ethereum `secp256k1`) with Ethereum. -This allows users (EOA accounts) that have been allocated EVMOS tokens -to directly claim their tokens using their preferred web3 wallet. - -#### Cosmos Hub and Osmosis Users - -Cosmos Hub and Osmosis users who use the default Tendermint `secp256k1` keys, -need to perform a "cross-chain attestation" of their Evmos address. - -This can be done by submitting an IBC transfer from Cosmos Hub and Osmosis, -which is signed by the addresses, that have been allocated the tokens. - -The recipient Evmos address of this IBC transfer is the address, that the tokens will be airdropped to. - -:::warning -**IMPORTANT** - -Only submit an IBC transfer to an Evmos address that you own. Otherwise, you will lose your airdrop allocation. -::: - -### Decay Period - -A decay period defines the duration of the period during which the amount of claimable tokens -by the user decays decrease linearly over time. -It's goal is to incentivize users to claim their tokens and interact with the blockchain early. - -The start is of this period is defined -as the sum of the `AirdropStartTime` and `DurationUntilDecay` parameter -and the duration of the linear decay is defined as `DurationOfDecay`, as described below: - -```go -decayStartTime = AirdropStartTime + DurationUntilDecay -decayEndTime = decayStartTime + DurationOfDecay -``` - -By default, users have two months (`DurationUntilDecay`) to claim their full airdrop amount. -After two months, the reward amount available will decline over 1 month (`DurationOfDecay`) in real time, -until it hits `0%` at 3 months from launch (end). - -### Airdrop Clawback - -After the claim period ends, the tokens that were not claimed by users will be transferred to the community pool treasury. -In the same way, users with tokens allocated but no transactions (i.e nonce = 0), -will have their balance clawbacked to the community pool. - -## State - -### State Objects - -The `x/claims` module keeps the following objects in state: - -| State Object | Description | Key | Value | Store | -|----------------|------------------------|-------------------------------|------------------------|-------| -| `ClaimsRecord` | Claims record bytecode | `[]byte{1} + []byte(address)` | `[]byte{claimsRecord}` | KV | - -#### Claim Record - -A `ClaimRecord` defines the initial claimable airdrop amount and the list of completed actions to claim the tokens. - -```protobuf -message ClaimsRecord { - // total initial claimable amount for the user - string initial_claimable_amount = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; - // slice of the available actions completed - repeated bool actions_completed = 2; -} -``` - -### Genesis State - -The `x/claims` module's `GenesisState` defines the state necessary -for initializing the chain from a previously exported height. -It contains the module parameters and a slice containing all the claim records by user address: - -```go -// GenesisState defines the claims module's genesis state. -type GenesisState struct { - // params defines all the parameters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - // list of claim records with the corresponding airdrop recipient - ClaimsRecords []ClaimsRecordAddress `protobuf:"bytes,2,rep,name=claims_records,json=claimsRecords,proto3" json:"claims_records"` -} -``` - -### Invariants - -The `x/claims` module registers an [`Invariant`](https://docs.cosmos.network/main/building-modules/invariants) -to ensure that a property is true at any given time. -These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. -by halting the chain). - -#### ClaimsInvariant - -The `ClaimsInvariant` checks that the total amount of all unclaimed coins held -in claims records is equal to the escrowed balance held in the claims module -account. This is important to ensure that there are sufficient coins to claim for all claims records. - -```go -balance := k.bankKeeper.GetBalance(ctx, moduleAccAddr, params.ClaimsDenom) -isInvariantBroken := !expectedUnclaimed.Equal(balance.Amount.ToDec()) -``` - -## State Transitions - -### ABCI - -#### End Block - -The ABCI EndBlock checks if the airdrop has ended in order to process the clawback of unclaimed tokens. - -1. Check if the airdrop has concluded. This is the case if: - - the global flag is enabled - - the current block time is greater than the airdrop end time -2. Clawback tokens from the escrow account that holds the unclaimed tokens - by transferring its balance to the community pool -3. Clawback tokens from empty user accounts - by transferring the balance from empty user accounts with claims records to the community pool if: - - the account is an ETH account - - the account is not a vesting account - - the account has a sequence number of 0, i.e. no transactions submitted, and - - the balance amount is the same as the dust amount sent in genesis - - the account does not have any other balances on other denominations except for the claims denominations. -4. Prune all the claim records from the state -5. Disable any further claim by setting the global parameter to `false` - -## Hooks - -The `x/claims` module implements transaction hooks for each of the four actions -from the `x/staking`, `x/gov` and `x/evm` modules. -It also implements an IBC Middleware in order to claim the IBC transfer action -and to claim the tokens for Cosmos Hub and Osmosis users by migrating the claims record to the recipient address. - -### Governance Hook - Vote Action - -The user votes on a Governance proposal using their Evmos account. -Once the vote is successfully included, the claimable amount corresponding -to the vote action is transferred to the user address: - -1. The user submits a `MsgVote`. -2. Begin claiming process for the `ActionVote`. -3. Check if the claims is allowed: - - global parameter is enabled - - current block time is before the end of the claims period - - user has a claims record (i.e allocation) for the airdrop - - user hasn't already claimed the action - - claimable amount is greater than zero -4. Transfer the claimable amount from the escrow account to the user balance -5. Mark the `ActionVote` as completed on the claims record. -6. Update the claims record and retain it, even if all the actions have been claimed. - -### Staking Hook - Delegate Action - -The user delegates their EVMOS tokens to a validator. -Once the tokens are staked, the claimable amount corresponding to the delegate action is transferred to the user address: - -1. The user submits a `MsgDelegate`. -2. Begin claiming process for the `ActionDelegate`. -3. Check if the claims is allowed: - - global parameter is enabled - - current block time is before the end of the claims period - - user has a claims record (i.e allocation) for the airdrop - - user hasn't already claimed the action - - claimable amount is greater than zero -4. Transfer the claimable amount from the escrow account to the user balance -5. Mark the `ActionDelegate` as completed on the claims record. -6. Update the claims record and retain it, even if all the actions have been claimed. - -### EVM Hook - EVM Action - -The user deploys or interacts with a smart contract using their Evmos account or send a transfer using their Web3 wallet. -Once the EVM state transition is successfully processed, -the claimable amount corresponding to the EVM action is transferred to the user address: - -1. The user submits a `MsgEthereumTx`. -2. Begin claiming process for the `ActionEVM`. -3. Check if the claims is allowed: - - global parameter is enabled - - current block time is before the end of the claims period - - user has a claims record (i.e allocation) for the airdrop - - user hasn't already claimed the action - - claimable amount is greater than zero -4. Transfer the claimable amount from the escrow account to the user balance -5. Mark the `ActionEVM` as completed on the claims record. -6. Update the claims record and retain it, even if all the actions have been claimed. - -### IBC Middleware - IBC Transfer Action - -#### Send - -The user submits an IBC transfer to a recipient in the destination chain. -Once the transfer acknowledgement package is received, -the claimable amount corresponding to the IBC transfer action is transferred to the user address: - -1. The user submits a `MsgTransfer` to a recipient address in the destination chain. -2. The transfer packet is processed by the IBC ICS20 Transfer app module and relayed. -3. Once the packet acknowledgement is received, the IBC transfer module `OnAcknowledgementPacket` callback is executed. - After which the claiming process for the `ActionIBCTransfer` begins. -4. Check if the claims is allowed: - - global parameter is enabled - - current block time is before the end of the claims period - - user has a claims record (i.e allocation) for the airdrop - - user hasn't already claimed the action - - claimable amount is grater than zero -5. Transfer the claimable amount from the escrow account to the user balance -6. Mark the `ActionIBC` as completed on the claims record. -7. Update the claims record and retain it, even if all the actions have been claimed. - -#### Receive - -The user receives an IBC transfer from a counterparty chain. -If the transfer is successful, -the claimable amount corresponding to the IBC transfer action is transferred to the user address. -Additionally, if the sender address is Cosmos Hub or Osmosis address with an airdrop allocation, -the `ClaimsRecord` is merged with the recipient's claims record. - -1. The user receives an packet containing an IBC transfer data. -2. The transfer is processed by the IBC ICS20 Transfer app module -3. Check if the claims is allowed: - - global parameter is enabled - - current block time is before the end of the claims period -4. Check if package is from a sent NON EVM channel and sender and recipient - address are the same. If a packet is sent from a non-EVM chain, the sender - addresss is not an ethereum key (i.e. `ethsecp256k1`). Thus, if - `sameAddress` is true, the recipient address must be a non-ethereum key as - well, which is not supported on Evmos. To prevent funds getting stuck, - return an error, unless the destination channel from a connection to a chain - is EVM-compatible or supports ethereum keys (eg: Cronos, Injective). -6. Check if destination channel is authorized to perform the IBC claim. - Without this authorization the claiming process is vulerable to attacks. -7. Handle one of four cases by comparing sender and recipient addresses with each other - and checking if either addresses have a claims record (i.e allocation) for the airdrop. - To compare both addresses, the sender address's bech32 human readable prefix (HRP) is replaced with `evmos`. - - 1. both sender and recipient are distinct and have a claims record -> - merge sender's record with the recipient's record and claim actions that have been completed by one or the other - 2. only the sender has a claims record -> migrate the sender record to the recipient address and claim IBC action - 3. only the recipient has a claims record -> - only claim IBC transfer action and transfer the claimable amount from the escrow account to the user balance - 4. neither the sender or recipient have a claims record -> - perform a no-op by returning the original success acknowledgement - -## Events - -The `x/claims` module emits the following events: - -### Claim - -| Type | Attribute Key | Attribute Value | -| ------- | ------------- | ----------------------------------------------------------------------- | -| `claim` | `"sender"` | `{address}` | -| `claim` | `"amount"` | `{amount}` | -| `claim` | `"action"` | `{"ACTION_VOTE"/ "ACTION_DELEGATE"/"ACTION_EVM"/"ACTION_IBC_TRANSFER"}` | - -### Merge Claims Records - -| Type | Attribute Key | Attribute Value | -| ---------------------- | ----------------------------- | --------------------------- | -| `merge_claims_records` | `"recipient"` | `{recipient.String()}` | -| `merge_claims_records` | `"claimed_coins"` | `{claimed_coins.String()}` | -| `merge_claims_records` | `"fund_community_pool_coins"` | `{remainderCoins.String()}` | - -## Parameters - -The `x/claims` module contains the parameters described below. All parameters can be modified via governance. - -:::danger -🚨 **IMPORTANT**: `time.Duration` store value is in nanoseconds but the JSON / `String` value is in seconds! -::: - -| Key | Type | Default Value | -| -------------------- | --------------- | ----------------------------------------------------------- | -| `EnableClaim` | `bool` | `true` | -| `ClaimsDenom` | `string` | `"aevmos"` | -| `AirdropStartTime` | `time.Time` | `time.Time{}` // empty | -| `DurationUntilDecay` | `time.Duration` | `2629800000000000` (nanoseconds) // 1 month | -| `DurationOfDecay` | `time.Duration` | `5259600000000000` (nanoseconds) // 2 months | -| `AuthorizedChannels` | `[]string` | `[]string{"channel-0", "channel-3"}` // Osmosis, Cosmos Hub | -| `EVMChannels` | `[]string` | `[]string{"channel-2"}` // Injective | - -### Enable claim - -The `EnableClaim` parameter toggles all state transitions in the module. -When the parameter is disabled, it will disable all the allocation of airdropped tokens to users. - -### Claims Denom - -The `ClaimsDenom` parameter defines the coin denomination that users will receive as part of their airdrop allocation. - -### Airdrop Start Time - -The `AirdropStartTime` refers to the time when user can start to claim the airdrop tokens. - -### Duration Until Decay - -The `DurationUntilDecay` parameter defines the duration from airdrop start time to decay start time. - -### Duration Of Decay - -The `DurationOfDecay` parameter refers to the duration from decay start time to claim end time. -Users are not able to claim airdrop after this duration has ended. - -### Authorized Channels - -The `AuthorizedChannels` parameter describes the set of channels -that users can perform the ibc callback with to claim coins for the ibc action. - -### EVM Channels - -The `EVMChannels` parameter describes the list of Evmos channels -that connected to EVM compatible chains and can be used during the ibc callback action. - -## Clients - -A user can query the `x/claims` module using the CLI, gRPC or REST. - -### CLI - -Find below a list of `evmosd` commands added with the `x/claims` module. -You can obtain the full list by using the `evmosd -h` command. - -#### Queries - -The `query` commands allow users to query `claims` state. - -**`total-unclaimed`** - -Allows users to query total amount of unclaimed tokens from the airdrop. - -```bash -evmosd query claims total-unclaimed [flags] -``` - -**`records`** - -Allows users to query all the claims records available. - -```bash -evmosd query claims records [flags] -``` - -**`record`** - -Allows users to query a claims record for a given user. - -```bash -evmosd query claims record ADDRESS [flags] -``` - -**`params`** - -Allows users to query claims params. - -```bash -evmosd query claims params [flags] -``` - -### gRPC - -#### Queries - -| Verb | Method | Description | -|--------|--------------------------------------------|--------------------------------------------------| -| `gRPC` | `evmos.claims.v1.Query/TotalUnclaimed` | Gets the total unclaimed tokens from the airdrop | -| `gRPC` | `evmos.claims.v1.Query/ClaimsRecords` | Gets all registered claims records | -| `gRPC` | `evmos.claims.v1.Query/ClaimsRecord` | Get the claims record for a given user | -| `gRPC` | `evmos.claims.v1.Query/Params` | Gets claims params | -| `GET` | `/evmos/claims/v1/total_unclaimed` | Gets the total unclaimed tokens from the airdrop | -| `GET` | `/evmos/claims/v1/claims_records` | Gets all registered claims records | -| `GET` | `/evmos/claims/v1/claims_records/{address}` | Gets a claims record for a given user | -| `GET` | `/evmos/claims/v1/params` | Gets claims params | diff --git a/docs/protocol/modules/incentives.md b/docs/protocol/modules/incentives.md deleted file mode 100644 index e49333f..0000000 --- a/docs/protocol/modules/incentives.md +++ /dev/null @@ -1,468 +0,0 @@ -# `incentives` - -## Abstract - -This document specifies the internal `x/incentives` module of the Evmos Hub. - -The `x/incentives` module is part of the Evmos tokenomics and aims -to increase the growth of the network by distributing rewards -to users who interact with incentivized smart contracts. -The rewards drive users to interact with applications on Evmos and reinvest their rewards in more services in the network. - -The usage incentives are taken from block reward emission (inflation) -and are pooled up in the Incentives module account (escrow address). -The incentives functionality is fully governed by native EVMOS token holders -who manage the registration of `Incentives`, -so that native EVMOS token holders decide which application should be part of the usage incentives. -This governance functionality is implemented using the Cosmos-SDK `gov` module -with custom proposal types for registering the incentives. - -Users participate in incentives by submitting transactions to an incentivized contract. -The module keeps a record of how much gas the participants spent on their transactions and stores these in gas meters. -Based on their gas meters, participants in the incentive are rewarded in regular intervals (epochs). - -## Contents - -1. **[Concepts](#concepts)** -2. **[State](#state)** -3. **[State Transitions](#state-transitions)** -4. **[Transactions](#transactions)** -5. **[Hooks](#hooks)** -6. **[Events](#events)** -7. **[Parameters](#parameters)** -8. **[Clients](#clients)** - -## Concepts - -### Incentive - -The purpose of the `x/incentives` module is to provide incentives to users who interact with smart contracts. -An incentive allows users to earn rewards up to `rewards = k * sum(tx fees)`, -where `k` defines a reward scaler parameter that caps the incentives allocated to a single user -by multiplying it with the sum of transaction fees -that they’ve spent in the current epoch. - -An `incentive` describes the conditions under which rewards are allocated and distributed for a given smart contract. -At the end of every epoch, rewards are allocated from an Inflation pool -and distributed to participants of the incentive, depending on how much gas every participant spent and the scaling parameter. - -The incentive for a given smart contract can be enabled or disabled via governance. - -### Inflation Pool - -The inflation pool holds `rewards` that can be allocated to incentives. -On every block, inflation rewards are minted and added to the inflation pool. -Additionally, rewards may also be transferred to the inflation pool on top of inflation. -The details of how rewards are added to the inflation pool are described in the `x/inflation` module. - -### Epoch - -Rewarding users for smart contract interaction is organized in epochs. -An `epoch` is a fixed duration in which rewards are added to the inflation pool and smart contract interaction is logged. -At the end of an epoch, rewards are allocated and distributed to all participants. -This creates a user experience, where users check their balance for new rewards regularly (e.g. -every day at the same time). - -### Allocation - -Before rewards are distributed to users, each incentive allocates rewards from the inflation pool. -The `allocation` describes the portion of rewards in the inflation pool, -that is allocated to an incentive for a specified coin. - -Users can be rewarded in several coin denominations. -These are organized in `allocations`. -An allocation includes the coin denomination and the percentage of rewards that are allocated from the inflation pool. - -- There is a cap on how high the reward percentage can be per allocation. - It is defined via the chain parameters and can be modified via governance -- The amount of incentives is limited by the sum of all active incentivized contracts' allocations. - If the sum is > 100%, no further incentive can be proposed until another allocation becomes inactive. - -### Distribution - -The allocated rewards for an incentive are distributed -according to how much gas participants spend on interaction with the contract during an epoch. -The gas used per address is recorded using transaction hooks and stored on the KV store. -At the end of an epoch, the allocated rewards in the incentive are distributed -by transferring them to the participants accounts. - -:::tip -💡 We use hooks instead of the transaction hash to measure the gas spent -because the hook has access to the actual gas spent and the hash only includes the gas limit. -::: - -## State - -### State Objects - -The `x/incentives` module keeps the following objects in state: - -| State Object | Description | Key | Value | Store | -| --------------- | --------------------------------------------- | ------------------------------------------------------ | ------------------- | ----- | -| Incentive | Incentive bytecode | `[]byte{1} + []byte(contract)` | `[]byte{incentive}` | KV | -| GasMeter | Incentive id bytecode by erc20 contract bytes | `[]byte{2} + []byte(contract) + []byte(participant)` | `[]byte{gasMeter}` | KV | -| AllocationMeter | Total allocation bytes by denom bytes | `[]byte{3} + []byte(denom)` | `[]byte{sdk.Dec}` | KV | - -#### Incentive - -An instance that organizes distribution conditions for a given smart contract. - -```go -type Incentive struct { - // contract address - Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` - // denoms and percentage of rewards to be allocated - Allocations github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,2,rep,name=allocations,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"allocations"` - // number of remaining epochs - Epochs uint32 `protobuf:"varint,3,opt,name=epochs,proto3" json:"epochs,omitempty"` - // distribution start time - StartTime time.Time `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"` - // cumulative gas spent by all gasmeters of the incentive during the epoch - TotalGas uint64 `protobuf:"varint,5,opt,name=total_gas,json=totalGas,proto3" json:"total_gas,omitempty"` -} -``` - -As long as an incentive has remaining epochs, it distributes rewards according to its allocations. -The allocations are stored as `sdk.DecCoins` where each containing -[`sdk.DecCoin`](https://github.com/cosmos/cosmos-sdk/blob/master/types/dec_coin.go) describes the percentage of rewards -(`Amount`) that are allocated to the contract for a given coin denomination (`Denom`). -An incentive can contain several allocations, resulting in users to receive rewards in form of several different denominations. - -#### GasMeter - -Tracks the cumulative gas spent in a contract per participant during one epoch. - -```go -type GasMeter struct { - // hex address of the incentivized contract - Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` - // participant address that interacts with the incentive - Participant string `protobuf:"bytes,2,opt,name=participant,proto3" json:"participant,omitempty"` - // cumulative gas spent during the epoch - CumulativeGas uint64 `protobuf:"varint,3,opt,name=cumulative_gas,json=cumulativeGas,proto3" json:"cumulative_gas,omitempty"` -} -``` - -#### AllocationMeter - -An allocation meter stores the sum of all registered incentives’ allocations for a given denomination -and is used to limit the amount of registered incentives. - -Say, there are several incentives that have registered an allocation for the EVMOS coin -and the allocation meter for EVMOS is at 97%. -Then a new incentve proposal can only include an EVMOS allocation at up to 3%, -claiming the last remaining allocation capacity from the EVMOS rewards in the inflation pool. - -### Genesis State - -The `x/incentives` module's `GenesisState` defines the state -necessary for initializing the chain from a previously exported height. -It contains the module parameters and the list of active incentives and their corresponding gas meters: - -```go -// GenesisState defines the module's genesis state. -type GenesisState struct { - // module parameters - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - // active incentives - Incentives []Incentive `protobuf:"bytes,2,rep,name=incentives,proto3" json:"incentives"` - // active Gasmeters - GasMeters []GasMeter `protobuf:"bytes,3,rep,name=gas_meters,json=gasMeters,proto3" json:"gas_meters"` -} -``` - -## State Transitions - -The `x/incentive` module allows for two types of registration state transitions: -`RegisterIncentiveProposal` and `CancelIncentiveProposal`. -The logic for *gas metering* and *distributing rewards* is handled through [Hooks](#hooks). - -### Incentive Registration - -A user registers an incentive defining the contract, allocations, and number of epochs. -Once the proposal passes (i.e is approved by governance), -the incentive module creates the incentive and distributes rewards. - -1. User submits a `RegisterIncentiveProposal`. -2. Validators of the Evmos Hub vote on the proposal using `MsgVote` and proposal passes. -3. Create incentive for the contract with a `TotalGas = 0` and set its `startTime` to `ctx.Blocktime` - if the following conditions are met: - 1. Incentives param is globally enabled - 2. Incentive is not yet registered - 3. Balance in the inflation pool is > 0 for each allocation denom except for the mint denomination. - We know that the amount of the minting denom (e.g. EVMOS) will be added to every block - but for other denominations (IBC vouchers, ERC20 tokens using the `x/erc20` module) - the module account needs to have a positive amount to distribute the incentives - 4. The sum of all registered allocations for each denom (current + proposed) is < 100% - -## Transactions - -This section defines the `sdk.Msg` concrete types that result in the state transitions defined on the previous section. - -## `RegisterIncentiveProposal` - -A gov `Content` type to register an Incentive for a given contract for the duration of a certain number of epochs. -Governance users vote on this proposal -and it automatically executes the custom handler for `RegisterIncentiveProposal` when the vote passes. - -```go -type RegisterIncentiveProposal struct { - // title of the proposal - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` - // proposal description - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // contract address - Contract string `protobuf:"bytes,3,opt,name=contract,proto3" json:"contract,omitempty"` - // denoms and percentage of rewards to be allocated - Allocations github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,4,rep,name=allocations,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"allocations"` - // number of remaining epochs - Epochs uint32 `protobuf:"varint,5,opt,name=epochs,proto3" json:"epochs,omitempty"` -} -``` - -The proposal content stateless validation fails if: - -- Title is invalid (length or char) -- Description is invalid (length or char) -- Contract address is invalid -- Allocations are invalid - - no allocation included in Allocations - - invalid amount of at least one allocation (below 0 or above 1) -- Epochs are invalid (zero) - -## `CancelIncentiveProposal` - -A gov `Content` type to remove an Incentive. -Governance users vote on this proposal -and it automatically executes the custom handler for `CancelIncentiveProposal` when the vote passes. - -```go -type CancelIncentiveProposal struct { - // title of the proposal - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` - // proposal description - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // contract address - Contract string `protobuf:"bytes,3,opt,name=contract,proto3" json:"contract,omitempty"` -} -``` - -The proposal content stateless validation fails if: - -- Title is invalid (length or char) -- Description is invalid (length or char) -- Contract address is invalid - -## Hooks - -The `x/incentives` module implements two transaction hooks from the `x/evm` and `x/epoch` modules. - -### EVM Hook - Gas Metering - -The EVM hook updates the logs that keep track of much gas was used -for interacting with an incentivized contract during one epoch. -An [EVM hook](evm.md#hooks) executes custom logic -after each successful evm transaction. -In this case it updates the incentive’s total gas count and the participant's own gas count. - -1. User submits an EVM transaction to an incentivized smart contract and the transaction is finished successfully. -2. The EVM hook’s `PostTxProcessing` method is called on the incentives module. - It is passed a transaction receipt - that includes the cumulative gas used by the transaction sender to pay for the gas fees. - The hook - 1. adds `gasUsed` to an incentive's cumulated `totalGas` and - 2. adds `gasUsed` to a participant's gas meter's cumulative gas used. - -### Epoch Hook - Distribution of Rewards - -The Epoch hook triggers the distribution of usage rewards for all registered incentives at the end of each epoch -(one day or one week). -This distribution process first 1) allocates the rewards for each incentive from the allocation pool -and then 2) distributes these rewards to all participants of each incentive. - -1. A `RegisterIncentiveProposal` passes and an `incentive` for the proposed contract is created. -2. An `epoch` begins and `rewards` (EVMOS and other denoms) that are minted on every block for inflation - are added to the inflation pool every block. -3. Users submit transactions and call functions on the incentivized smart contracts to interact - and gas gets logged through the EVM Hook. -4. A block, which signalizes the end of an `epoch`, is proposed - and the `DistributeIncentives` method is called through `AfterEpochEnd` hook. - This method: - 1. Allocates the amount to be distributed from the inflation pool - 2. Distributes the rewards to all participants. - The rewards of each participant are limited by the amount of gas they spent on transaction fees - during the current epoch and the reward scaler parameter. - 3. Deletes all gas meters for the contract - 4. Updates the remaining epochs of each incentive. - If an incentive’s remaining epochs equals to zero, - the incentive is removed and the allocation meters are updated. - 5. Sets the cumulative totalGas to zero for the next epoch -5. Rewards for a given denomination accumulate in the inflation pool - if the denomination’s allocation capacity is not fully exhausted - and the sum of all active incentivized contracts' allocation is < 100%. - The accumulated rewards are added to the allocation in the following epoch. - -## Events - -The `x/incentives` module emits the following events: - -### Register Incentive Proposal - -| Type | Attribute Key | Attribute Value | -| -------------------- | ------------ | --------------------------------------------- | -| `register_incentive` | `"contract"` | `{erc20_address}` | -| `register_incentive` | `"epochs"` | `{strconv.FormatUint(uint64(in.Epochs), 10)}` | - -### Cancel Incentive Proposal - -| Type | Attribute Key | Attribute Value | -| ------------------ | ------------ | ----------------- | -| `cancel_incentive` | `"contract"` | `{erc20_address}` | - -### Incentive Distribution - -| Type | Attribute Key | Attribute Value | -| ----------------------- | ------------ | --------------------------------------------- | -| `distribute_incentives` | `"contract"` | `{erc20_address}` | -| `distribute_incentives` | `"epochs"` | `{strconv.FormatUint(uint64(in.Epochs), 10)}` | - -## Parameters - -The `x/incentives` module contains the parameters described below. All parameters can be modified via governance. - -| Key | Type | Default Value | -| --------------------------- | ------- | ---------------------------------- | -| `EnableIncentives` | bool | `true` | -| `AllocationLimit` | sdk.Dec | `sdk.NewDecWithPrec(5,2)` // 5% | -| `IncentivesEpochIdentifier` | string | `week` | -| `rewardScaler` | sdk.Dec | `sdk.NewDecWithPrec(12,1)` // 120% | - -### Enable Incentives - -The `EnableIncentives` parameter toggles all state transitions in the module. -When the parameter is disabled, it will prevent all Incentive registration and cancellation and distribution functionality. - -### Allocation Limit - -The `AllocationLimit` parameter defines the maximum allocation that each incentive can define per denomination. -For example, with an `AllocationLimit` of 5%, -there can be at most 20 active incentives per denom if they all max out the limit. - -There is a cap on how high the reward percentage can be per allocation. - -### Incentives Epoch Identifier - -The `IncentivesEpochIdentifier` parameter specifies the length of an epoch. -It is the interval at which incentive rewards are regularly distributed. - -### Reward Scaler - -The `rewardScaler` parameter defines each participant’s reward limit, relative to their gas used. -An incentive allows users to earn rewards up to `rewards = k * sum(txFees)`, -where `k` defines the reward scaler parameter that caps the incentives allocated to a single user -by multiplying it to the sum of transaction fees that they’ve spent in the current epoch. - -## Clients - -A user can query the `x/incentives` module using the CLI, JSON-RPC, gRPC or REST. - -### CLI - -Find below a list of `evmosd` commands added with the `x/incentives` module. -You can obtain the full list by using the `evmosd -h` command. - -#### Queries - -The `query` commands allow users to query `incentives` state. - -**`incentives`** - -Allows users to query all registered incentives. - -```go -evmosd query incentives incentives [flags] -``` - -**`incentive`** - -Allows users to query an incentive for a given contract. - -```go -evmosd query incentives incentive CONTRACT_ADDRESS [flags] -``` - -**`gas-meters`** - -Allows users to query all gas meters for a given incentive. - -```bash -evmosd query incentives gas-meters CONTRACT_ADDRESS [flags] -``` - -**`gas-meter`** - -Allows users to query a gas meter for a given incentive and user. - -```go -evmosd query incentives gas-meter CONTRACT_ADDRESS PARTICIPANT_ADDRESS [flags] -``` - -**`params`** - -Allows users to query incentives params. - -```bash -evmosd query incentives params [flags] -``` - -#### Proposals - -The `tx gov submit-legacy-proposal` commands allow users to query create a proposal using the governance module CLI: - -**`register-incentive`** - -Allows users to submit a `RegisterIncentiveProposal`. - -```bash -evmosd tx gov submit-legacy-proposal register-incentive CONTRACT_ADDRESS ALLOCATION EPOCHS [flags] -``` - -**`cancel-incentive`** - -Allows users to submit a `CanelIncentiveProposal`. - -```bash -evmosd tx gov submit-legacy-proposal cancel-incentive CONTRACT_ADDRESS [flags] -``` - -**Update Params** - -Allows users to submit a `MsgUpdateParams` with the desired changes on the `x/incentives` module parameters. -To do this, you will have to provide a JSON file with the correspondiong message in the `submit-proposal` command. - -For more information on how to draft a proposal, refer to the [Drafting a proposal section](../evmos-cli/proposal-draft.md). - -```bash -evmosd tx gov submit-proposal proposal.json [flags] -``` - -### gRPC - -#### Queries - -| Verb | Method | Description | -| ------ | ---------------------------------------------------------- | --------------------------------------------- | -| `gRPC` | `evmos.incentives.v1.Query/Incentives` | Gets all registered incentives | -| `gRPC` | `evmos.incentives.v1.Query/Incentive` | Gets incentive for a given contract | -| `gRPC` | `evmos.incentives.v1.Query/GasMeters` | Gets gas meters for a given incentive | -| `gRPC` | `evmos.incentives.v1.Query/GasMeter` | Gets gas meter for a given incentive and user | -| `gRPC` | `evmos.incentives.v1.Query/AllocationMeters` | Gets all allocation meters | -| `gRPC` | `evmos.incentives.v1.Query/AllocationMeter` | Gets allocation meter for a denom | -| `gRPC` | `evmos.incentives.v1.Query/Params` | Gets incentives params | -| `GET` | `/evmos/incentives/v1/incentives` | Gets all registered incentives | -| `GET` | `/evmos/incentives/v1/incentives/{contract}` | Gets incentive for a given contract | -| `GET` | `/evmos/incentives/v1/gas_meters` | Gets gas meters for a given incentive | -| `GET` | `/evmos/incentives/v1/gas_meters/{contract}/{participant}` | Gets gas meter for a given incentive and user | -| `GET` | `/evmos/incentives/v1/allocation_meters` | Gets all allocation meters | -| `GET` | `/evmos/incentives/v1/allocation_meters/{denom}` | Gets allocation meter for a denom | -| `GET` | `/evmos/incentives/v1/params` | Gets incentives params | diff --git a/docs/protocol/modules/index.md b/docs/protocol/modules/index.md index 08d2af6..adfb85f 100644 --- a/docs/protocol/modules/index.md +++ b/docs/protocol/modules/index.md @@ -6,17 +6,13 @@ sidebar_position: 3 Here is a list of all production-grade modules that can be used on the Evmos blockchain, along with their respective documentation: -- [claims](claims.md) - Rewards status and claiming process for the mainnet release. - [epochs](epochs.md) - Executes custom state transitions every period (*aka* epoch). - [erc20](erc20.md) - Trustless, on-chain bidirectional internal conversion of tokens between Evmos' EVM and Cosmos runtimes. - [evm](evm.md) - Smart Contract deployment and execution on Cosmos - [feemarket](feemarket.md) - Fee market implementation based on the EIP1559 specification. +- [inflation](inflation.md) - Mint tokens and allocate them to staking rewards and the community pool. - [revenue](revenue.md) - Split EVM transaction fees between block proposer and smart contract developers. -- [incentives](incentives.md) - Incentivize user interaction with governance-approved smart contracts. -- [inflation](inflation.md) - Mint tokens and allocate them to staking rewards, - usage incentives and community pool. -- [recovery](recovery.md) - Recover tokens that are stuck on unsupported Evmos accounts. - [vesting](vesting.md) - Vesting accounts with lockup and clawback capabilities. ## Cosmos SDK diff --git a/docs/protocol/modules/inflation.md b/docs/protocol/modules/inflation.md index df84a16..c1c5eb9 100644 --- a/docs/protocol/modules/inflation.md +++ b/docs/protocol/modules/inflation.md @@ -6,18 +6,16 @@ The `x/inflation` module mints new Evmos tokens and allocates them in daily epochs according to the [Evmos Token Model](https://evmos.blog/the-evmos-token-model-edc07014978b) distribution to -* Staking Rewards `40%`, -* Team Vesting `25%`, -* Usage Incentives: `25%`, -* Community Pool `10%`. +* Community Pool `50%`. +* Staking Rewards `50%`, +* Usage Incentives: `0%`, -It replaces the currently used Cosmos SDK `x/mint` module. +It replaces the Cosmos SDK `x/mint` module, that other Cosmos chains are using. -The allocation of new coins incentivizes specific behaviour in the Evmos -network. Inflation allocates funds to 1) the `Fee Collector account` (in the sdk -`x/auth` module) to increase staking rewards, 2) the `x/incentives` module -account to provide supply for usage incentives and 3) the community pool -(managed by sdk `x/distr` module) to fund spending proposals. +The allocation of new coins incentivizes specific behaviour in the Evmos network. +Inflation allocates funds to 1) the community pool(managed by sdk `x/distribution` module) to fund spending proposals, +and 2) the `Fee Collector account` (in the sdk `x/auth` module) to increase staking rewards. +The now deprecated `x/incentives` module account (3) does not accrue tokens anymore. ## Contents @@ -58,8 +56,7 @@ issue 1 billion Evmos tokens within the first 4 years. We implement two different inflation mechanisms to support the token model: 1. linear inflation for team vesting and -2. exponential inflation for staking rewards, usage incentives and community - pool. +2. exponential inflation for staking rewards and community pool. #### Linear Inflation - Team Vesting @@ -74,12 +71,12 @@ transaction with `unvested` tokens until they are unlocked represented as #### Exponential Inflation - **The Half Life** -The inflation distribution for staking, usage incentives and community pool is +The inflation distribution for staking and community pool is implemented through an exponential formula, a.k.a. the Half Life. -Inflation is minted in daily epochs. During a period of 365 epochs (one year), a -daily provision (`epochProvison`) of Evmos tokens is minted and allocated to staking rewards, -usage incentives and the community pool. +Inflation is minted in daily epochs. During a period of 365 epochs (one year), +a daily provision (`epochProvison`) of Evmos tokens is minted +and allocated to staking rewards and the community pool. The epoch provision depends on module parameters and is recalculated at the end of every epoch. The calculation of the epoch provision is done according to the following formula: @@ -112,6 +109,10 @@ f(2) 84 375 000 553 125 000 231 164 f(3) 46 875 000 600 000 000 128 424 ``` +Note, that after [discussion](https://www.mintscan.io/evmos/proposals/258) +with the validator community, it was decided to decrease the inflation to 1/3 +during the upgrade to [v16.0.0](https://www.mintscan.io/evmos/proposals/265). + ## State ### State Objects @@ -141,7 +142,8 @@ Amount of epochs in one period The `x/inflation` module's `GenesisState` defines the state necessary for initializing the chain from a previously exported height. It contains the module -parameters and the list of active incentives and their corresponding gas meters +parameters, the current period, epoch identifier, epochs per period and +the number of skipped epochs. : ```go @@ -175,8 +177,7 @@ well as updating it: 2. A block is committed, that signalizes that an `epoch` has ended (block `header.Time` has surpassed `epoch_start` + `epochIdentifier`). 3. Mint coin in amount of calculated `epochMintProvision` and allocate according to - inflation distribution to staking rewards, usage incentives and community - pool. + inflation distribution to staking rewards and community pool. 4. If a period ends with the current epoch, increment the period by `1` and set new value to the store. ## Events @@ -196,18 +197,18 @@ The `x/inflation` module emits the following events: The `x/inflation` module contains the parameters described below. All parameters can be modified via governance. -| Key | Type | Default Value | -| ------------------------------------- | ---------------------- | ----------------------------------------------------------------------------- | -| `ParamStoreKeyMintDenom` | string | `evm.DefaultEVMDenom` // “aevmos” | -| `ParamStoreKeyExponentialCalculation` | ExponentialCalculation | `A: sdk.NewDec(int64(300_000_000))` | -| | | `R: sdk.NewDecWithPrec(50, 2)` | -| | | `C: sdk.NewDec(int64(9_375_000))` | -| | | `BondingTarget: sdk.NewDecWithPrec(66, 2)` | -| | | `MaxVariance: sdk.ZeroDec()` | -| `ParamStoreKeyInflationDistribution` | InflationDistribution | `StakingRewards: sdk.NewDecWithPrec(533333334, 9)` // 0.53 = 40% / (1 - 25%) | -| | | `UsageIncentives: sdk.NewDecWithPrec(333333333, 9)` // 0.33 = 25% / (1 - 25%) | -| | | `CommunityPool: sdk.NewDecWithPrec(133333333, 9)` // 0.13 = 10% / (1 - 25%) | -| `ParamStoreKeyEnableInflation` | bool | `true` | +| Key | Type | Default Value | +| ------------------------------------- | ---------------------- |------------------------------------------------------| +| `ParamStoreKeyMintDenom` | string | `evm.DefaultEVMDenom` // “aevmos” | +| `ParamStoreKeyExponentialCalculation` | ExponentialCalculation | `A: sdk.NewDec(int64(300_000_000))` | +| | | `R: sdk.NewDecWithPrec(50, 2)` | +| | | `C: sdk.NewDec(int64(9_375_000))` | +| | | `BondingTarget: sdk.NewDecWithPrec(66, 2)` | +| | | `MaxVariance: sdk.ZeroDec()` | +| `ParamStoreKeyInflationDistribution` | InflationDistribution | `StakingRewards: sdk.NewDecWithPrec(500000000, 9)` | +| | | `UsageIncentives: sdk.NewDecWithPrec(000000000, 9)` | +| | | `CommunityPool: sdk.NewDecWithPrec(500000000, 9)` | +| `ParamStoreKeyEnableInflation` | bool | `true` | ### Mint Denom @@ -226,18 +227,8 @@ can be found under ### Inflation Distribution The `ParamStoreKeyInflationDistribution` parameter defines the distribution in which -inflation is allocated through minting on each epoch (`stakingRewards`, -`usageIncentives`, `CommunityPool`). The `x/inflation` excludes the team -vesting distribution, as team vesting is minted once at genesis. To reflect this -the distribution from the Evmos Token Model is recalculated into a distribution -that excludes team vesting. Note, that this does not change the inflation -proposed in the Evmos Token Model. Each `InflationDistribution` can be -calculated like this: - -```markdown -stakingRewards = evmosTokenModelDistribution / (1 - teamVestingDistribution) -0.5333333 = 40% / (1 - 25%) -``` +inflation is allocated through minting on each epoch +(`stakingRewards`, `CommunityPool`). ### Enable Inflation @@ -247,7 +238,7 @@ epoch. ## Clients -A user can query the `x/incentives` module using the CLI, JSON-RPC, gRPC or +A user can query the `x/inflation` module using the CLI, JSON-RPC, gRPC or REST. ### CLI diff --git a/docs/protocol/modules/recovery.md b/docs/protocol/modules/recovery.md deleted file mode 100644 index 7a446ba..0000000 --- a/docs/protocol/modules/recovery.md +++ /dev/null @@ -1,262 +0,0 @@ -# `recovery` - -Recover tokens that are stuck on unsupported Evmos accounts. - -## Abstract - -This document specifies the `x/recovery` module of the Evmos Hub. - -The `x/recovery` module enables users on Evmos to recover locked funds -that were transferred to accounts whose keys are not supported on Evmos. -This happened in particular after the initial Evmos launch (`v1.1.2`), -where users transferred tokens to a `secp256k1` Evmos address via IBC -in order to [claim their airdrop](claims.md). -To be EVM compatible, -[keys on Evmos](https://docs.evmos.org/protocol/concepts/accounts#evmos-accounts) are generated -using the `eth_secp256k1` key type which results in a different address derivation -than e.g. the `secp256k1` key type used by other Cosmos chains. - -At the time of Evmos’ relaunch, -the value of locked tokens on unsupported accounts sits at $36,291.28 worth of OSMO and $268.86 worth of ATOM tokens -according to the [Mintscan](https://www.mintscan.io/evmos/assets) block explorer. -With the `x/recovery` module, users can recover these tokens back to their own addresses -in the originating chains by performing IBC transfers from authorized IBC channels -(i.e. Osmosis for OSMO, Cosmos Hub for ATOM). - -## Contents - -1. **[Concepts](#concepts)** -2. **[Hooks](#hooks)** -3. **[Events](#events)** -4. **[Parameters](#parameters)** -5. **[Clients](#clients)** - -## Concepts - -### Key generation - -`secp256k1` refers to the parameters of the elliptic curve used in generating cryptographic public keys. -Like Bitcoin, IBC compatible chains like the Cosmos chain use `secp256k1` for public key generation. - -Some chains use different elliptic curves for generating public keys. -An example is the`eth_secp256k1`used by Ethereum and Evmos chain for generating public keys. - -```go -// Generate new random ethsecp256k1 private key and address - -ethPrivKey, err := ethsecp256k1.GenerateKey() -ethsecpAddr := sdk.AccAddress(ethPrivKey.PubKey().Address()) - -// Bech32 "evmos" address -ethsecpAddrEvmos := sdk.AccAddress(ethPk.PubKey().Address()).String() - -// We can also change the HRP to use "cosmos" -ethsecpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, ethsecpAddr) -``` - -The above example code demonstrates a simple user account creation on Evmos. -On the second line, a private key is generated using the `eth_secp256k1` curve, -which is used to create a human readable `PubKey` string. -For more detailed info on accounts, -please check the [accounts section](https://docs.evmos.org/protocol/concepts/accounts#evmos-accounts) -in the official Evmos documentation. - -### Stuck funds - -The primary use case of the `x/recovery` module is to enable the recovery of tokens, -that were sent to unsupported Evmos addresses. -These tokens are termed “stuck”, as the account’s owner cannot sign transactions -that transfer the tokens to other accounts. -The owner only holds the private key to sign transactions for its `eth_secp256k1` public keys on Evmos, -not other unsupported keys (i.e. `secp256k1` keys). -They are unable to transfer the tokens using the keys of the accounts through which they were sent -due to the incompatibility of their elliptic curves. - -### Recovery - -After the initial Evmos launch (`v1.1.2`), tokens got stuck from accounts with -and without claims records (airdrop allocation): - -1. Osmosis/Cosmos Hub account without claims record sent IBC transfer to Evmos `secp256k1` receiver address - - **Consequences** - - - IBC vouchers from IBC transfer got stuck in the receiver’s balance - - **Recovery procedure** - - - The receiver can send an IBC transfer from their Osmosis / Cosmos Hub account (i.e `osmo1...` or `cosmos1...`) - to its same Evmos account (`evmos1...`) to recover the tokens - by forwarding them to the corresponding sending chain (Osmosis or Cosmos Hub) - -2. Osmosis/Cosmos Hub account with claims record sent IBC transfer to Evmos `secp256k1` receiver address - - **Consequences** - - - IBC vouchers from IBC transfer got stuck in the receiver’s balance - - IBC Transfer Action was claimed - and the EVMOS rewards were transferred to the receiver’s Evmos `secp256k1` account, - resulting in stuck EVMOS tokens. - - Claims record of the sender was migrated to the receiver’s Evmos `secp256k1` account - - **Recovery procedure** - - - The receiver can send an IBC transfer from their Osmosis / Cosmos Hub account (i.e `osmo1...` or `cosmos1...`) - to its same Evmos account (`evmos1...`) to recover the tokens - by forwarding them to the corresponding sending chain (Osmosis or Cosmos Hub) - - Migrate once again the claims record to a valid account so that the remaining 3 actions can be claimed - - Chain is restarted with restored Claims records - -### IBC Middleware Stack - -#### Middleware ordering - -The IBC middleware adds custom logic between the core IBC and the underlying application. -Middlewares are implemented as stacks so that applications can define multiple layers of custom behavior. - -The order of middleware matters. -Function calls from IBC core to the application travel from top-level middleware to the bottom middleware -and then to the application, -whereas function calls from the application to IBC core go through the bottom middleware first -and then in order to the top middleware and then to core IBC handlers. -Thus, the same set of middleware put in different orders may produce different effects. - -During packet execution each middleware in the stack will be executed in the order defined on creation -(from top to bottom). - -For Evmos the middleware stack ordering is defined as follows (from top to bottom): - -1. IBC Transfer -2. Claims Middleware -3. Recovery Middleware - -This means that the IBC transfer will be executed first, then the claim will be attempted -and lastly the recovery will be executed. -By performing the actions in this order we allow the users to receive back the coins used to trigger the recover. - -**Example execution order** - -1. User attempts to recover `1000aevmos` that are stuck on the Evmos chain. -2. User sends `100uosmo` from Osmosis to Evmos through an IBC transaction. -3. Evmos receives the transaction, and goes through the IBC stack: - 1. **IBC transfer**: the `100uosmo` IBC vouchers are added to the user balance on evmos. - 2. **Claims Middleware**: since `sender=receiver` -> perform no-op - 3. **Recovery Middleware**: since `sender=receiver` -> recover user balance (`1000aevmos` and `100uosmo`) - by sending an IBC transfer from `receiver` to the `sender` on the Osmosis chain. -4. User receives `100uosmo` and `1000aevmos` (IBC voucher) on Osmosis. - -#### Execution errors - -It is possible that the IBC transaction fails in any point of the stack execution -and in that case the recovery will not be triggered by the transaction, as it will rollback to the previous state. - -So if at any point either the IBC transfer or the claims middleware return an error, -then the recovery middleware will not be executed. - -## Hooks - -The `x/recovery` module allows for state transitions that return IBC tokens -that were previously transferred to EVMOS back to the source chains into the source accounts -with the `Keeper.OnRecvPacket` callback. -The source chain must be authorized. - -### Withdraw - -A user performs an IBC transfer to return the tokens that they previously transferred -to their Cosmos `secp256k1` address instead of the Ethereum `ethsecp256k1` address. -The behavior is implemented using an IBC`OnRecvPacket` callback. - -1. A user performs an IBC transfer to their own account by sending tokens from their address on an authorized chain - (e.g. `cosmos1...`) to their evmos `secp2561` address (i.e. `evmos1`) which holds the stuck tokens. - This is done using a - [`FungibleTokenPacket`](https://github.com/cosmos/ibc/blob/master/spec/app/ics-020-fungible-token-transfer/README.md) - IBC packet. - -2. Check that the withdrawal conditions are met and skip to the next middleware if any condition is not satisfied: - - 1. recovery is enabled globally - 2. channel is authorized - 3. channel is not an EVM channel (as an EVM supports `eth_secp256k1` keys and tokens are not stuck) - 4. sender and receiver address belong to the same account as recovery - is only possible for transfers to a sender's own account on Evmos. - Both sender and recipient addresses are therefore converted from `bech32` to `sdk.AccAddress`. - 5. the sender/recipient account is a not vesting or module account - 6. recipient pubkey is not a supported key (`eth_secp256k1`, `amino multisig`, `ed25519`), - as in this case tokens are not stuck and don’t require recovery - -3. Check if sender/recipient address is blocked by the `x/bank` module - and throw an acknowledgment error to prevent further execution along with the IBC middleware stack -4. Perform recovery to transfer the recipient’s balance back to the sender address with the IBC `OnRecvPacket` callback. - There are two cases: - - 1. First transfer from authorized source chain: - 1. sends back IBC tokens that originated from the source chain - 2. sends over all Evmos native tokens - 2. Second and further transfers from a different authorized source chain - 1. only sends back IBC tokens that originated from the source chain - -5. If the recipient does not have any balance, return without recovering tokens - -## Events - -The `x/recovery` module emits the following event: - -### Recovery - -| Type | Attribute Key | Attribute Value | -| :--------- | :------------------- | :-------------------------- | -| `recovery` | `sender` | `senderBech32` | -| `recovery` | `receiver` | `recipientBech32` | -| `recovery` | `amount` | `amtStr` | -| `recovery` | `packet_src_channel` | `packet.SourceChannel` | -| `recovery` | `packet_src_port` | `packet.SourcePort` | -| `recovery` | `packet_dst_channel` | `packet.DestinationPort` | -| `recovery` | `packet_dst_port` | `packet.DestinationChannel` | - -## Parameters - -The `x/recovery` module contains the following parameters: - -| Key | Type | Default Value | -| :---------------------- | :-------------- | :------------------------ | -| `EnableRecovery` | `bool` | `true` | -| `PacketTimeoutDuration` | `time.Duration` | `14400000000000` // 4hrs | - -### Enable Recovery - -The `EnableRecovery` parameter toggles Recovery IBC middleware. -When the parameter is disabled, it will disable the recovery of stuck tokens to users. - -### Packet Timeout Duration - -The `PacketTimeoutDuration` parameter is the duration before the IBC packet timeouts -and the transaction is reverted on the counter party chain. - -## Clients - -A user can query the `x/recovery` module using the CLI, gRPC or REST. - -### CLI - -Find below a list of `evmosd` commands added with the `x/recovery` module. -You can obtain the full list by using the `evmosd` -h command. - -#### Queries - -The query commands allow users to query Recovery state. - -**`params`** -Allows users to query the module parameters. - -```bash -evmosd query recovery params [flags] -``` - -### gRPC - -#### Queries - -| Verb | Method | Description | -| :----- | :------------------------------- | :-------------------- | -| `gRPC` | `evmos.recovery.v1.Query/Params` | `Get Recovery params` | -| `GET` | `/evmos/recovery/v1/params` | `Get Recovery params` |