2

I want to add a modifier to one of my function that checks wether the function call is a call or a delegatecall? Is there any way to figure that out? May be with some assembly?

1

1 Answer 1

3

Yes there is !It's actually a similar process that deployed libraries are using to ensure that they are not called directly, only through delegate call with some caveats.

What you want is :

  • Save your contract's address into it's code
  • When called, check if address(this) equals the value saved before.

You can easily do that with immutable variables :

The contract creation code generated by the compiler will modify the contract’s runtime code before it is returned by replacing all references to immutables by the values assigned to the them. This is important if you are comparing the runtime code generated by the compiler with the one actually stored in the blockchain.

In solidity you could write it that way :

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


contract Target {

  address immutable _this;

  constructor() {
    _this = address(this);
  }

  function isDelegate() public returns (bool) {
    if (address(this) == _this) {
      // This is a call address(this) is this contract
      // We are executing in our own context.
    }
    else {
      // This is a delegatecall address(this) is not this contract.
      // We are executing in another contract's context.
    }
  }
}

Do not go for alternatives as checking for a specific storage value, as they are 1) more costly and 2) unsafe.

I hope that answers your question.

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.