DEV Community

Kristaps Grinbergs
Kristaps Grinbergs

Posted on

Mistery revealed about delegatecall in Solidity

This time we will talk about the critical lower-level function delegatecall. It is widely used in a proxy pattern, for instance, when using OpenZepplin upgrades pattern. Essentially this function executes code in another contract but uses data from the caller concept. Let's dig deeper and explore more.

Storage clash

When using delegatecall function, it is vital to note that state variables should be in the same order in both contracts. If it isn't, then bizarre things can happen. For instance, data will be overwritten.

Data labyrinth

Let's have a contract, Executor, that will save our lucky number, sender address, and Ether value sent to it.

pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Executor {
  uint256 public luckyNumber;
  address public sender;
  uint256 public value;

  function setLuckyNumber(uint256 _luckyNumber) public payable {
    luckyNumber = _luckyNumber;
    sender = msg.sender;
    value = msg.value;
  }
}
Enter fullscreen mode Exit fullscreen mode

Let's deploy the Executor contract and get the deployed address.

Deployed  raw `Executor` endraw  contract

After that, we can create the Caller smart contract.

Deploy  raw `Caller` endraw  contract

contract Caller {
  uint256 public luckyNumber;
  address public sender;
  uint256 public value;

  function setLuckyNumber(address executor, uint256 _luckyNumber) public payable {
    (bool success, bytes memory data) = executor.delegatecall(
      abi.encodeWithSignature("setLuckyNumber(uint256)", _luckyNumber)
    );

    console.log(success);
  }
}
Enter fullscreen mode Exit fullscreen mode

Now when we interact with the Caller contract and set the lucky number, we can see that data has been changed only in this contract, not in the Executor contract. To verify that, we can get the lucky number from both contracts.

Interaction with the  raw `Caller` endraw  and  raw `Executor` endraw  smart contracts

Potential vulnerability

Using the delegatecall function is a compelling feature in Solidity programming language. With great power comes great responsibility. It can be perilous when misused.

Two major vulnerability attacks are mistakes preserving caller context and storage layout mismatch. We won't go into details this time but will follow up on that in future posts.

TL;DR

The delegatecall is a lower-level function in Solidity programming language. It unlocks the possibility to interact from one smart contract with another by using the caller's context. When using delegatecall we should be super careful because misusing it can cause serious vulnerabilities.

Links

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay