-
Notifications
You must be signed in to change notification settings - Fork 2.6k
contracts: ReentranceDenied
shouldn't trap the caller but return an error code from seal_call
#11018
Comments
CC @athei |
My rationale was that basically any case of unintended re-entrancy would constitute an attack or at least a bug. This is why I opted to revert the call stack instead of returning an error. Do you think it there is a use case where you actually want to handle this error? |
Yep, for example: During the transfer of fungible tokens, the |
Why would you want to allow transfer of token when you get |
I agree with you that
The idea of the
|
I don't think it is sound to do that. As already discussed: You get exactly zero information whether tokens should be received or not. You should not do the transfer in this case. This is clearly a case where you want re-entrancy. So why not call |
Because that means that if I don't plan to implement It is the most common case. The problem is that if the contract doesn't implement |
If you want to send yourself tokens you know that you need to call the PSP22 contract with reentrancy enabled. I see no problem with that. If you don't do that you just have a bug in your contract that you will fix. Cause you know you should test contracts before deploying them to production. Not transferring the funds is a sound default for that kind of programming error.
But you can't know if |
The problem is that I don't plan to implement The idea of the issue is that this error can be handled by the caller contract and the caller decides how to process it. In most cases, it will be
Will be cool to pass |
Yeah we digressed a bit. I just had the feeling you intent to use that feature in an unsafe way. But I am not opposed to make this error non fatal.
I don't fully get what you mean. But shouldn't be discussed here. If you have a good idea there please open another issue where you explain it fully :) |
I describe it here because maybe it will cancel that issue. At the moment The The contract can call that method and decide by itself: panic, or not. It can be implemented in the ink! the same way as By default, reentrancy is not allowed(as payment for #[ink(message, payable, allow_reetrancy)]
pub fn deposit(&self) {
// ...
} |
It is essentially the question who controls the reentrancy. In both cases it is the contract which is in control (by specifying the call flags). Caller vs Callee: Right now we have a caller controlled restriction (you specify it on call). We can have of course both. Adding a |
If the callee contract controls the reentrancy -> |
Yeah I meant that "some contract" is in control. In that case it is the callee. Which is fine. We should support both cases. |
So, what is our final decision regarding that issue? For me, the most usable solution is:
Do we need to add something? If you want to have an additional way how to control it from the caller's side too(it is an additional way because the caller can use |
Why would we remove that? There might be reasons the caller want to disallow reentrancy.
No need to rename anything here. ink! can just pass |
ink! can, but it will increase the size of the contract because each cross-contract call will specify that flag. If we agree that the default way to handle reentry is on the callee side, then better to adapt the whole flow for that. It means that reentrancy is allowed on the
I think it is better to remove that because caller == callee in the scope of reentry. If it is expected reentry, then the developer should mark the function with I see only a small sense to have It is more clear for the developer. |
Sorry but I am not pushing user space functionality to the pallet in order to save setting one bit in a bitfield. Somewhere a line needs to be drawn.
This is not about pallet vs. contract. It is about caller vs. callee. The pallet merely enforces the callers decision of not setting There is a huge barrier to changing existing functionality because we need to be backwards compatible to existing contracts. If it is solvable in user space we solve it there. |
And it will not affect the size, I forgot that it is a bit=D
You are right. It can be changed on the ink! side. |
ReentranceDenied
in contract-pallet
is not critical errorReentranceDenied
shouldn't trap the caller but return an error code from seal_call
I described my reasoning for having this error being fatal in my first reply. This discussion didn't convince me that we want to change that. Rather we should to these things: |
At the moment if one of the sub-contract doesn't allow reentrance it throws a
ReentranceDenied
that breaks the execution of the full call stack.But it is the same level of error as
CalleeTrapped
. So we don't need to break all execution, we can returnCalleeReentranceDenied
and the caller can decide what to do with that error.The text was updated successfully, but these errors were encountered: