69 lines
2.1 KiB
Solidity
69 lines
2.1 KiB
Solidity
// SPDX-License-Identifier: Apache-2.0
|
|
pragma solidity >=0.8.0;
|
|
|
|
// Contract that always reverts in constructor
|
|
contract ChildRevert {
|
|
constructor() {
|
|
revert("ChildRevert: revert in constructor");
|
|
}
|
|
}
|
|
|
|
contract Caller {
|
|
function normal(address _callee, uint64 _value, bytes memory _data, uint64 _gas)
|
|
external
|
|
returns (bool success, bytes memory output)
|
|
{
|
|
(success, output) = _callee.call{value: _value, gas: _gas}(_data);
|
|
}
|
|
|
|
function delegate(address _callee, bytes memory _data, uint64 _gas)
|
|
external
|
|
returns (bool success, bytes memory output)
|
|
{
|
|
(success, output) = _callee.delegatecall{gas: _gas}(_data);
|
|
}
|
|
|
|
function staticCall(
|
|
// Don't rename to `static` (it's a Rust keyword).
|
|
address _callee,
|
|
bytes memory _data,
|
|
uint64 _gas
|
|
) external view returns (bool success, bytes memory output) {
|
|
(success, output) = _callee.staticcall{gas: _gas}(_data);
|
|
}
|
|
|
|
function create(bytes memory initcode) external payable returns (address addr) {
|
|
assembly {
|
|
// CREATE with no value
|
|
addr := create(0, add(initcode, 0x20), mload(initcode))
|
|
if iszero(addr) {
|
|
// bubble failure
|
|
let returnDataSize := returndatasize()
|
|
returndatacopy(0, 0, returnDataSize)
|
|
revert(0, returnDataSize)
|
|
}
|
|
}
|
|
}
|
|
|
|
function createRevert() external returns (address addr) {
|
|
try new ChildRevert() returns (ChildRevert c) {
|
|
addr = address(c);
|
|
} catch (bytes memory reason) {
|
|
revert(string(reason));
|
|
}
|
|
}
|
|
|
|
function create2(bytes memory initcode, bytes32 salt) external payable returns (address addr) {
|
|
assembly {
|
|
// CREATE2 with no value
|
|
addr := create2(0, add(initcode, 0x20), mload(initcode), salt)
|
|
if iszero(addr) {
|
|
// bubble failure
|
|
let returnDataSize := returndatasize()
|
|
returndatacopy(0, 0, returnDataSize)
|
|
revert(0, returnDataSize)
|
|
}
|
|
}
|
|
}
|
|
}
|