Skip to content

Instantly share code, notes, and snippets.

@hosseinnedaee
Last active January 24, 2023 13:09
Show Gist options
  • Save hosseinnedaee/532120c3e645865514f7201c0d80370b to your computer and use it in GitHub Desktop.
Save hosseinnedaee/532120c3e645865514f7201c0d80370b to your computer and use it in GitHub Desktop.
5 different ways to create calldata for low-level calls

5 different ways to create calldata for low-level calls

inspired by jeancvllr article

// SPDX-LICENSE: UNLICENSED
pragma solidity ^0.8.0;

contract DeployedContract {
    uint public result = 0;

    function add(uint256 input) public {
        result = result + input;
    }
}

contract CallerContract {    
    DeployedContract deployed_contract;

    constructor(DeployedContract deployedContract_) {
        deployed_contract = deployedContract_;
    }

    // see examples below of different types
    // of low level call

}

1. Calldata by creating the bytes4 selector manually with keccak256 using abi.encodePacked

function callWithFunctionSignatureFromHash(uint256 input) public {
  bytes memory calldataPayload = abi.encodePacked(
    bytes4(keccak256("add(uint256)")),
    input
  );
  
  (bool success, ) = address(deployed_contract).call(calldataPayload);
}

2. Calldata using abi.encodeWithSignature

function callWithEncodeWithSignature(uint256 input) public {
  bytes memory calldataPayload = abi.encodeWithSignature("add(uint256)", input);
  (bool success, ) = address(deployed_contract).call(calldataPayload);
}

3. Calldata using abi.encodeWithSelector+bytes4 value

function callWithEncodeWithSelectorAsLiternal(uint256 input) public {
  bytes memory calldataPayload = abi.encodeWithSelector(0x1003e2d2, input);
  (bool success, ) = address(deployed_contract).call(calldataPayload);
}

4. Calldata using abi.encodeWithSelector+functionName.selector

function callWithEncodeWithSelectorAsReference(uint256 input) public {
  bytes memory calldataPayload = abi.encodeWithSelector(deployed_contract.add.selector, input);
  (bool success, ) = address(deployed_contract).call(calldataPayload);
}

5. Calldata using abi.encodeCall

function callWithABIEncodecCall(uint256 input) public {
  function (uint256) external functionToCall = deployed_contract.add;

  bytes memory calldataPayload = abi.encodeCall(functionToCall, input);
  (bool success, ) = address(deployed_contract).call(calldataPayload);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment