Hasu just published “Transaction fee economics in NEAR”, reviewing few of the concepts that NEAR uses for charging transactions and doing contract rewards. Really appreciate diving in and thinking through the design. Let’s open conversation here.
There are two arguments in that article:
- Leaving out a “tip” for block producers will lead to off chain black markets
- Portion of the gas fee going to contracts would lead to negative consequences
Tip or no Tip
Let’s start with compensation of validators for their costs. Tip is not doing that.
In general, transaction fees are actually not doing that for the most part.
Validators in PoS must validate every block that was produced to themself be included in consensus and not getting kicked out. E.g. if someone produces a valid block - they need to extend computational resources and bandwidth to receive (and propagate to those who it’s unknown if they are sending their approvals to them). State storage is a bit separate and probably should be discussed in a separate article.
Validator that includes transaction into block originally has two things to consider:
- Very minimal cost of “including” transaction into block (e.g. ~100 bytes of bandwidth per transaction). But there is an opportunity cost of not including transaction as it burns the supply, however small that is it’s on the order of sending extra bytes over network.
- Nodes routing transactions to the validator detecting that validator is not including their transactions.
Note, NEAR doesn’t have mempool in normal sense, transactions are routed to the next few chunk producers in the respective shard. With ~1 second blocks and constant validator rotation transaction get routed pretty quickly to the validator that will include them. Given routing node knows where they are routing and observer produced blocks, they can detect if it wasn’t included. (Though this is not really implemented right now, but it is easy addition to keep track of “dropped” transactions on routing and having heuristics around that)
Let’s review few cases:
- Some subset of validators only accept transactions that were bribed, dropping others. This is where tip actually would make sense but it’s unclear why would validators do this as they have opportunity cost by not including transactions. Also as mentioned above - it is detectable and attributable (e.g. not like in PoW) and can be also punished on social level via community shifting delegations away from such validators.
- Validators include transactions that were paid off-chain first. Interestingly, given MEV in Etheruem right now - this is happening even with current gas auctions and can happened with EIP-1559 / tip because can be done via side-channeling. E.g. prices are been driven up by miner themself while they still front-run all the transactions themself. The way to fix this is actually to require specific order of transactions in the block. For example, they should be ordered randomly shuffled with random seed from previous block. This means that validator will have ~1 second to try to literally mine a transaction that would sort before an arbitrary transaction that they want to front-run.
Because NEAR was designed with dynamic resharding in mind, even though it’s expected that temporarily there can be congestion within current capacity due to spike in usage and hence gas price might adjust up - relatively soon there will be more capacity added by the network via resharding.
I think the main concern here is really spamming - if someone starts to spam network filling all the blocks with low value transactions - applications and users that have high value transactions want to get in.
Even though it’s a clearly a concern, let’s do back of envelope: initial price for 1Tgas is 0.0001 N. So one block is 0.1N at the minimum.
For those who need predictable capacity (vs extracting economic value due to timing) - there can be even better solution, where you can rent your own “shard” - e.g. some pre-determined gas limit shard on which only specific contract(s) operate and hence not be subject to congestion from other contracts. This is useful for oracles for example.
Now, we are adding EVM “vaults” (aka EVM shards), and for them dynamic resharding won’t work as all contracts inside one EVM shard are synchronous and need to live on the same shard. This means that adding tip for such transaction would make sense.
So why no tip in the first place, if it should work without it anyway?
Main reason has been that block producers can agree on side-channel repayment of the tip to always include some transactions at the top of the block. This is also directly leads to MEV, as block producers themself can include anything. This is possibly addressable by non-tip ordering of transaction but hasn’t been fully analyzed.
There are also possible attacks that is way easier to execute in PoS than in PoW where order is not deterministic, where block producers can execute on transactions with tips, by maintaining gas price at minimum by producing full block followed by empty block on repeat. Which means it will just degrade to a tip auction (and given tip is usually designed not proportional to gas). This also sounds like something that social consensus would prevent though.
Another consideration is that having two parameters that users and developers need to deal with increases complication of already something pretty complex like transaction fees in blockchains.
One of the major problems with blockchain development, is that protocols that are not directly dealing with value transfers are actually really hard to capture value if they are running on top of existing Layer-1. E.g. DeFi applications can charge fees from tokens that are transferred, but any applications that is not directly dealing with transfer of funds doesn’t have this ability.
Hence the reason why things like Cosmos and Polkadot actually make sense for subset of use cases - where starting your own chain is a way to create a fee capturing mechanism on top of the developers and investors.
There are now some data providing applications trying to also create a fee generation process on top of Ethereum, like NEST - where they would be charging for a call to their contract to fetch data. The problem is that reading data off chain and proving it on chain is not that expensive (it’s proving trie merkle path) which means there is maximum that such applications can charge and it’s priced in the gas spent and usability.
NEAR’s contract rewards just create a floor for such operations.
Frequent arguments are: it will lead to suboptimal gas usage, developers will fork and contract will pay it back to users.
Suboptimal gas usage: this is actually true short term for any contract on NEAR. Just because NEAR is so cheap, people are not going to be optimizing things in the beginning. And given our goal is to provide scale, I think optimizations will be more happening on the protocol side. Of cause if developers maliciously adds 10x in gas usage or in some other way spends extra - this will be known and given most of these contracts will be used by other developers it will lead to this contract not been used.
Developers will fork: this is true about Ethereum right now as well. If there is a way to fork something, it will be forked. Hence contract must have some moat: either branding, community, already usage, external data providers, internal liquidity, etc. And even with all that, it’s possible to fork, but it won’t be because of contract fees.
Contract will pay users back: This is actually great. That means that is economics that make sense for developers to do that. For example, if contract has an ownership (governance) token that is distributed among developers, investors and users. Contract can use these fees to buy-and-burn this token, hence providing value to everyone. This would actually match experience of building your application on Layer 1 to provide the community with sustainable way to capture fees while paying the rest of the fees to validators and token holders of NEAR for running compute / storing data.
Would love to see if there are any wrong arguments here.