-
Notifications
You must be signed in to change notification settings - Fork 88
/
Copy pathBatch.sol
151 lines (125 loc) · 4.41 KB
/
Batch.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// SPDX-License-Identifier: MIT
pragma solidity 0.8.2;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts-0.8/utils/Address.sol";
contract Batch {
using Address for address;
struct Execution {
address target;
bytes callData;
}
struct ExecutionWithETH {
address target;
bytes callData;
uint256 value;
}
struct SingleTargetExecutionWithETH {
bytes callData;
uint256 value;
}
address public immutable executor;
constructor(address _executor) {
executor = _executor;
}
modifier onlyExecutor() {
require(msg.sender == executor, "NOT_AUTHORIZED");
_;
}
function atomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {
for (uint256 i = 0; i < executions.length; i++) {
executions[i].target.functionCallWithValue(executions[i].callData, executions[i].value);
}
}
function nonAtomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {
for (uint256 i = 0; i < executions.length; i++) {
_call(executions[i].target, executions[i].callData, executions[i].value);
}
}
function atomicBatch(Execution[] calldata executions) external onlyExecutor {
for (uint256 i = 0; i < executions.length; i++) {
executions[i].target.functionCall(executions[i].callData);
}
}
function nonAtomicBatch(Execution[] calldata executions) external onlyExecutor {
for (uint256 i = 0; i < executions.length; i++) {
_call(executions[i].target, executions[i].callData, 0);
}
}
function singleTargetAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)
external
payable
onlyExecutor
{
for (uint256 i = 0; i < executions.length; i++) {
target.functionCallWithValue(executions[i].callData, executions[i].value);
}
}
function singleTargetNonAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)
external
payable
onlyExecutor
{
for (uint256 i = 0; i < executions.length; i++) {
_call(target, executions[i].callData, executions[i].value);
}
}
function singleTargetAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {
for (uint256 i = 0; i < callDatas.length; i++) {
target.functionCall(callDatas[i]);
}
}
function singleTargetNonAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {
for (uint256 i = 0; i < callDatas.length; i++) {
_call(target, callDatas[i], 0);
}
}
function _call(
address target,
bytes calldata data,
uint256 value
) internal returns (bool) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = target.call{value: value}(data);
return success;
}
// ----------------------------------------------------------------------------------------------------
// TOKEN RECEPTION
// ----------------------------------------------------------------------------------------------------
// ERC1155
bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;
bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;
bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external pure returns (bytes4) {
return ERC1155_RECEIVED;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure returns (bytes4) {
return ERC1155_BATCH_RECEIVED;
}
// ERC721
bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;
bytes4 private constant ERC721_RECEIVED = 0x150b7a02;
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external pure returns (bytes4) {
return ERC721_RECEIVED;
}
// ERC165
function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {
return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;
}
}