Table of Contents
Introduction
Background
Moonbeam and Moonriver have historically provided Web3 developers and users a low fee environment in which to experiment with Moonbeam’s connected contract capabilities. However, as the Moonbeam and Moonriver ecosystems continue to mature, so too must the fee model to ensure long term sustainability and scalability.
As discussed in this previous forum post, a Dynamic Fee model had already been in the process of making its way to Moonbeam but it became necessary to accelerate this effort due to a particular use case which was causing a rapid increase in the size of chain storage which was clearly not sustainable.
While the addition of Dynamic Fees resulted in the rate of growth of storage to decrease, it has only bought time - long term sustainability remains at risk.
A fundamental reason for this is that the fee model on Moonbeam and Moonriver was implemented in such a way as to maximize compatibility with Ethereum and this model disproportionately leans towards transaction compute costs over storage costs. When one considers that the current model is to pay once to store data forever, it becomes clear to the reader that this could be problematic and that fees related to data storage must be appropriately set.
Here is the rate of growth as of May 24th. The effect of Dynamic Fees is visible but storage continues to grow at an alarming rate :
(Blue: Accounts, Red: Smart Contracts)
Purpose of Post
Over the past few weeks, many of the Moonbeam core developers have been discussing various ways that the fee model could be modified in order to drive better alignment between user/developer behavior and long term sustainability.
The purpose of this post is to provide a high level summary of possible solutions to the community in order to provide the community with an opportunity to weigh in on these proposals, ask questions and provide feedback.
For each proposal, a link to a corresponding MBIP (Moonbeam Improvement Proposal) in GitHub is provided where the technical specifics are detailed. Engineering oriented discussions on specific implementation details should be discussed there.
Each of these proposals have potentially far reaching implications for the Moonriver and Moonbeam networks, users, developers and other stakeholders. The implementation and adoption of one or more of these solutions can only occur with the approval of the community through governance.
Timeline
Given the potential impact of these proposals on the core protocol, it is critical that the community is provided ample time to provide feedback. Moreover, the implementation of one or more of these solutions is a non-trivial amount of work and should only commence once the community has indicated its support.
Assuming the change would be introduced in Runtime 2500, here is a tentative timeline (subject to change based on feedback, additional research from core engineers, etc.):
- Community Feedback: Today through June 14th
- Snapshot Vote: June 14th to June 21st
- Development: June 21st to July 5th
- Runtime 2500 Deployment Cycle - July 5th through August 6th
Proposals (MBIPs)
List of MBIPs and Evaluation
As various approaches were considered, they were evaluated in the context of 3 scenarios on Moonbeam which impact storage size:
- Creation of a new account (EOAs as well as contracts)
- Storage of a Smart Contract
- Storage of data within a Smart Contract
At this time, there are 5 proposals presented for discussion:
- MBIP-1: Smart Contract Creation Deposit
- MBIP-2: Storage Data Deposit
- MBIP-3: Storage Rent Mechanism
- MBIP-4: Storage Base Fee
- MBIP-5: Gas-Based Storage Limit
These proposals vary in terms of which of the 3 storage categories they address. In theory, some of these proposals could be used in combination with one another as part of a holistic approach.
A summary of each proposal is provided below and considered from the perspective of the following criteria:
- Storage Categories Addressed: A, B and/or C as per above
- Cost to Grief Network: Relative amount of cost in GLMR to grief the network from storage spam. (Based on a number of assumptions but should be useful to understand the order of magnitude)
- Impact to Ethereum Compatibility: How much does this deviate from Ethereum Compatibility (low=good, high=bad)
- Impact to End-User Experience: Extent to which end-user experience is negatively impacted (low=good, high=bad)
- Impact to Developer Experience: Extent to which end-user experience is negatively impacted (low=good, high=bad)
MBIP-1: Smart Contract Creation Deposit
This solution proposes that a deposit would be required in order to deploy a Smart Contract. The deposit would be proportional to the size of the contract plus any overhead and would be taken from the account sending the transaction that resulted in the creation of the contract.
The deposit is linked to the contract itself. If and when the contract is destroyed, the deposit would be returned to the depositor account.
This proposal addresses:
- Category B: Storage of a Smart Contract
This would primarily impact projects who are deploying smart contracts but it should be noted that this goes beyond dApp developers since in some use cases, a user may interact with a smart contract which turns around and creates one or more new contracts (eg. creating a multisig, launchpads, etc).
The deposit could either be debited from the overall account balance or, it could be “reserved” (ie. the deposit remains with the address but is not part of the transferable amount).
Either way, the deposit would not be visible via the Ethereum RPC which may confuse users. That is, it would not appear in EVM based Wallets or in Moonscan and a user may not realize when signing a transaction that a deposit will be deducted from their balance (for example, when creating a new Moonsafe multisig). Moreover, a user could interact with a contract that in turn creates many new contracts causing the entire user balance being used for deposit.
These compatibility issues could perhaps be mitigated by including the deposit amount as part of the overall “value” used in the transaction but would require developers to take this into consideration in developing/maintaining their dApps and it’s unclear if they’d follow this approach and would be a special case for their Moonbeam deployment (as compared to other EVM chains).
MBIP-1 Summary
- Storage Categories Addressed:
- Category B: Storage of a Smart Contract
- Cost to Grief Network: Very High
- Impact to Ethereum Compatibility: Medium
- Impact to User Experience: Medium
- Impact to Developer Experience: Medium
- MBIP-1 Draft Technical Specifications
MBIP-2: Storage Data Deposit
In this proposal, whenever a user executes a transaction that increases the storage size of the chain, a deposit is taken (or reserved) from the sender proportional to the increase in storage size and added to the sender’s overall “deposit balance”. Unlike MBIP-1, the deposit is linked to the user (sender), not the contract.
Conversely, whenever a user executes a transaction that decreases the storage size of the chain, a portion of the sender’s “deposit balance” proportional to the decrease in size is returned/freed. (Note that the “deposit balance” can never go below zero so it is not possible for a user to receive/free more tokens than they had ever deposited/reserved.)
This proposal addresses:
- Category C: Storage of data within a Smart Contract
- Optionally, Category B: Storage of a Smart Contract
It should be noted that it is compatible with MBIP-1, “Smart Contract Creation Deposit”.
This would impact many if not most users in some form or another. For example, a user would incur a deposit when first using any smart contract which records balances or other information related to their account. If extended to cover contract creation, then developers would also be impacted.
There are many similarities to MBIP-1:
- the deposit could either be debited from the overall account balance or, it could be “reserved” (ie. the deposit remains with the address but is not part of the transferable amount).
- the deposit would not be visible via the Ethereum RPC which may confuse users (it would not appear in EVM based Wallets or in Moonscan).
- a user could interact with a contract that generates a huge amount of storage causing the entire user balance being used for deposit.
- compatibility issues could be mitigated by incorporating the deposit into the “value” of the transaction but would require developers to take this into consideration
A variant of this solution would be to make the deposit dynamic such that for a given transaction, a higher deposit would be required when the rate of storage growth is high and lower deposit when the rate of growth decreases. However, this would need to be carefully thought through in order to discourage any attempts at gaming based on speculation the price will go up or down.
MBIP-2 Summary
- Storage Categories Addressed:
- Category C: Storage of data within a Smart Contract
- Optionally, Category B: Storage of a Smart Contract
- Cost to Grief Network: High
- Impact to Ethereum Compatibility: Medium
- Impact to User Experience: Medium
- Impact to Developer Experience: Medium
- MBIP-2 Draft Technical Specifications
MBIP-3: Smart Contract Rent Mechanism
Similar to MBIP-1, this solution proposes that a deposit would be required in order to deploy a Smart Contract and the deposit remains linked to the contract.
However, this deposit would essentially act as prepaid rent for contract storage (the contract itself and any data stored). Rental fees are charged at a set rate of GLMR per Byte per Year (or MOVR on Moonriver). Rent would be deducted from the deposit balance over time and the amount of rent due would vary according to the data stored in the Smart Contract. (The exact mechanics of this are explained in detail in the proposal specifications).
If the contract is called by a transaction but the rent deposit balance has been exhausted (ie. the contract has been deployed for longer than for which rent has been paid), the transaction would fail and the transaction would be reverted.
This mechanism has the advantage that, provided the rent is paid up, there’s no change in behavior for end users interacting with contracts. However, if/when there are failures, this could be confusing for end users.
However, App Developers would need to ensure that their rent is paid up and, depending on the implementation and/or use case, the rent could become prohibitively expensive over time.
Perhaps a clean up mechanism could be implemented whereby contracts that haven’t had rent paid for some long period of time are destroyed.
However, the implications of any such cleanup mechanism would require careful consideration since the contract may contain token balances, etc. There are also potential catastrophic risks associated with contracts being destroyed and re-created in a state where they could be subject to a replay attack (eg. a bridge contract).
MBIP-3 Summary
- Storage Categories Addressed:
- Category B: Storage of a Smart Contract
- Category C: Storage of data within a Smart Contract
- Cost to Grief Network: High
- Impact to Ethereum Compatibility: Medium
- Impact to User Experience: Low
- Impact to Developer Experience: High
- MBIP-3 Draft Technical Specifications
MBIP-4: Storage Base Fee
In this solution, “Storage Base Fee” is introduced (similar to the EIP-1559 idea of a “Base Fee”). The fee would be dynamic, computed at each block based on the previous change in storage size. The fee would be expressed in GWEI per byte (unit of storage).
The Storage Base Fee would be calculated based on the increase/decrease of storage from the previous block, and would be incorporated into the calculation of the Base Fee for the next block.
This proposal addresses:
- Category B: Storage of a Smart Contract
- Category C: Storage of data within a Smart Contract
- Optionally, Category A: Creation of a new account
In this model, the cost to execute a transaction becomes:
total cost = units of gas used * gas base fee + units of storage used * storage base fee
This solution has the advantage that there are no complexities involving deposits and for the most part, doesn’t stray very far in terms of Ethereum compatibility.
However, when a client makes an RPC call to get the base fee, only one value can be returned so the question is how to incorporate the storage base fee into the overall base fee returned.
There are a few options for computing the Base Fee returned by this RPC call. In the simplest case, you could just add the gas base fee and storage base fee together. However, this may lead to users overpaying for transactions by a relatively large amount.
Another approach could take into account an amount of bytes (units) of storage per block that the community feels is sustainable in the long term, target max storage. Thus, we can derive what should be considered a sustainable ratio of units of storage to units of gas - target storage to gas ratio.
The RPC call could then be made to multiply the storage base fee by this ratio before adding it to the gas base fee. Assuming a target max storage in the order of 50,000 bytes, the weight of the storage fee is greatly reduced and the base fee returned by the RPC server will be much closer to the expected gas fee.
The idea is that for transactions where the ratio of storage increase to gas use is relatively low, the value returned by the RPC call will be sufficient. However, if a given transaction has a relatively high ratio of storage to gas, the user may have to manually bump the gas price as the value returned by the RPC call will not be enough.
The actual value used for target max storage would require some study to strike a good balance.
MBIP-4 Summary
- Storage Categories Addressed:
- Category B: Storage of a Smart Contract
- Category C: Storage of data within a Smart Contract
- Optionally, Category A: Creation of a new account
- Cost to Grief Network: High
- Impact to Ethereum Compatibility: Low
- Impact to User Experience: Medium
- Impact to Developer Experience: Low
- MBIP-4 Draft Technical Specifications
MBIP-5: Gas-Based Storage Limit
In this solution, a transaction would consume additional gas based on the storage used. This will be reflected in the gas estimation call of the transaction, as returned by Moonbeam’s Ethereum JSON RPC.
This proposal addresses:
- Category B: Storage of a Smart Contract
- Category C: Storage of data within a Smart Contract
Similar to a variant of MBIP-4, the cost to execute a transaction incorporates the storage used and the community would decide upon an amount of bytes (units) of storage per block that the community feels is sustainable in the long term (target max storage) - perhaps something in the order of 40,000 bytes.
This value would be used to derive a healthy ratio of gas units to storage units per block, the target gas to storage ratio. (Note this is the inverse of the ratio in MBIP-4.)
In this model, the cost to execute a transaction becomes:
total cost = units of gas used * gas base fee + units of storage used * target gas to storage ratio
Also similar to MBIP-4, this solution has the advantage that there are no complexities involving deposits and for the most part, doesn’t stray very far in terms of Ethereum compatibility. The current implementation of Moonbeam’s Ethereum JSON RPC, and therefore, Ethereum tooling should work out of the box.
However, this could lead to blocks being considered full due to storage limits leading to under utilization from a computational perspective.
Additionally, this could cause problems for contracts that estimate gas to forward on to other contracts/function calls to fail as the contract developer may have already put fixed gas estimates into their contracts. For example, a call hardcoded in a smart contract like:
address(_address).call{gas: 1000000}(…)
MBIP-5 Summary
- Storage Categories Addressed:
- Category B: Storage of a Smart Contract
- Category C: Storage of data within a Smart Contract
- Cost to Grief Network: Very High
- Impact to Ethereum Compatibility: Low
- Impact to User Experience: Low
- Impact to Developer Experience: Low
- MBIP-5 Draft Technical Specifications
MBIP Comparison Chart
1- SC Creation Deposit | 2 - Data Storage Deposit | 3 - Storage Rent Mechanism | 4 - Storage Base Fee | 5 - Gas-Based Storage Limit | |
---|---|---|---|---|---|
A - Address Creation | No | No | No | Maybe | No |
B - Contract Code Storage | Yes | Maybe | Yes | Yes | Yes |
C -Contract Data Storage | No | Yes | Yes | Yes | Yes |
Cost to Grief Network | Very High | High | High | High | Very High |
Impact to Eth Compatibility | Med | Med | Med | Low | Low |
Impact to User Experience | Med | Med | Low | Med | Low |
Impact to Developer Experience | Med | Med | High | Low | Low |