Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Removing storage staking for base account information #415

Closed
ilblackdragon opened this issue Oct 13, 2022 · 30 comments
Closed

Comments

@ilblackdragon
Copy link
Member

ilblackdragon commented Oct 13, 2022

TLDR:

  • Allow to create accounts with 0 $NEAR balance.
  • This would unblock Meta Tx NEP and wallets to create named accounts without exploitation

Problem

Currently there is a blocker with #366 which spans from the problem that to initialize account that doesn't exist yet on the blockchain, one needs to deposit $NEAR into it prior to other actions happening.

Similar problem exist broadly for all account actions, where someone needs to deposit $NEAR into the account either via call to .near or via transfer to implicit address.

Historically we have been trying to allow people to create easily named accounts and were distributing some amount of $NEAR via wallet.near.org for newly created accounts. Due to ability for user to remove such account later, it led to a massive drain of the faucet by bots who would try to collect these free tokens.

New applications that are launching and want to initialize accounts for their users also face this issue. E.g. SweatCoin has been initializing accounts with $NEAR due to this and lack of meta transactions.

Context

Storage staking was designed for NEAR to have a sustainable storage economics. Observing Ethereum we saw continues growth in storage usage which didn't account in the economics.

Ethereum devs themself have been exploring other options of dealing with this, including storage rent. Early on we have implemented storage rent but it led to more issues due to all the tooling needing to understand continuously reducing amounts and impact on the user.

Storage staking was proposed as an alternative that also was designed to align economics of projects with broader NEAR economy. As projects grow and take more space on the blockchain they would need to lock more $NEAR tokens, reducing liquidity and amount available for staking in turn paying to validators.

Although it is still valid point, a deeper understanding of token economics lead to realization that growth of usage (and especially NEAR locked in various DeFi protocols or usage as a medium of exchange) benefits the protocol's economics way more than locking NEAR.

Observing the developers on NEAR, we also see two cases:

  • developers building correct storage staking model, which users don't appreciate and see as higher cost. E.g. Ref Finance requires users to deposit storage when they interact with application, but nobody ever released storage back, recovering the funds
  • developers forgo managing storage, having simplified codebase and just covering storage costs from their pocket (Aurora & Tonic), focusing on growing usage first.

Idea

The proposal here is to forgo storage costs of the account information.

Specifically:

  • CreateAccount would cost more and burn tokens for storage via gas
  • Storage amount is 0 after account is created, not requiring to have NEAR balance
  • DeleteAccount can be considered for deprecation, as it's not useful anymore

Considerations: should this only cover 1 key or allow to add more keys to the account? limit is needed as otherwise people would just store data in keys

Reasoning:

  • Dramatically simplifies account creation, including of named accounts.
  • There is cost of calling this action (tx fees) to prevent general spam in the network
  • Allows wallets to pay for named account creation by just paying tx fee and some basic Sybil resistance (like Captcha) as there is no economic incentive to attack it.
  • Addresses current blocker of the meta transactions with implicit accounts, as DelegatedAction can also create account as part of the action
  • Generally preferring growth vs correct charging unblocks ecosystem. NEAR is focused on sharding as an approach to address state growth.

Data

Account size: 100 bytes, minimum deposit required: 0.001Ⓝ

Current cost of account creation: 424 Ggas (0.00004 Ⓝ) and is equal to the cost of transferring NEAR.
This is true for both implicit account initialization with transfer and creation of new account with explicit CreateAccount + AddKey + Transfer action (which is strange).

If we want the same amount of $NEAR to be burnt in gas as minimum deposit, account creation would need to take ~10Tgas

Amazon S3 costs: $0.023 / GB / mo or $0.276e-9 / byte / year

Broader idea

Reconsider storage staking overall and replace with increased gas charges for writing new bytes (currently writing extra 1kb is very cheap compared to just doing a single write, while to have that 1kb you need to have 0.01N available).

Given NEAR is focused on sharding the state and cost of hard drives is reducing, economically this can leverage Arweave's logic around their model of permanent storage and cost formation for that.

@garikbesson
Copy link

I like the idea. Sounds reasonable

@Plufix
Copy link

Plufix commented Oct 13, 2022

The idea is very good, it will also make it easier for users of various projects to create wallets. Perhaps it is worth doing so :
When creating you can already actively receive any tokens and coins, but the first time you send it will already need to make a commission, which will make life even more easy for different projects.

@balaianu
Copy link

The idea is very good, it will also make it easier for users of various projects to create wallets. Perhaps it is worth doing so : When creating you can already actively receive any tokens and coins, but the first time you send it will already need to make a commission, which will make life even more easy for different projects.

I really like this proposal! The original idea is also very good, as it will indeed simplify a lot of things for projects, but having the tax postponed until the first TX allows for an even easier time and can have a good impact in raising adoption.

There can even be an "Activate sending/withdrawals" TX that users have to do in order to activate transferring any tokens out of their wallets, that will have the sole purpose of paying for the storage tax.

@soul-wish
Copy link

I really like this proposal. It can open the doors for NEAR adoption. Right now it is really hard to create user accounts for various projects in NEAR, because someone needs to pay for the storage, even if there is no need to call any additional transactions for such accounts at this time.
I hope that this change will not lead to some spam behaviour, when some people just try to get some "cool" names for their wallets in order to sell it to someone later. // most of such names are already taken 😉

@mfornet
Copy link
Member

mfornet commented Oct 13, 2022

DeleteAccount can be considered for deprecation, as it's not useful anymore

Delete Account will be relevant for factory contracts. For example in the case of near contract, if temporal.near is deleted, it can be re-claimed later by another party.

Allows wallets to pay for named account creation by just paying tx fee and some basic Sybil resistance (like Captcha) as there is no economic incentive to attack it.

Presumably, wallets will need to add a FullAccessKey during account creation. So they will need to pay $NEAR to cover the storage used by the key. In this case there will be similar friction and pervasive incentives as before.

@frol
Copy link
Collaborator

frol commented Oct 13, 2022

Given the massive impact, I want to invite the relevant working groups to this discussion. cc @near/wg-protocol @near/wg-wallet-standards

@flmel
Copy link
Member

flmel commented Oct 13, 2022

DeleteAccount can be considered for deprecation, as it's not useful anymore

Delete Account will be relevant for factory contracts. For example in the case of near contract, if temporal.near is deleted, it can be re-claimed later by another party.

Also there is no reliable way to remove the contract out of an account apart of deleting and recreating the account itself

@ilblackdragon
Copy link
Member Author

@mfornet

Presumably, wallets will need to add a FullAccessKey during account creation. So they will need to pay $NEAR to cover the storage used by the key. In this case there will be similar friction and pervasive incentives as before.

Correct and that is why there is "Consideration" section in the proposal, that suggests to cover either at least one key or possibly up to some number.

@zavodil
Copy link

zavodil commented Oct 13, 2022

Having account with no funds makes total sense for meta transactions.

I like the idea of replacing the initial storage with gas, as the attackers will not be able to restore burned gas after deleting the account. But it doesn't cover all use cases as @mfornet highlighted.
If Near native application onboards a new web2 user, app should deposit some NEAR to user account to maintain keys and cover gas for further txs. Malicious actors will delete keys and withdraw NEAR tokens.

Can we introduce something like a storage staking loan on a protocol level? The application covers some storage for the user and this deposit can be used on gas to call certain specified contracts only, the account cannot transfer NEAR if its balance became smaller than the loan. User can repay the loan, or we can treat every incoming NEAR transfer as a loan repayment.

@ilblackdragon
Copy link
Member Author

ilblackdragon commented Oct 13, 2022

The application covers some storage for the user and this deposit can be used on gas to call certain specified contracts only, the account cannot transfer NEAR if its balance became smaller than the loan.

I think meta transaction is better approach here. Application or relayers like Aurora Labs can submit and pay tx fees on user's behalf.

The loan for storage is also doesn't cover the cases where storage needs to be covered inside the applications or FT tokens. And the issue here is that these deposits are also user recoverable so can be grieved. Which is why also suggestion to stretch to remove need in storage deposits overall.

@balaianu
Copy link

The application covers some storage for the user and this deposit can be used on gas to call certain specified contracts only, the account cannot transfer NEAR if its balance became smaller than the loan.

I think meta transaction is better approach here. Application or relayers like Aurora Labs can submit and pay tx fees on user's behalf.

The loan for storage is also doesn't cover the cases where storage needs to be covered inside the applications or FT tokens. And the issue here is that these deposits are also user recoverable so can be grieved. Which is why also suggestion to stretch to remove need in storage deposits overall.

good point

@jefedeoro
Copy link

Could the seeding deposit be set up as a loan, that is auto repayed automatically from the initial deposit is made.
If the contract is deleted prior to repayment the seed funds returns to the predecessor_account_id?

to minimize bots claiming all the names possibly adding a pow-faucet.

@bowenwang1996
Copy link
Collaborator

This is a much better written proposal than what I did in #402 :)

should this only cover 1 key or allow to add more keys to the account? limit is needed as otherwise people would just store data in keys

It seems that we can limit it to a smaller number (such as 5) so that when a user needs to login from another device, they don't need to acquire NEAR tokens to pay for storage staking

@k3y0k3y
Copy link

k3y0k3y commented Oct 13, 2022

From a user onboarding perspective:
*App / Relayer makes an account for the User ------ frictionless onboarding
*App / Relayer can send the account FTs / NFTs paying the fees ----- enables crypto gated experiences
*App / Relayer can allow for user to create a named account paying the fees ------ enables social experiences
Open questions:
*App / Relayers are now the attack vector. There should be recommended security strategies on access keys.
*"Claiming" asset pages in apps will be bot attack vectors. There should be recommended anti-bot strategies like to use Captcha in their apps/pages.
*When a user wants to engage in "financial management" transferring/swapping how do we graduate them to a wallet? I think this is where injected wallet library comes in. Perhaps a transfer function of this account to a full wallet account?

@evgenykuzyakov
Copy link
Contributor

Faucet draining attacks are not prevented by this. But this change removes the incentive to drain faucets, because the attacker doesn't get the funds.

Maybe we can introduce a different change. Non-staked storage that is based on total burnt gas amount.

We introduce a new runtime method that allows a contract to burn prepaid gas for storage bytes. These storage bytes will forever be available on the account and only disappear if the account is deleted (no refunds).

The storage price can be something like 100Tgas = 1Kb.

Account creation now costs extra 28.2Tgas for 282bytes (account+fullaccesskey). The account can have 0 balance.

Contracts for ft_transfer needs 12.5Tgas for 125 bytes.

This change doesn't blow up the storage and applications that still want to manage storage may still do this with cheaper transactions.

@markoggwp
Copy link

developers forgo managing storage, having simplified codebase and just covering storage costs from their pocket (Aurora & Tonic), focusing on growing usage first.

Tonic v1 actually does have granular storage tracking but regret implementing it this way. Practically every DeFi contract will have NEAR deposits that are more than enough to cover storage costs.

In our case, implementing a one time fee upon account creation along with application level limits is the better solution. The USN contract is a classic case of ignoring storage altogether, which has the effect of improving the frontend developer experience since there is no need to check if a call to storage_deposit is required.

wrt to the proposal: agree with @k3y0k3y that this will improve the onboarding experience

@mattlockyer
Copy link
Contributor

Maybe we can introduce a different change. Non-staked storage that is based on total burnt gas amount.

We introduce a new runtime method that allows a contract to burn prepaid gas for storage bytes. These storage bytes will forever be available on the account and only disappear if the account is deleted (no refunds).

Second this, because applications will want to get creative with how they create accounts and how much base storage they have. For example, creating an account with several access keys or creating an account with a deployed contract that's pre-paid.

If we use an arbitrary base storage amount, we limit future use cases.

@evgenykuzyakov
Copy link
Contributor

Tonic v1 actually does have granular storage tracking but regret implementing it this way. Practically every DeFi contract will have NEAR deposits that are more than enough to cover storage costs.

Unless you work with wrap.near

@mohamedalichelbi
Copy link

  • DeleteAccount can be considered for deprecation, as it's not useful anymore

In addition to use cases mentioned by others, it's also a convenient way to wipe out old state before a contract upgrade.

Considerations: should this only cover 1 key or allow to add more keys to the account? limit is needed as otherwise people would just store data in keys

Doesn't this break the use case of developers distributing AccessKeys to users so users interact with NEAR without having an account?

@petersalomonsen
Copy link

petersalomonsen commented Oct 14, 2022

OK, so my current way of paying tx-fees for users is to create an implicit account, fund it with 0.25N for allowance, and create a function access key to my contract, and then I give away that function access key to the user (not the full access key to the implicit account). See https://twitter.com/salomonsen_p/status/1581020993539436545?s=20&t=NAYIBkj5osu0ZXGDQgXDQg and the reply for an example implementation.

With this proposal and #366 I will be able to create a named account for the user, and they can have a full access key to that. There's no need to fund that account because the tx fee for using my app could be covered by the meta transaction.

Have I got the correct understanding? In that case this would be great!

@vgrichina
Copy link

I think this proposal would work great if we also figure out a way to refer to WASM code by hash vs deploying it separately for every account.

In that case you would be able to create accounts for users that also have smart contract attached to them without extra storage staking. Enabling more use cases with user-owned web4 pages like https://vlad.near.page.

@vgrichina
Copy link

Given NEAR is focused on sharding the state and cost of hard drives is reducing, economically this can leverage Arweave's logic around their model of permanent storage and cost formation for that.

I think it's still good to have some motivation for developers to free up unused state. What would it be in the case that storage staking is completely removed?

@AngelBlock
Copy link

This will significantly reduce the account creation cost 0.02 -> 0.00004 or 500x. Consequences:

  • implicit account: none
  • named account: will allow to create named accounts 500 times cheaper and opens the opportunity to farm vanity addresses for future monetisation
  • statistics, metrics: can create false metrics for ecosystem as creating 20M new near addresses will only cost NEAR 800

Solution:

  • create a mechanism for creator to pay for named account.
  • adjusts statistics to show only active account.

In general one needs to weight benefits of mass adoption vs possible abuse.

DeleteAccount IMHO will still be useful, should one decided to release the name.near account and it can be recycled.

@ilblackdragon
Copy link
Member Author

I think it's still good to have some motivation for developers to free up unused state. What would it be in the case that storage staking is completely removed?

@vgrichina I agree in theory, but the issue we are observing is that even developers create such mechanisms - the users are the ones who at the end need to free the storage. I would like to collect more on-chain statistics but anecdotally I don't think it's happening outside of parties that create lots and lots of accounts on their users behalf. Partially this is due to lack of tooling for users (e.g. may be if there was a screen in the wallet showing that they have X $N spread across 20 apps and single button to free it)

Playing off @evgenykuzyakov suggestion, how about this idea:

  • "storage" units are introduced.
  • "storage" units included in the gas fee of the transaction, by default if storage_write is used - it charges the current storage_bytes * storage_price / current_gas_price of gas units and adds it to storage_used.
  • on storage_remove the freed up storage_price * storage_bytes is added to the predecessor's refund. A % can be returned here instead as well, to allow for overall cheaper storage fees.
  • when transactions are processed, the limits are enforced on how much compute gas has been spent by a transactions, not including what was subtracted for storage. E.g. transaction_gas_limit is compared with compute_gas_so_far.
  • overall valid transaction gas limits are increased while keeping transaction_gas_limit the same.
  • for account creation specifically, the storage_used is 0 after initial creation, removing ability to receive refund when just deleting account

Optionally, "storage_paid" can be added with extra APIs that allow to pay/free storage inside a contract vs just on transactional level.

This idea is about moving current storage staking into gas, due to complexity of the passing around and management of the $NEAR for storage staking.

With this reducing storage costs at least by 10 also would be important.
TBD on adding here some calculations around hardware costs.

@htafolla
Copy link

htafolla commented Oct 18, 2022

I don't understand the semantics fully on the technical level, however improving the user onboarding experience by 10+x is necessary for growth.

-- Creating accounts with gas fees and 3-5 keys + captcha sounds good
-- Burning NEAR for dedicated storage has many benefits
-- Storage "programs" that provide devs with "growing apps" storage grants following this model if possible

Will either introduce any scaling limits?

In terms of deleting accounts for state cleanup, there is a util Illia created for that, but maybe better tooling is still needed. Unless deleting a sub-account, it's very risky to delete a master and get it back. That could be an attack vector on projects by bots.

@JeffBissinger
Copy link

This proposal would address a major issue we are seeing when it comes to creating new wallets right now - contract exploits for non-custodial wallets are making it challenging to build experiences for new users. I see the tradeoff when it comes to abuse but think the metric rollup should account for wallets that have a level of activity outside of just created.

**I would be curious to see the data of wallets deleted and where those funds have been sent - what is the percentage of wallets today that have been created to then be deleted shortly after. And if there is a general network of wallets that are running these transactions.

@robert-zaremba
Copy link
Contributor

Using TX fees to cover storage deposits sounds the most natural solution and should be generalizable to all transactions. In other words, smart contract should be able to consume gas if storage is not provide, and use that gas to deposit for storage.

@jakmeier
Copy link
Contributor

jakmeier commented Nov 4, 2022

I just outlined an idea under the name Gas Weight in the governance forum. I believe it is relevant because if gas weights were implemented, it would be easy to convert gas to "storage units" without affecting gas limits. (We don't want the 1000 Tgas per chunk or 300 Tgas per transaction limit to be affected by gas spent on storage.)

@eriktrautman
Copy link

A quick fix for stopping the bleeding from third parties attacking account creation endpoints so they can delete/harvest accounts for their storage could be to send back the account creation storage tokens to whoever originally paid it when the account is deleted.

@ilblackdragon
Copy link
Member Author

Implemented and launched for 1 year

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests