Delegate Call in Smart Contract

Aman Agarwal
Nerd For Tech
Published in
3 min readJun 1, 2022

--

Some developers are wary of the term “delegate call” since it has been described as “hazardous.” Fear and danger arise from a lack of knowledge about how something works and how to utilize it securely. Most of us, for example, are not terrified to drive a car since we understand how it works and how to do so securely.
When a contract uses a delegate call to invoke a function, it loads and executes the function code from another contract as if it were it's own.

When a function is executed with a delegate call these values do not change:

  • address(this)
  • msg.sender
  • msg.value

The contract that loads and executes functions using delegate calls performs reads and writes to state variables. The contract that holds the retrieved functions is never subjected to reads or writes.

If ContractA utilizes a delegate call to call a function from ContractB, the following two statements are true:

  • ContractA’s state variables can be read and written.
  • ContractB’s state variables are never read or written.

ContractB’s functions can read and write values to state variables declared by both ContractA and ContractB. Only the state variables of ContractA are ever read or written.

delegatecall affects the state variables of the contract that calls a function with delegatecall. The state variables of the contract that holds the functions that are borrowed are not read or written.

Example

Let’s look at a basic example.
ContractA has the following:

  • address(this) == 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
  • The value of a state variable called “string tokenName” is “FunToken.”
  • An external method named ‘initialise()’ that uses delegatecall to call ContractB’s’setTokenName(string calldata _newName)’ function.

ContractB has the following clauses:

  • address(this) == 0x6b175474e89094c44da98b954eedeac495271d0f
  • The value of the state variable string “tokenName’ is “BoringToken.”
  • ‘setTokenName(string calldata _newName)’ is an external function that updates the ‘tokenName’ state variable to the ‘_newName’ value.

This is what occurs when the ‘initialise()’ function in ContractA is invoked with 2 ETH:

  1. These values are set:
  • address(this) == 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
  • msg.sender == 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B
  • msg.value == 2 ETH

2. Using a delegate call, the ‘initialise()’ method calls the ’setTokenName’ function in ContractB. When ’setTokenName’ is run, the following values are returned. They haven’t changed at all.

  • address(this) == 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
  • msg.sender == 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B
  • msg.value == 2 ETH

3. In ContractA, the value of the string ‘tokenName’ state variable is altered. Even if the code originates from ContractB, it is not changed in ContractB.

Solidity addresses feature a ‘delegate call’ method that allows you to make delegate calls. This method returns a boolean status variable that indicates whether or not the function call was reversed. The delegate call function returns a second value, which is the function call’s return value. See the example code above.

How To Use delegate call Safely

Now that you understand how delegate call works let’s look at how to use it safely.

1. Control what is executed with a delegate call

Untrusted code shouldn’t be run with a delegate call since it could change state variables or call “selfdestruct’ to destroy the calling contract. Delegate call functions and contracts can be specified or changed using permissions, authentication, or some other type of control.

2. Only call delegate calls on addresses that have code

If Delegatecall is called on an address that is not a contract and so has no code, it will return ‘True’ for the status value. If the code expects delegate call functions to return ‘False’ when they can’t run, this can lead to errors.

If you’re not sure whether an address variable will always retain an address with code when a delegate call is made on it, check that any address from the variable has code before calling it and revert if it doesn’t. Here’s an example of code that checks for code in an address:

Conclusion

So we learn about the delegate call in a smart contract, How to use it carefully, and how it can benefit us when we the usecase.

You can support me and my content by buying a coffee ☕ here.

Follow me on Twitter and LinkedIn.

Learn More

Contents distributed by Learn.Block6.tech

👉 Telegram — Fresh ideas

👉 Twitter — Latest articles

👉 LinkTr.ee

--

--

Aman Agarwal
Nerd For Tech

Engineer | Explorer | Blockchain | Golang | JavaScript developer