Skip to content

Instantly share code, notes, and snippets.

@zeroknots
Last active November 10, 2023 04:30
Show Gist options
  • Save zeroknots/f2d456f4496ed4122646836d605d3743 to your computer and use it in GitHub Desktop.
Save zeroknots/f2d456f4496ed4122646836d605d3743 to your computer and use it in GitHub Desktop.
Comparison of Execution structs vs calldata arrays
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import "forge-std/Test.sol";
import "forge-std/console2.sol";
struct Execution {
// The target contract for account to execute.
address target;
// The value for the execution.
uint256 value;
// The call data for the execution.
bytes data;
}
contract Target {
uint256 value;
function set(uint256 _val) external {
value = _val;
}
}
contract ExecGasTest {
function executeSingle(address dest, uint256 value, bytes calldata func) external {
dest.call{value: value}(func);
console2.logBytes(msg.data);
}
function executeBatch(address[] calldata dest, uint256[] calldata value, bytes[] calldata func) external {
uint256 length = dest.length;
if (length == 0 || length != value.length || length != func.length) revert();
for (uint256 i; i < length; i++) {
dest[i].call{value: value[i]}(func[i]);
}
console2.logBytes(msg.data);
}
function execute6900(Execution calldata execution) external payable returns (bytes memory) {
execution.target.call{value: execution.value}(execution.data);
console2.logBytes(msg.data);
}
function executeBatch6900(Execution[] calldata executions) external payable returns (bytes[] memory) {
uint256 len = executions.length;
for (uint256 i; i < len; i++) {
executions[i].target.call{value: executions[i].value}(executions[i].data);
}
console2.logBytes(msg.data);
}
}
contract ExecFunctionGasTest is Test {
ExecGasTest execGasTest;
Target target;
function setUp() public {
execGasTest = new ExecGasTest();
target = new Target();
}
function testGas() public {
Execution memory execution =
Execution({target: address(target), value: 0, data: abi.encodeCall(Target.set, 1337)});
target.set(123);
execGasTest.execute6900(execution);
execGasTest.execute6900(execution);
execGasTest.executeSingle(execution.target, execution.value, execution.data);
execGasTest.executeSingle(execution.target, execution.value, execution.data);
Execution[] memory executions = new Execution[](4);
executions[0] = execution;
executions[1] = execution;
executions[2] = execution;
executions[3] = execution;
execGasTest.executeBatch6900(executions);
execGasTest.executeBatch6900(executions);
address[] memory dest = new address[](4);
uint256[] memory value = new uint256[](4);
bytes[] memory func = new bytes[](4);
for (uint256 i; i < 4; i++) {
dest[i] = execution.target;
value[i] = execution.value;
func[i] = execution.data;
}
execGasTest.executeBatch(dest, value, func);
execGasTest.executeBatch(dest, value, func);
}
}
| executeSingle | 2448 ✅
| execute6900 | 2825 🚨
| executeBatch | 8979 ✅
| executeBatch6900 | 9873 🚨
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment