With dedicated msg.sender enabled, you can make use of its multi-call function batchExecuteCall
to execute multiple functions on different contracts.
function batchExecuteCall(
address[] calldata _targets,
bytes[] calldata _datas,
uint256[] calldata _values
) external payable override onlyAuth {
uint256 length = _targets.length;
require(
length == _datas.length && length == _values.length,
"OpsProxy: Length mismatch"
);
for (uint256 i; i < length; i++)
_executeCall(_targets[i], _datas[i], _values[i]);
}
To do so, you will need to create a task with your dedicated msg.sender
as the target contract address.
Get your dedicated msg.sender
Copy the address of your dedicated msg.sender
which can be found in the user drop-down.
Create a task calling your dedicated msg.sender
Paste the ABI below into the ABI field and select batchExecuteCall
as the function to be automated.
[{"inputs":[{"internalType":"address[]","name":"_targets","type":"address[]"},{"internalType":"bytes[]","name":"_datas","type":"bytes[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"batchExecuteCall","outputs":[],"stateMutability":"payable","type":"function"}]
You can either predefine the arguments or have a resolver return the data.
If you are using a resolver, you must return an ABI encoded payload of the batchExecuteCall
function.
Here is an example resolver that returns a payload that calls increaseCount
on 2 different contracts.
interface IOpsProxy {
function batchExecuteCall(
address[] calldata targets,
bytes[] calldata datas,
uint256[] calldata values
) external payable;
}
interface ICounter {
function increaseCount(uint256 _amount) external;
}
contract BatchExecCallResolver {
address public immutable counter1;
address public immutable counter2;
constructor(address _counter1, address _counter2){
counter1 = _counter1;
counter2 = _counter2;
}
function checker()
external
view
returns (bool canExec, bytes memory execPayload)
{
address[] memory targets = new address[](2);
targets[0] = counter1;
targets[1] = counter2;
bytes[] memory datas = new bytes[](2);
datas[0] = abi.encodeWithSelector(ICounter.increaseCount.selector, [1]);
datas[1] = abi.encodeWithSelector(ICounter.increaseCount.selector, [2]);
uint256[] memory values = new address[](2);
values[0] = 0;
values[1] = 0;
execPayload = abi.encodeWithSelector(
IOpsProxy.batchExecuteCall.selector,
[targets, datas, values]
);
return (true, execPayload);
}
}