Skip to content

Instantly share code, notes, and snippets.

@pcaversaccio
Last active February 8, 2023 15:15
Show Gist options
  • Save pcaversaccio/c6fea9f494ebe8f1dfec2ead63d60d46 to your computer and use it in GitHub Desktop.
Save pcaversaccio/c6fea9f494ebe8f1dfec2ead63d60d46 to your computer and use it in GitHub Desktop.
A contract that highlights the difference in behaviour between `CALL` and `DELEGATECALL` in relation to `tx.origin` and `msg.sender`.
// SPDX-License-Identifier: WTPFL
pragma solidity 0.8.18;
contract Called {
function callMe() external view returns (address) {
// solhint-disable-next-line avoid-tx-origin
assert(tx.origin == msg.sender);
return msg.sender;
}
}
contract Caller {
function makeCall(address contractAddr) public returns (address) {
/**
* @dev Will fail due to `assert(tx.origin == msg.sender)`.
*/
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returnData) = address(contractAddr).call(
abi.encodeWithSignature("callMe()")
);
require(success, "CALL FAILED");
address msgSender = abi.decode(returnData, (address));
return msgSender;
}
function makeDelegateCall(address contractAddr) public returns (address) {
/**
* @dev Will succeed due to `delegatecall`.
*/
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returnData) = address(contractAddr)
.delegatecall(abi.encodeWithSignature("callMe()"));
require(success, "DELEGATECALL FAILED");
address msgSender = abi.decode(returnData, (address));
return msgSender;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment