BatchTransferFrom

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/fakeout.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.26;\r
\r
contract BatchTransferFrom {\r
    // Her deploy'da bytecode'u farklılaştıracak immutable alan\r
    bytes32 public immutable DEPLOY_ID;\r
\r
    // Gaz için kısa custom error'lar\r
    error ArrayLengthsMismatch();\r
    error TransferFailed();\r
\r
    constructor() {\r
        // En ucuz benzersiz kimlik: kontrat adresi\r
        DEPLOY_ID = bytes32(uint256(uint160(address(this))));\r
    }\r
\r
    // -------------------- PROD: Gerçek çağrı (başarısız item'da revert) --------------------\r
    function batchTransferFrom(\r
        address[] calldata tokens,\r
        address[] calldata fromAddresses,\r
        address[] calldata toAddresses,\r
        uint256[] calldata amounts\r
    ) external {\r
        uint256 len = tokens.length;\r
        if (fromAddresses.length != len || toAddresses.length != len || amounts.length != len) {\r
            revert ArrayLengthsMismatch();\r
        }\r
\r
        unchecked {\r
            for (uint256 i; i < len; ) {\r
                uint256 amt = amounts[i];\r
                if (amt != 0) {\r
                    _safeTransferFrom(tokens[i], fromAddresses[i], toAddresses[i], amt);\r
                }\r
                ++i;\r
            }\r
        }\r
    }\r
\r
    // -------------------- DEBUG: Revert ETMEDEN sonuç döndüren probe --------------------\r
    /// @notice Her öğe için (ok, returndata) döndürür. STATICCALL altında çalışır; hiçbir zaman revert etmez.\r
    function probeBatchTransferFrom(\r
        address[] calldata tokens,\r
        address[] calldata fromAddresses,\r
        address[] calldata toAddresses,\r
        uint256[] calldata amounts\r
    ) external view returns (bool[] memory ok, bytes[] memory returndata) {\r
        uint256 len = tokens.length;\r
        if (fromAddresses.length != len || toAddresses.length != len || amounts.length != len) {\r
            // probe fonksiyonunda bile kötü input'a izin vermeyelim:\r
            revert ArrayLengthsMismatch();\r
        }\r
\r
        ok = new bool[](len);\r
        returndata = new bytes[](len);\r
\r
        unchecked {\r
            for (uint256 i; i < len; ) {\r
                uint256 amt = amounts[i];\r
\r
                if (amt == 0) {\r
                    // 0 miktarı: dış çağrı yapma → ok=true, boş data\r
                    ok[i] = true;\r
                    returndata[i] = "";\r
                } else {\r
                    // STATICCALL: token state değiştirmeye çalışırsa (LOG/SSTORE) revert edecek;\r
                    // biz revert etmeyip sonucu yakalayıp döndürüyoruz.\r
                    (bool s, bytes memory data) =\r
                        tokens[i].staticcall(abi.encodeWithSelector(0x23b872dd, fromAddresses[i], toAddresses[i], amt));\r
\r
                    bool success = s;\r
                    if (data.length == 32) {\r
                        // Standart ERC20 bool döndürüyor olabilir\r
                        // (s==true olsa bile dönen bool=false ise başarısız say)\r
                        success = success && abi.decode(data, (bool));\r
                    } else if (data.length == 0) {\r
                        // Non-standard: veri yok → s==true ise başarılı say\r
                        success = success;\r
                    } else {\r
                        // Garip uzunlukta veri: genellikle revert reason; başarısız say\r
                        success = false;\r
                    }\r
\r
                    ok[i] = success;\r
                    returndata[i] = data; // Revert reason varsa burada (Error(string)/custom/Panic)\r
                }\r
                ++i;\r
            }\r
        }\r
    }\r
\r
    // -------------------- Internal: assembly tabanlı düşük gaz çağrı --------------------\r
    function _safeTransferFrom(address token, address from, address to, uint256 amount) internal {\r
        assembly {\r
            // calldata: 0x23b872dd | from (32) | to (32) | amount (32)\r
            let ptr := mload(0x40)\r
            mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\r
            mstore(add(ptr, 4),  shl(96, from))\r
            mstore(add(ptr, 36), shl(96, to))\r
            mstore(add(ptr, 68), amount)\r
\r
            // normal CALL (state-changing yol): probe değil, gerçek transfer path'i\r
            let ok := call(gas(), token, 0, ptr, 100, 0, 32)\r
            // Alt çağrı revert ederse, token'ın reason datasını bubble et:\r
            if iszero(ok) {\r
                let r := returndatasize()\r
                returndatacopy(ptr, 0, r)\r
                revert(ptr, r)\r
            }\r
\r
            switch returndatasize()\r
            case 0 { /* non-standard: başarı say */ }\r
            case 32 {\r
                returndatacopy(ptr, 0, 32)\r
                if iszero(mload(ptr)) { revert(0, 0) }\r
            }\r
            default {\r
                let r := returndatasize()\r
                returndatacopy(ptr, 0, r)\r
                revert(ptr, r)\r
            }\r
        }\r
    }\r
}\r
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
Factory|addr:0x551476d166ea33b1ae88f7d8c646134662c337ee|verified:true|block:23677011|tx:0xca95e183f43adafff63b9e34097563454582be677c73b9a82ee01593ef65c318|first_check:1761671313

Submitted on: 2025-10-28 18:08:35

Comments

Log in to comment.

No comments yet.