fip | title | discussions-to | author | status | type | created |
---|---|---|---|---|---|---|
0073 |
Remove beneficiary from the self_destruct syscall |
Steven Allen (@stebalien) |
Final |
Technical Core |
2023-08-29 |
Currently, actors can delete themselves and send away their funds (to another actor) in a single operation. Unfortunately, this doesn't behave exactly like a normal transfer of funds and introduces some complexity. We propose to simplify this "self destruct" mechanism by requiring users to send away any remaining funds first through a normal send, if desired.
Currently, the self::self_destruct(beneficiary)
syscall transfers funds to some designated beneficiary before deleting the actor. We propose to remove the beneficiary from this syscall. Instead, the user will be able to pass a boolean to specify if any remaining funds should be burnt, or if the self-destruct operation should fail if there are any remaining funds.
Unfortunately, self_destruct
transfers funds in a non-standard way. I.e., it doesn't send a message, it just implicitly transfers the funds. This means:
- This transfer won't show up in traces. This is fixable without a FIP, but adds some complexity to parsing traces.
- It won't automatically create the beneficiary, unlike a normal
send
(requires a FIP to fix). This is a foot-gun because it behaves differently from howsend
currently behaves. - If we ever decide to implement some mechanism whereby actors can execute code whenever they receive funds, this syscall, as currently implemented, could pose an issue. E.g., it might cause reentrency on self-destruct.
We could fix the first two issues instead of removing the beneficiary and there may be ways to work around the third issue. However, that would add unnecessary complexity. This complexity is unnecessary as there's already a way to transfer funds (the send
syscall).
Instead, this FIP proposed to fix this issue by reducing complexity: the self_destruct
syscall will be responsible for deleting the actor and that's it. Sending away funds will be the responsibility of the actor.
We replace the self_destruct(beneficiary: Address)
syscall with a self_destruct(burn: bool)
syscall. This syscall will:
- Check if the actor is executing in "read-only" mode. If so, the syscall will fail as it currently does.
- Check if there are remaining funds. If there are:
- If
burn
isfalse
, this syscall will fail with anIllegalOperation
error number (0x2). - If
burn
istrue
, the funds will be transferred to the burnt funds account (charging no additional gas).
- If
- Proceed to delete the actor.
There's no additional gas charge to burn funds as:
- We'll already charge to update the actor being deleted.
- We don't charge to update the burnt-funds actor per FIP-0057.
So any additional cost for burning funds is negligible.
We considered two potential implementations of self_destruct
:
- The first we considered was to always return an error when
self_destruct
is called and there are remaining unspent funds in the actor. - We also considered always burning funds.
We settled on a boolean flag because neither option is strictly superior. Passing a flag forces the user to make an explicit decision.
If we ever introduce account abstractions, accounts may want to "delete" themselves. It's unclear whether or not we even want to allow this however, if we do, we'll run into an issue: the account will be refunded for any unused gas after it has self-destructed. If a beneficiary is specified in self_destruct
, this is less of an issue as the unspent gas can simply be sent to said beneficiary.
However, I'm not particularly concerned about this for a few reasons:
- It's unclear whether or not we'll even allow this.
- This is already an issue even with the syscall as specified today as the beneficiary may self-destruct, leaving the FVM no place to send the refund from unused gas.
- Said refund will usually be negligible.
This FIP changes a syscall used by exactly one actor: the payment channel. Changing the payment channel actor to use the new syscall is trivial and already implemented in filecoin-project/builtin-actors#1362.
The implementation includes unit tests.
This FIP has negligible risk from a security standpoint.
This FIP has no impact on network incentives.
This FIP removes a potential foot-gun (self_destruct
not behaving like send
) and simplifies the FVM a bit.
- FVM: filecoin-project/ref-fvm#1838
- Builtin Actors: filecoin-project/builtin-actors#1362
Copyright and related rights waived via CC0.