-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathHints.sol
64 lines (53 loc) · 1.97 KB
/
Hints.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
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.25;
import {StaticDelegateCallable} from "../common/StaticDelegateCallable.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
abstract contract Hints {
using Address for address;
address private immutable _SELF;
constructor() {
_SELF = address(this);
}
error ExternalCall();
modifier internalFunction() {
if (msg.sender != _SELF) {
revert ExternalCall();
}
_;
}
function _selfStaticDelegateCall(address target, bytes memory dataInternal) internal view returns (bytes memory) {
(, bytes memory returnDataInternal) =
target.staticcall(abi.encodeCall(StaticDelegateCallable.staticDelegateCall, (address(this), dataInternal)));
(bool success, bytes memory returnData) = abi.decode(returnDataInternal, (bool, bytes));
if (!success) {
if (returnData.length == 0) revert();
assembly {
revert(add(32, returnData), mload(returnData))
}
}
return returnData;
}
function _estimateGas(address target, bytes memory data) private view returns (uint256) {
uint256 gasLeft = gasleft();
target.functionStaticCall(data);
return gasLeft - gasleft();
}
function _optimizeHint(
address target,
bytes[] memory datas,
bytes[] memory hints
) internal view returns (bytes memory lowestHint) {
uint256 length = datas.length;
for (uint256 i; i < length; ++i) {
target.functionStaticCall(datas[i]);
}
uint256 lowestGas = type(uint256).max;
for (uint256 i; i < length; ++i) {
uint256 gasSpent = _estimateGas(target, datas[i]);
if (gasSpent < lowestGas || (gasSpent == lowestGas && datas[i].length < lowestHint.length)) {
lowestGas = gasSpent;
lowestHint = hints[i];
}
}
}
}