Looking through the docs I found that a malicious caller can take the stack depth to ~1000 and then make a call which would fail due to stack depth. Based on that let's assume that stack indeed persists through calls.

So, is it possible that an entity can make a legit contract call their malicious contract and then use the SWAP16 opcode to manipulate the 15th stack value even though it was not meant to be accessible?

Like consider this

function sendEtherAndCall(address maliciousRecipient) external preventRentrant{
 uint someEther = balances[maliciousRecipient];
 balances[maliciousRecipient] = 0;
 bool success = maliciousRecipient.send(someEther);
 maliciousContract.call("Some function that uses SWAP 16");
 if(!success) balances[maliciousRecipient] = someValue; // Send failed

Is it possible to do this? Can the malicious contract use something like

PUSH false

Which makes the bool success as false even though it was successful? I just assumed that bottom 15th value would be the bool success. But is it possible?

1 Answer 1


No, it is not possible. The malicious recipient contract doesn't have access to the caller contract's stack.

There are two separate stacks: a local stack where variables are pushed and removed (accessible only to the contract instance being executed); a global call stack where the the calls are stored (it is not accessible to contract).

  • So the global EVM stack let's say has the per contract stack pushed onto it just as some local variable? So the bigger stack manages the per contract stack and prevents inter stack OPs?
    – Pranay
    Jan 25, 2022 at 5:53
  • The "global stack" doesn't exists as such, it is just a concept where calls between contracts are tracked. It doesn't contain anything else, its purpose is to enforce de 1024 call deep.
    – Ismael
    Jan 25, 2022 at 14:51
  • Okay. So, the scope of stack is the contract call and scope of memory is function call is that correct? And the said global watching stack’s scope is whole message call?
    – Pranay
    Jan 25, 2022 at 16:04
  • The "global stack" scope is the whole transaction execution. The "local stack" and memory have the same stock: the contract call.
    – Ismael
    Jan 25, 2022 at 19:47
  • Isn't memory wiped off between function calls? Like iirc memory is not accessible in between function calls right, not even internal calls?
    – Pranay
    Jan 26, 2022 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.