forked from CosmosContracts/juno
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FeePay Documentation (CosmosContracts#886)
* Structure FeePay Docs * Complete FeePay Docs * fmt on 04 page --------- Co-authored-by: Reece Williams <[email protected]> Co-authored-by: Reece Williams <[email protected]>
- Loading branch information
1 parent
c7f8966
commit d48ff12
Showing
6 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# FeePay | ||
|
||
The `x/feepay` allows developers to register contracts, fund them with juno, and then cover the execution fees of wallets interacting with their contract. | ||
|
||
[FeePay Spec](./spec/README.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<!-- | ||
order: 1 | ||
--> | ||
|
||
# Concepts | ||
|
||
## FeePay | ||
|
||
The FeePay module provides functionality for Smart Contract developers to cover the execution fees of transactions interacting with their contract. This aims to improve the user experience and help onboard wallets with little to no available funds. Developers can setup their contract with FeePay by first registering it and then funding it with Juno. Clients can then interact with the contract by explicitly specifying 0 fees. | ||
|
||
## Registering a Contract | ||
|
||
Register a contract with FeePay by executing the following transaction: | ||
|
||
```bash | ||
junod tx feepay register [contract_address] [wallet_limit] | ||
``` | ||
|
||
> Note: the sender of this transaction must be the contract admin, if exists, or else the contract creator. | ||
The `contract_address` is the bech32 address of the contract whose execution fees will be covered. The `wallet_limit` is the maximum number of times a wallet can execute the contract with 0 fees. This is a safety measure to prevent draining the account. The `wallet_limit` can be set to 0 to disable all FeePay interactions with this contract. Executions can still take place if the client explicitly specifies gas or a fee. | ||
|
||
## Updating the Wallet Limit | ||
|
||
The `wallet_limit` can be updated by executing the following transaction: | ||
|
||
```bash | ||
junod tx feepay update-wallet-limit [contract_address] [wallet_limit] | ||
``` | ||
|
||
> Note: the sender of this transaction must be the contract admin, if exists, or else the contract creator. | ||
The `contract_address` is the bech32 address of the FeePay contract to update. The `wallet_limit` is the maximum number of times a wallet can execute the contract with 0 fees. A `wallet_limit` of 0 disables all FeePay interactions with this contract. Executions can still take place if the client explicitly specifies gas or a fee. | ||
|
||
## Unregistering a Contract | ||
|
||
A contract can be unregistered by executing the following transaction: | ||
|
||
```bash | ||
junod tx feepay unregister [contract_address] | ||
``` | ||
|
||
> Note: the sender of this transaction must be the contract admin, if exists, or else the contract creator. | ||
The `contract_address` is the bech32 address of the FeePay contract to unregister. Unregistering a contract will remove it from the FeePay module. This means that clients will no longer be able to interact with the contract with 0 fees. Executions can still take place if the client explicitly specifies gas or a fee. All funds in the contract will be sent to the contract creator. | ||
|
||
## Funding a Contract | ||
|
||
A contract can be funded by executing the following transaction: | ||
|
||
```bash | ||
junod tx feepay fund [contract_address] [amount] | ||
``` | ||
|
||
The `contract_address` is the bech32 address of the FeePay contract to fund. The `amount` is the amount of Juno to send to the contract. This amount will be used to pay for the execution fees of transactions interacting with the contract. Presently the FeePay module only supports Juno. The `amount` must be specified in ujuno. | ||
|
||
## Client Interactions | ||
|
||
Clients can interact with a contract registered with FeePay by explicitly specifying 0 fees. This can be done by setting the `--fees=0ujuno` flag. | ||
|
||
```bash | ||
junod tx wasm execute [contract_address] [json] --fees=0ujuno | ||
``` | ||
|
||
The `contract_address` is the bech32 address of the FeePay contract to interact with. The `json` is the JSON-encoded transaction message. The `--fees=0ujuno` flag explicitly sets the fees to 0. This will trigger the FeePay module to attempt to pay for the execution fees of the transaction. See the [Ante](03_ante.md) for more details on how this works. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<!-- | ||
order: 2 | ||
--> | ||
|
||
# State | ||
|
||
## State Objects | ||
|
||
The `x/feepay` module keeps the following objects in the state: FeePayContract and FeePayWalletUsage. These objects are used to store the state of a contract and the number of times a wallet has interacted with a contract. | ||
|
||
```go | ||
// This defines the address, balance, and wallet limit | ||
// of a fee pay contract. | ||
message FeePayContract { | ||
// The address of the contract. | ||
string contract_address = 1; | ||
// The ledger balance of the contract. | ||
uint64 balance = 2; | ||
// The number of times a wallet may interact with the contract. | ||
uint64 wallet_limit = 3; | ||
} | ||
``` | ||
|
||
```go | ||
// This object is used to store the number of times a wallet has | ||
// interacted with a contract. | ||
message FeePayWalletUsage { | ||
// The contract address. | ||
string contract_address = 1; | ||
// The wallet address. | ||
string wallet_address = 2; | ||
// The number of uses corresponding to a wallet. | ||
uint64 uses = 3; | ||
} | ||
``` | ||
|
||
## Genesis & Params | ||
|
||
The `x/feepay` module's `GenesisState` defines the state necessary for initializing the chain from a previously exported height. It contains the module parameters and the fee pay contracts. As of now, it does not contain the wallet usage. The params are used to enable or disable the module. This value can be modified with a governance proposal. | ||
|
||
```go | ||
// GenesisState defines the module's genesis state. | ||
message GenesisState { | ||
// params are the feepay module parameters | ||
Params params = 1 [ (gogoproto.nullable) = false ]; | ||
|
||
// fee_pay_contracts are the feepay module contracts | ||
repeated FeePayContract fee_pay_contracts = 2 [ (gogoproto.nullable) = false ]; | ||
} | ||
|
||
// Params defines the feepay module params | ||
message Params { | ||
// enable_feepay defines a parameter to enable the feepay module | ||
bool enable_feepay = 1; | ||
} | ||
``` | ||
|
||
## State Transitions | ||
|
||
The following state transitions are possible: | ||
|
||
- Registering a contract creates a FeePayContract object in the state. | ||
- Unregistering a contract removes the FeePayContract object from the state. | ||
- Funding a contract updates the balance of the FeePayContract object in the state. | ||
- Updating the wallet limit of a contract updates the FeePayContract object in the state. | ||
- Interacting with a contract updates the FeePayWalletUsage object in the state and deducts the balance of the FeePayContract object in the state. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!-- | ||
order: 3 | ||
--> | ||
|
||
# Ante | ||
|
||
The `x/feepay` module implements two handlers to perform all of the necessary logic on incoming transactions. | ||
|
||
## FeeRouteDecorator Logic | ||
|
||
The FeeRouteDecorator is responsible for determining if a transaction is to be processed as a FeePay transaction and correctly routes it to additional decorators for further processing. Below are the steps taken by the FeeRouteDecorator to process a transaction: | ||
|
||
1. Flag incoming transaction as a FeePay transaction or not a FeePay transaction (Requirements: 0 provided gas, 0 provided fee, contains only 1 message, only message is a MsgExecuteContract message, & the contract is registered with FeePay) | ||
2. If a FeePay transaction: | ||
1. Route to FeePayDecorator (If an error occurs: Handle transaction normally with the SDK's DeductFeeDecorator logic & proceed if no additional errors occur) | ||
2. Route to GlobalFeeDecorator | ||
3. If not a FeePay transaction: | ||
1. Route to GlobalFeeDecorator | ||
2. Route to FeePayDecorator | ||
|
||
The purpose of routing a FeePay transaction to the FeePayDecorator first is to avoid the GlobalFeeDecorator from erroring out due to no provided fees. Additionally, if the FeePayDecorator logic fails, the transaction will attempt to be processed by the SDK's DeductFeeDecorator logic and then proceed to the GlobalFeeDecorator if no errors occur. | ||
|
||
## FeePayDecorator Logic | ||
|
||
> Note: The FeePayDecorator is an extension of the SDK's DeductFeeDecorator. | ||
The FeePayDecorator is responsible for handling normal fee deductions (on normal transactions) and all FeePay transaction logic (on FeePay transactions). Below are the steps taken by the FeePayDecorator to process a transaction: | ||
|
||
1. If not a FeePay transaction: | ||
1. Deduct fees from the transaction normally, just like the default SDK decorator | ||
2. If a FeePay transaction: | ||
1. Determine the required fee to cover the contract execution gas cost | ||
2. Ensure wallet has not exceeded limit | ||
3. Ensure contract has enough funds to cover fee | ||
4. Transfer funds to the FeeCollector module from the contract's funds | ||
5. Update contract funds in state | ||
6. Increment wallet usage in state | ||
|
||
If any of the FeePay transaction steps fail, the transaction will attempt to be processed normally by the SDK's DeductFeeDecorator logic. If the fallback attempt succeeds, the transaction will pass. If the fallback attempt fails, the transaction will fail and the client will be notified of any and all errors. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!-- | ||
order: 4 | ||
--> | ||
|
||
# Clients | ||
|
||
## Command Line Interface (CLI) | ||
|
||
The CLI has been updated with new queries and transactions for the `x/feepay` module. View the entire list below. | ||
|
||
### Queries | ||
|
||
| Command | Subcommand | Arguments | Description | | ||
| :------------------- | :------------ | :---------------------------------- | :-------------------------------------------------------------- | | ||
| `junod query feepay` | `params` | | Get FeePay params | | ||
| `junod query feepay` | `contract` | [contract_address] | Get a FeePay contract | | ||
| `junod query feepay` | `contracts` | | Get all FeePay contracts | | ||
| `junod query feepay` | `uses` | [contract_address] [wallet_address] | Get the number of times a wallet has interacted with a contract | | ||
| `junod query feepay` | `is-eligible` | [contract_address] [wallet_address] | Check if a wallet has not met the wallet limit on a contract | | ||
|
||
### Transactions | ||
|
||
| Command | Subcommand | Arguments | Description | | ||
| :-----------------| :-------------------- | :-------------------------------- | :--------------------------------------------- | | ||
| `junod tx feepay` | `register` | [contract_address] [wallet_limit] | Register a FeePay contract with a wallet limit | | ||
| `junod tx feepay` | `update-wallet-limit` | [contract_address] [wallet_limit] | Update the wallet limit of a FeePay contract | | ||
| `junod tx feepay` | `unregister` | [contract_address] | Unregister a FeePay contract | | ||
| `junod tx feepay` | `fund` | [contract_address] [amount] | Fund a FeePay contract | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# `feepay` | ||
|
||
## Abstract | ||
|
||
This document specifies the internal `x/feepay` module of Juno Network. | ||
|
||
The `x/feepay` module provides functionality for Smart Contract developers to cover the execution fees of transactions interacting with their contract. This aims to improve the user experience and help onboard wallets with little to no available funds. | ||
|
||
## Contents | ||
|
||
1. **[Concepts](01_concepts.md)** | ||
2. **[State](02_state.md)** | ||
3. **[Ante](03_ante.md)** | ||
4. **[Clients](04_clients.md)** |