Open lrettig opened 3 weeks ago
@lrettig
If there's no receive and no fallback method, a CALL or inbound tx with > 0 amount should fail.
It means that single-entrypoint programs cannot receive coins at all (they only have a main()
). Is it intended?
Clarification from https://github.com/athenavm/athena/pull/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.
If an account is not spawned, we don't know its template yet and cannot tell whether it will have a receive()
method. It will be possible to send coins to a stub account until it is spawned. Then if it is spawned with a template that doesn't have receive()
, it will not be able to receive coins any more, right?
It means that single-entrypoint programs cannot receive coins at all (they only have a
main()
). Is it intended?
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.
If an account is not spawned, we don't know its template yet and cannot tell whether it will have a
receive()
method. It will be possible to send coins to a stub account until it is spawned. Then if it is spawned with a template that doesn't havereceive()
, it will not be able to receive coins any more, right?
Yes, exactly. There's no way to prevent this, without blocking all transfers to stub accounts, which we don't want to do.
Thanks for the explanations. The remaining question is whether this mechanism should be implemented in the VM or rather on the host side. WDYT?
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:
receive
(or fallback) method exists and reverts, or if no such method exists, this virtual method should indicate failure to the host, which should propagate that failure as a failed tx.
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.