Replies: 11 comments
-
It means that single-entrypoint programs cannot receive coins at all (they only have a
If an account is not spawned, we don't know its template yet and cannot tell whether it will have a |
Beta Was this translation helpful? Give feedback.
-
Yup. This is a safety thing. It's quite possible to write a template that becomes a "black hole" for incoming coins or other assets, i.e., there's no mechanism to ever move them out. Programs need to explicitly opt into receiving.
Yes, exactly. There's no way to prevent this, without blocking all transfers to stub accounts, which we don't want to do. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the explanations. The remaining question is whether this mechanism should be implemented in the VM or rather on the host side. WDYT? |
Beta Was this translation helpful? Give feedback.
-
Assuming by "this mechanism" that you mean specifically "reject inbound coin transfers to a single-entrypoint program", it's better if the host doesn't need to know the details of things like entrypoints, program type, etc. I think the cleanest way to do this is the following, let me know what you think:
|
Beta Was this translation helpful? Give feedback.
-
I'm not sure if we should allow accounts to decline incoming funds. I don't see how it's a "safety mechanism". If somebody sends funds to an account that cannot spend them (a "black hole") it's not any different from somebody sending coins to an address that doesn't exist (creating a stub in the process, but in this case spawn arguments that result in this address might not even exist). I don't see how burning coins by sending them to a "black hole" account is any different than burning them any other way. If we do want to prevent incoming funds in a consistent way, we can prevent incoming funds to stubs as well. We can do this by incorporating a raw bit into the address that indicates if the template used by this account allows incoming payments with no code or not. This will also make the But, again, I'm not sure allowing accounts to reject funds even makes sense. |
Beta Was this translation helpful? Give feedback.
-
I think there is a difference here. We cannot prevent funds being sent to stub/unspawned accounts, nor do we want to. In most cases these accounts are valid and will be spawned later. I think the risk is much greater once a "black hole" template has been spawned. Unless there's some form of upgradability, funds sent to such an address are necessarily lost forever. I see no reason to allow this. Why deviate from the EVM standard here? Also probably worth looking at what other systems do. |
Beta Was this translation helpful? Give feedback.
-
This isn't a "safety mechanism" preventing a user from intentionally sending funds to accounts that cannot spend them (e.g., a random unspawned address), but I see it could improve UX by preventing funds from being sent by mistake to accounts that we already know aren't meant to receive coins. |
Beta Was this translation helpful? Give feedback.
-
This is not a hill I will die on, but I see no benefit in this and it adds complexity. Funds can be burned, intentionally or not. We can build a foot-shooting prevention mechanism into the wallet - that is something I fully support.
We could have a whitelist of templates in the wallet, for which we verify their behavior:
But preventing this at the protocol level will create more edge cases and more unexpected behavior. E.g. what if a transaction sends funds into a stub and in the same block it's being spawned (and it doesn't have a receive address) - in this case the order of transactions has more impact than it must on the result of execution. If we have a reorg it can also have destabilizing cascading effects, where a spawn that makes it in or not can change a whole bunch of (possibly unrelated) transactions (i.e. transactions that are ineffective with the spawn suddenly become effective, emptying accounts and causing following transactions from the same accounts to suddenly fail). As I said, not a hill I would die on, but I just fail to see the benefit of limiting what people can do IN PROTOCOL. Having said that, I think it might be nice to have some signaling mechanism where templates can advertise their "intended use". So you can have some flag value that either explicitly says "please don't send naked funds (funds that are not part of a method call)" or the opposite, "naked funds are supported". Then it can be up to to the wallet to decide how to present this to the user and how hard to insist on no foot shooting (only send naked funds to accounts that explicitly say they accept them / allow sending naked funds to any account that doesn't explicitly say it doesn't want them / whatever). We should set the norm by using this signaling convention in our own templates and wallet, but I don't think this should be part of the protocol. |
Beta Was this translation helpful? Give feedback.
-
Thanks @noamnelke I'm convinced we don't need/want |
Beta Was this translation helpful? Give feedback.
-
I think the right next step here is to research prior art -- what does Solana do? What do the Move chains do? Etc. |
Beta Was this translation helpful? Give feedback.
-
I always think it's good to know what others are doing, however, we're not in the same situation and I don't want to fall into cargo-culting. Given our stub design and how reorgs work, I think it makes sense for us to apply user protections at the wallet-level, rather than protocol-level. I would actually have been for this approach regardless of our specific situation, but that just strengthens my case. |
Beta Was this translation helpful? Give feedback.
-
As in EVM, a template should be able to declare a
receive
method. The method cannot have any arguments and cannot have any return value. It should be executed whenever a program receives incoming coins with no calldata.If there is no
receive
method, but afallback
method exists (#203), that method should be called instead. If there's noreceive
and nofallback
method, a CALL or inbound tx with > 0 amount should fail.We may need a new macro for this, or else we may be able to update the existing
#[template]
and#[callable]
proc macros to do the additional work here (if they notice that the method name isreceive
).Clarification from #206: we still allow coins to be sent to a stub account, i.e., one that hasn't been spawned yet. This only applies to spawned accounts.
Beta Was this translation helpful? Give feedback.
All reactions