-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathSimulateTxAccessor.sol
More file actions
52 lines (47 loc) · 1.68 KB
/
SimulateTxAccessor.sol
File metadata and controls
52 lines (47 loc) · 1.68 KB
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
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;
import "../base/Executor.sol";
/// @title Simulate Transaction Accessor - can be used with StorageAccessible to simulate Safe transactions
/// @author Richard Meissner - <richard@gnosis.pm>
contract SimulateTxAccessor is Executor {
address private immutable accessorSingleton;
constructor() {
accessorSingleton = address(this);
}
modifier onlyDelegateCall() {
require(address(this) != accessorSingleton, "SimulateTxAccessor should only be called via delegatecall");
_;
}
function simulate(
address to,
uint256 value,
bytes calldata data,
Enum.Operation operation
)
external
onlyDelegateCall()
returns (
uint256 estimate,
bool success,
bytes memory returnData
)
{
uint256 startGas = gasleft();
success = execute(to, value, data, operation, gasleft());
estimate = startGas - gasleft();
// solhint-disable-next-line no-inline-assembly
assembly {
// Load free memory location
let ptr := mload(0x40)
// We allocate memory for the return data by setting the free memory location to
// current free memory location + data size + 32 bytes for data size value
mstore(0x40, add(ptr, add(returndatasize(), 0x20)))
// Store the size
mstore(ptr, returndatasize())
// Store the data
returndatacopy(add(ptr, 0x20), 0, returndatasize())
// Point the return data to the correct memory location
returnData := ptr
}
}
}