Skip to content

Commit

Permalink
Merge pull request #116 from neonlabsorg/update/fees-and-gas-page
Browse files Browse the repository at this point in the history
add PRX_GAS_PRICE_SLIPPAGE parameter to gas price formula
  • Loading branch information
m4sterbunny authored Dec 4, 2023
2 parents bdb214f + 44bc5e7 commit 8e0b2be
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
---
title: Fees & Gas
proofedDate: na
proofedDate: 20231204
iterationBy: na
includedInSite: true
approvedBy: na
comment: wip items inline
comment: todo the zero gas for testing setup (see commented out section)

Check warning on line 7 in docs/operating/transaction-gas.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [write-good-adapted.todo] 'todo' left in text Raw Output: {"message": "[write-good-adapted.todo] 'todo' left in text", "location": {"path": "docs/operating/transaction-gas.mdx", "range": {"start": {"line": 7, "column": 10}}}, "severity": "WARNING"}
---

import Formula from '../single-source-snippets/_price_formula.mdx'
import Price from '../single-source-snippets/_gas_price_calc.mdx'

## TL;DR

Operators:
Expand All @@ -29,29 +32,27 @@ The Neon EVM calculates gas usage by tracking the SOL spent by the Neon Operator

### Pass on gas savings

Because the Neon EVM operates on Solana, not Ethereum it takes advantage of Solana’s inexpensive transaction costs and favourable approach to only charge for storage allocation. This contrasts with Ethereum, where calculations require much more gas, and gas is charged for every change in data stored in Ethereum. As a result, gas usage on Solana is much cheaper than on Ethereum, and the Neon EVM passes these savings on to users.
Because the Neon EVM operates on Solana, not Ethereum, it takes advantage of Solana’s inexpensive transaction costs and favorable approach to only charge for storage allocation. This contrasts with Ethereum, where calculations require much more gas, and gas is charged for every change in data stored in Ethereum. As a result, gas usage on Solana is much cheaper than on Ethereum, and the Neon EVM passes these savings on to users.

Check warning on line 35 in docs/operating/transaction-gas.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google-adapted.Passive] In general, use active voice instead of passive voice ('is charged'). Raw Output: {"message": "[Google-adapted.Passive] In general, use active voice instead of passive voice ('is charged').", "location": {"path": "docs/operating/transaction-gas.mdx", "range": {"start": {"line": 35, "column": 259}}}, "severity": "INFO"}


## Gas price: the Operator fee

The Neon Proxy obtains the current prices of SOL and NEON tokens from the [pyth.network](http://pyth.network) oracles.

Gas price = $SOL / $NEON * (1 + `PRX_OPERATOR_FEE`)
<Formula/>

> This ensures that the Neon Operator receives enough NEONs to cover the transaction cost in SOLs.
> This ensures that the Neon Operator receives enough NEON to cover the transaction cost in SOL.
The Neon Operator configures the value of `PRX_OPERATOR_FEE` where 1.0 represents 100% of the potential fee extraction, i.e. PRX_OPERATOR_FEE = "1.0”
The Neon Operator configures the value of `PRX_OPERATOR_FEE`, where 1.0 represents 100% of the potential fee extraction. The value of this parameter is currently set to **1**.

Check warning on line 46 in docs/operating/transaction-gas.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [write-good-adapted.Weasel] 'currently' is a weasel word! Raw Output: {"message": "[write-good-adapted.Weasel] 'currently' is a weasel word!", "location": {"path": "docs/operating/transaction-gas.mdx", "range": {"start": {"line": 46, "column": 153}}}, "severity": "WARNING"}

For example:
Parameter `PRX_GAS_PRICE_SLIPPAGE` provides a buffer against transactions getting stuck in the mempool if there is volatility in prices of $SOL and $NEON. The value of this parameter is currently set to **0.25**.

Check warning on line 48 in docs/operating/transaction-gas.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [write-good-adapted.Weasel] 'currently' is a weasel word! Raw Output: {"message": "[write-good-adapted.Weasel] 'currently' is a weasel word!", "location": {"path": "docs/operating/transaction-gas.mdx", "range": {"start": {"line": 48, "column": 187}}}, "severity": "WARNING"}

- $NEON = $0.25
- $SOL = $10
- PRX_OPERATOR_FEE = "1"
- Gas price = 10 / 0.25 * (1 + 1) = 80 Galan
For example:
<Price/>

Neon recommends that Neon Operators should initially set `PRX_OPERATOR_FEE` to “1.0” for Mainnet launch. This allows Operators to cover their hardware costs while transaction demands are low. As demand grows, Operators may adjust their fees in response.
Neon recommended that Neon Operators should initially set `PRX_OPERATOR_FEE` to “1.0” for Mainnet launch. This allows Operators to cover their hardware costs while transaction demands are low. As demand grows, Operators may adjust their fees in response.

> For example, `PRX_OPERATOR_FEE` = “0.1” → 10% of the total possible Neon Operator fee.
> A `PRX_OPERATOR_FEE` = “0.1” → 10% of the total possible Neon Operator fee.
## Minimum gas price

Expand All @@ -75,9 +76,12 @@ The Neon Proxy has several settings that accommodate the calculation of gas-pric
- `PRX_PYTH_MAPPING_ACCOUNT`: the Solana address of the Pyth mapping account; select the address on (https://pyth.network/developers/accounts) based on the type of network (Devnet/Mainnet)
- `PRX_UPDATE_PYTH_MAPPING_PERIOD_SEC`: the time period to reread the Pyth mapping account. The Neon Proxy reads the Pyth mapping account at the start, gets the addresses of $NEON and $SOL accounts, and rechecks the address from the Pyth Mapping account only after `UPDATE_PYTH_MAPPING_PERIOD_SEC`. It is recommended to set this generously (e.g. 1/3/10 hours), because the price feed accounts don’t change often.
- `PRX_MINIMAL_GAS_PRICE`: the minimum gas price to accept transactions into the mempool for on-chain execution

<!--

> Let's take a closer look at the minimum gas price variable.

<!-- ## Zero gas price for testing
## Zero gas price for testing

On Devnet test NEON is available, however, for beta Mainnet testing purposes, the Neon Proxy can be configured to accept transactions with a 0 gas price (a balance of SOL is available to cover the transaction fees on Solana).

Expand Down
15 changes: 0 additions & 15 deletions docs/single-source-snippets/_gas-price.mdx

This file was deleted.

11 changes: 11 additions & 0 deletions docs/single-source-snippets/_gas_price_calc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
| Component | Value | Units/Definition | Calculation |
| ------------------------ | ------------ | ---------------- | ----------- |
| Sol | 50 | $ | |
| Neon | 0.5 | $ | |
| Ratio | | SOL:NEON | 120 |
| Galan ratio | | Ratio \*10<sup>-9</sup> | 0.00000012 |
| Operator fee ratio | 1 | | |
| Proxy Gas Price Slippage | 0.25 | | |
| Adjustor | | 1+fee+slippage | 2.09 |
| **Gas price** | **0.0000002475** | NEON | [Gas price formula](#gas-price) |
| | **247.5** | Galan |
9 changes: 9 additions & 0 deletions docs/single-source-snippets/_price_formula.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
> Gas price = $SOL / $NEON(* 10<sup>-9</sup> NEON) * (1 + `PRX_OPERATOR_FEE` + `PRX_GAS_PRICE_SLIPPAGE`)
which can also be represented as:

Check warning on line 3 in docs/single-source-snippets/_price_formula.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google-adapted.Passive] In general, use active voice instead of passive voice ('be represented'). Raw Output: {"message": "[Google-adapted.Passive] In general, use active voice instead of passive voice ('be represented').", "location": {"path": "docs/single-source-snippets/_price_formula.mdx", "range": {"start": {"line": 3, "column": 16}}}, "severity": "INFO"}

> Gas price = SOL-to-NEON-rate in Galan * (1 + `PRX_OPERATOR_FEE` + `PRX_GAS_PRICE_SLIPPAGE`)



106 changes: 74 additions & 32 deletions docs/tokens/gas_fees.mdx
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
---
title: Gas Fees
proofedDate: na
proofedDate: 20231204
iterationBy: na
includedInSite: true
approvedBy: na
comment: Attempt to single source based on these docs failing to understand https://docusaurus.io/docs/next/markdown-features/react#markdown-and-jsx-interoperability -- need some help
comment: Calc sheet https://docs.google.com/spreadsheets/d/1g2ms3DveyPgrG0Gf6cSwq6xhT0AgrrRus_pa9ICHP4w/edit?usp=sharing

Check failure on line 7 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google-adapted.Units] Put a nonbreaking space between the number and the unit in '2ms'. Raw Output: {"message": "[Google-adapted.Units] Put a nonbreaking space between the number and the unit in '2ms'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 7, "column": 62}}}, "severity": "ERROR"}
---

import Formula from '../single-source-snippets/_price_formula.mdx'
import Price from '../single-source-snippets/_gas_price_calc.mdx'

import GasPrice from '../single-source-snippets/_gas-price.mdx'
## TL;DR

- `Gas Fee` = `Gas amount` \* `Gas price`
- [`Gas price`](#gas-price) depends on the SOL:NEON ratio and Proxy Operator fee
- [`Gas amount`](#gas-amount) depends on the computational resources as per Solana's rules
- The first transaction (i.e. requires account setup), is [more expensive](#example-2-create-a-new-account) than subsequent transactions

Check warning on line 18 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [write-good-adapted.TooWordy] 'subsequent' can you drop this word/phrase?. Raw Output: {"message": "[write-good-adapted.TooWordy] 'subsequent' can you drop this word/phrase?.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 18, "column": 114}}}, "severity": "WARNING"}

## Key takeaways

The NEON token is used to pay the “gas fees” required for transaction execution. The gas fee is the amount of NEON tokens that a user needs to pays for a transaction to execute it successfully.
## Introduction

The NEON token is used to pay the “gas fees” required for transaction execution. The gas fee is the amount of NEON a user pays for a transaction to execute successfully.

Check warning on line 23 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google-adapted.Passive] In general, use active voice instead of passive voice ('is used'). Raw Output: {"message": "[Google-adapted.Passive] In general, use active voice instead of passive voice ('is used').", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 23, "column": 16}}}, "severity": "INFO"}

Check warning on line 23 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [write-good-adapted.Weasel] 'successfully' is a weasel word! Raw Output: {"message": "[write-good-adapted.Weasel] 'successfully' is a weasel word!", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 23, "column": 157}}}, "severity": "WARNING"}

:::info

Check warning on line 25 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google-adapted.Substitutions] Use 'information' instead of 'info'. Raw Output: {"message": "[Google-adapted.Substitutions] Use 'information' instead of 'info'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 25, "column": 4}}}, "severity": "WARNING"}
Neon EVM will soon support fee payment in the same token as the transaction token for supported tokens e.g. SOL and USDC.

Check warning on line 26 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google-adapted.Will] Avoid using 'will'. Stick to the present tense. Raw Output: {"message": "[Google-adapted.Will] Avoid using 'will'. Stick to the present tense.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 26, "column": 10}}}, "severity": "WARNING"}
:::

> `Gas Fee` = `Gas amount` \* `Gas price`
>
> This amount is usually displayed for users in [Galans (10<sup>-9</sup> NEON)](/docs/tokens/neon_token#token-parameters).

Check failure on line 31 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'NEON' instead of 'neon'. Raw Output: {"message": "[Vale.Terms] Use 'NEON' instead of 'neon'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 31, "column": 94}}}, "severity": "ERROR"}
On a high level, gas fee payments in the Neon EVM work as follows:
1. The **User** pays for each transaction in NEON tokens to the **Proxy Operator**.
Expand All @@ -25,56 +40,83 @@ On a high level, gas fee payments in the Neon EVM work as follows:

</div>

As depicted in the diagram above, users of dApps built on the Neon EVM pay in NEON tokens for all the resources they consume, in addition to Operator fees that differ between Operators. Operators, however, use SOL to pay for the resources they consume. Specifically, operators pay Solana validators and governance fees in SOL. Operators pay the same amount for governance as they pay to Solana validators (for the signature validation).
As depicted in the diagram, users of dApps built on the Neon EVM pay for all the resources they consume plus the Operator fees (that may differ between Operators). Operators pay for the resources they consume in SOL. Specifically, Operators pay Solana validators and governance fees in SOL. Operators pay the same amount for governance as they pay to Solana validators (for the signature validation).

### Gas amount

The gas fee that a user pays is calculated as **gas amount \* gas price**.
The **gas amount** is the amount of computational resources, such as CPU time and storage, used to execute the transaction. The gas amount is calculated in accordance with Solana's rules (in fact, 1 gas unit = 1 Lamport) as a sum of the following amounts:
* The **computational cost**
> 5,000 units for each transaction (Solana charges 5,000 Lamports for the signature validation for each transaction). This amount goes to Solana validator. This computational cost is **doubled** to give the same amount of gas fees to the **DAO Treasury**.

Check failure on line 49 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'lamports' instead of 'Lamports'. Raw Output: {"message": "[Vale.Terms] Use 'lamports' instead of 'Lamports'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 49, "column": 58}}}, "severity": "ERROR"}
* The **storage cost**
> 6,960 units for each newly allocated byte (Solana charges 6,960 Lamports for each byte), while re-use of existing or already-allocated storage is free.

Check failure on line 51 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'lamports' instead of 'Lamports'. Raw Output: {"message": "[Vale.Terms] Use 'lamports' instead of 'Lamports'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 51, "column": 67}}}, "severity": "ERROR"}
The **gas amount** is the amount of computational resources, such as CPU time and storage, used to execute the transaction. The gas amount is calculated mainly in accordance with Solana's rules (in fact, 1 gas unit = 1 lamport) as a sum of the following amounts:
* The **computational cost**, which is 5,000 units for each transaction (Solana charges 5,000 lamports for the signature validation for each transaction). This amount goes to Solana validator. This computational cost is **doubled** to give the same amount of gas fees to the **DAO Treasury**.
* The **storage cost**, which is 6,960 units for each newly allocated byte (Solana charges 6,960 lamports for each byte), while re-use of existing or already-allocated storage is free.
For example, for a Neon transaction with N iterations and S newly allocated bytes, the *gas amount* will be:

For example, for a Neon transaction with N iterations and S newly allocated bytes, the gas amount will be:
> 2(computational cost) + storage cost
> 2 \* computational cost + storage cost
> = 2(5,000 \* N) + (6960 \* S units)
> = 2 \* 5,000 \* N + 6960 \* S units
### Gas price

<GasPrice/>
The **gas price** is the cost of 1 unit of gas in NEON. This price is calculated using the price of SOL:NEON multiplied by an adjuster that is configured by the Proxy Operator:

<Formula/>


## Examples
The following are some examples of gas fee calculation on Neon. They are all based on the following assumptions:
* The SOL price is $30 and the NEON price is $0.25
* The SOL-to-NEON rate is therefore 30 / 0.25 = 120.
* The Proxy Operator fee is 10%.
* The gas price is therefore (1 + 10%) \* 120 \* 10<sup>-9</sup> NEON = 132 \* 10<sup>9</sup> Alan = 132 Galan

### Example 1: swap
The gas amount in this case is 10 \* 2 \* 5,000 (computational cost + treasury) + 5 \* 6,960 (storage cost) ≈ 134,800 units
The total gas fee is therefore 134,800 units \* 132 \* Galan = 0.01779 NEON.
The following examples of gas fee calculations on Neon are all based on these assumptions:

<Price/>

### Example 1: swap or transfer

If the spend is already approved from an account that already exists, we can use the following Gas amount with the Gas price as calculated above.

The Gas amount is calculated with N=1 iterations and S=0 storage costs:

| Component | Value | Units/Definition | Calculation |
| ------------------ | ---------- | ------------------ | ---------------------------- |
| Computational cost | 1 | iterations \* 5000 | 1000 |
| Storage cost | 0 | bytes \* 6960 | 34800 |
| Gas amount | 54800 | Lamports | (2\*computational) + storage |

Check failure on line 82 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'lamports' instead of 'Lamports'. Raw Output: {"message": "[Vale.Terms] Use 'lamports' instead of 'Lamports'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 82, "column": 36}}}, "severity": "ERROR"}
| | | | |
| **Gas Fee** | **0.002475** | NEON | [gas price](#examples) \* gas amount |

### Example 2: create a new account
Within [Solana](https://docs.solana.com/storage_rent_economics), the rental cost for storage can be paid via one of two methods:
1. Set it and forget it.

> With this approach, accounts with two years' worth of rent deposited are exempt from network rent charges. By maintaining this minimum balance, the broader network benefits from reduced liquidity and the account holder can rest assured that their data will be retained for continual access and usage.
> With this approach, accounts with two years' worth of rent deposited are exempt from network rent charges. By maintaining this minimum balance, the broader network benefits from reduced liquidity and the account holder can rest assured that their data is retained for continual access and usage.
2. Pay per byte.

> If an account has less than two years' worth of deposited rent, the network charges rent on a per-epoch basis, in credit for the next epoch. This rent is deducted at a rate specified in genesis, in lamports per kilobyte-year.
> The network can charge rent on a per-epoch basis, in credit for the next epoch. This rent is deducted at a rate specified in genesis, in Lamports per Kilobyte-year.

Check failure on line 94 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'lamports' instead of 'Lamports'. Raw Output: {"message": "[Vale.Terms] Use 'lamports' instead of 'Lamports'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 94, "column": 140}}}, "severity": "ERROR"}
To simplify the user experience, Neon takes option 1 and charges two years' worth of rent deposits for each new account. The gas cost of creating a new account is:


| Component | Value | Units/Definition | Calculation |
| ------------------ | ---------- | ------------------ | ---------------------------- |
| Computational cost | 1 | iterations \* 5000 | 1000 |
| Storage cost | 199 | bytes \* 6960 | 34800 |
| Gas amount | 1395040 | Lamports | (2\*computational) + storage |

Check failure on line 103 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'lamports' instead of 'Lamports'. Raw Output: {"message": "[Vale.Terms] Use 'lamports' instead of 'Lamports'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 103, "column": 38}}}, "severity": "ERROR"}
| | | | |
| **Gas Fee** | **0.3452724** | NEON | [gas price](#examples) \* gas amount |

To simplify the user experience, Neon charges two years' worth of rent deposits for each new account. The gas cost of creating a new account is:
> 0 \* 2 \* 5,000 (computational cost + treasury) + (128 + 71) \* 6960 (storage cost for the minimum Neon account size) ≈ 1,400,000 units

Therefore, the total gas fee is 1,400,000 units \* 132 Galan = 0.1848 NEON tokens.

### Example 3: transfer
### Example 3: create a pool in Sobal

In the case of a transfer of NEON or ERC-20 tokens, the gas amount is:
> 1 \* 2 \* 5,000 (computational cost + treasury) + 0 \* 6,960 (storage cost in case the account exists) ≈ 10,000 units
| Component | Value | Units/Definition | Calculation |
| ------------------ | ---------- | ------------------ | ---------------------------- |
| Computational cost | 32 | iterations \* 5000 | 1000 |
| Storage cost | 10000 | bytes \* 6960 | 34800 |
| Gas amount | 69920000 | Lamports | (2\*computational) + storage |

Check failure on line 115 in docs/tokens/gas_fees.mdx

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'lamports' instead of 'Lamports'. Raw Output: {"message": "[Vale.Terms] Use 'lamports' instead of 'Lamports'.", "location": {"path": "docs/tokens/gas_fees.mdx", "range": {"start": {"line": 115, "column": 39}}}, "severity": "ERROR"}
| | | | |
| **Gas Fee** | **17.3052** | NEON | [gas price](#examples) \* gas amount |

Therefore, the total gas fee is 10,000 units * 132 Galan = 0.00132 NEON tokens.

## What next?

If you want to get your dApp started on Neon EVM you may be wondering how you pay for the first transactions that are required to buy the NEON required to cover gas costs. This is where our starter pack of [gasless transactions](/docs/developing/gasless) comes in.
If you want to get your dApp started on Neon EVM, you may be wondering how you pay for the first transactions that are required to buy the NEON required to cover gas costs. This is where our starter pack of [gasless transactions](/docs/developing/gasless) comes in. Furthermore, our "coming soon" feature will allow users to pay fees in [alternative tokens](https://neonevm.org/blog/feature-alternative-gas-fee-token).

0 comments on commit 8e0b2be

Please sign in to comment.