ETH Price: $2,553.64 (+0.76%)

Transaction Decoder

Block:
16249191 at Dec-23-2022 06:23:23 PM +UTC
Transaction Fee:
0.01306708 ETH $33.37
Gas Used:
502,580 Gas / 26 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x6a98d16E...Eb6fb2Be9
0.08199578 Eth
Nonce: 0
0 Eth
Nonce: 1
0.08199578From: 0 To: 3015969946573545740139396279804755990447083619333038993928590205728009611309921230868966714384368832870428212207671894499566809920482485735798903715655670095487168059251674721722630174039855204463467873088340063429644050861542492458747881543692318161232882631257533840856407657086604389028318530785422028456605067029800805231293354062985189108719552796633165631420598161489191988256901127302102866667748656364987607566020982236543380844395881324815984238600353529678683336510539846650167856966794686550526761637320684640826351220908855887104132148778866407847998828536505172429818402497840572386060937728383018861689450215309482339292288718035551216377072568636076248503085286392035622574298962505868881261982997540498310662480921504117579587993668158261519161618821760303740862158658511807640672325935728311384831492463556964834685123160949493842941554522359025411912429266334086170492290849941423416073121340751916313861100607332453873684869030980953243796545139229207551121692646034799365698510169475369827138165407743514003232621092003267444595376380563203645241998992365462435613688818348899843878958226771839675073610137561189843931308569898144206348539703894852526137877632135668683128778094415383596577630584296064008866170596456246495654816066742541864386680228370132176966177849199678842648044132667343517070603374376375851393982245054162507964526921915408240925912512560637367951728607054093927235492385087221203626902716203212021913237877653231566878369938824235752276420027110586001841936415937158294517657462736912136732666776878052667799511057565377358248511501538643872654342780723653372080744889690481150340541077891230256522832952711179960716932924945301373841316700154192245302855882459409784916688863634529650739993873158958217577413190173862219053586383511435264895200981278952584607407840806353180095103559152757239955505014455181379307890556408897504146843473742177214075611268683445540337593804414791787691737463535127537702100287540744219687208016223351071315121066845935154172058654947837252762717240062001533258426406534229465691194950718727131440706872322800799484380406833824968672196018886519738646025386552085383052057987701600672375404046980218903257533982733287857259874511421934577890733179590720681101240851275052973916701629827757781900102253045202984530648417444766926273960578050802290526909930490791471061225204528964168389708049731106076542080806828112510522328399396479630715472799469627396349425131914476095212074820214496021662395701038437877827416363377021745729663992365415204516156287916746133522003382285807204593150871764728103084757729508899248806107589425000500808082445734691730860609039272027822585717554587084784633865268943432515066160191774152201537574431687126941840574048059485755748419640639661060793562796140882188224546657729132736407648624583255112323650325097924527943829775136093164023918052618245911956825989003025734089131580541214817267970403751079746952362333248837414327098646496348827413871247954178144740642650139329878137680746318866568518248985433853334180388102198345636242610738570167370697910658688818389776831446253233973692981958121082176567239064898891710358687746187115672636333876440822957162483468376387507107540987384911704383246844431777369157162497944155393965918711254984381068050256493505581179401640138405048883802182141467867594850204546492401546346031604277533305349722922222457601488437701443702372849752151132761744692755924751911340013389740983242371802956229631758511225825081593432895841039708289780177949150149758080290959961898756861231563864749106285205620014787692667541595011133060592379107589791598952716332001755293501359870724051286755302865725895586694087346699788336617694549882303212214481483102875142769428885618379763980195306303132581614896882417241209865563288445759458625008682691240859808676574055062509685062725481911259034019473553848371707213019878100007460222318436526478915366825824573833446026322330618833029448222203663423900601917391968217719455669367119173447504483465913529144356381422106842998323268325682861778729136403022277653364516527974209404232132161231488999912153723076649172434551924914260314349497233211644512533114366399787642378650851918578946503070872680871104961611346148094160608973229618906634752669005586246248949776979973089646667354943561858918256137400250718886201772172759407324234058915521476295460767069292149606984443162662627200320440345842610392102198842178018461112958140249993381308267925177164993374788063060247801741490984135519909031842374136738655418375207012459090011532454677798816590635148288207857031496649354176692641229254787150633577312564787948828836291316355318144791953368046403190835
0x987E415C...0F0C16248
0.362633941362400147 Eth
Nonce: 415
0.431562641362400147 Eth
Nonce: 416
0.0689287
0xe39C37E7...22360875B
(eth-builder)
10.216029252799460864 Eth10.216932127044403664 Eth0.0009028742449428

Execution Trace

RecycleFactory.recycle( to=0x987E415CD0215924a1909DAB5cBEbB50F0C16248, uids=[1752228794708459705], erc20=[] )
  • 0x6a98d16e708d9411bafda2c6f5b4d94eb6fb2be9.60806040( )
  • 0x6a98d16e708d9411bafda2c6f5b4d94eb6fb2be9.19ab453c( )
  • 0x6a98d16e708d9411bafda2c6f5b4d94eb6fb2be9.724c6ddc( )
    • ETH 0.08199578 0x987e415cd0215924a1909dab5cbebb50f0c16248.CALL( )
      // File: @openzeppelin/[email protected]/utils/Create2.sol
      
      
      // OpenZeppelin Contracts v4.4.1 (utils/Create2.sol)
      
      pragma solidity ^0.8.0;
      
      /**
       * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
       * `CREATE2` can be used to compute in advance the address where a smart
       * contract will be deployed, which allows for interesting new mechanisms known
       * as 'counterfactual interactions'.
       *
       * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
       * information.
       */
      library Create2 {
          /**
           * @dev Deploys a contract using `CREATE2`. The address where the contract
           * will be deployed can be known in advance via {computeAddress}.
           *
           * The bytecode for a contract can be obtained from Solidity with
           * `type(contractName).creationCode`.
           *
           * Requirements:
           *
           * - `bytecode` must not be empty.
           * - `salt` must have not been used for `bytecode` already.
           * - the factory must have a balance of at least `amount`.
           * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
           */
          function deploy(
              uint256 amount,
              bytes32 salt,
              bytes memory bytecode
          ) internal returns (address) {
              address addr;
              require(address(this).balance >= amount, "Create2: insufficient balance");
              require(bytecode.length != 0, "Create2: bytecode length is zero");
              assembly {
                  addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
              }
              require(addr != address(0), "Create2: Failed on deploy");
              return addr;
          }
      
          /**
           * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
           * `bytecodeHash` or `salt` will result in a new destination address.
           */
          function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
              return computeAddress(salt, bytecodeHash, address(this));
          }
      
          /**
           * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
           * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
           */
          function computeAddress(
              bytes32 salt,
              bytes32 bytecodeHash,
              address deployer
          ) internal pure returns (address) {
              bytes32 _data = keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash));
              return address(uint160(uint256(_data)));
          }
      }
      
      // File: @openzeppelin/[email protected]/utils/Address.sol
      
      
      // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
      
      pragma solidity ^0.8.1;
      
      /**
       * @dev Collection of functions related to the address type
       */
      library Address {
          /**
           * @dev Returns true if `account` is a contract.
           *
           * [IMPORTANT]
           * ====
           * It is unsafe to assume that an address for which this function returns
           * false is an externally-owned account (EOA) and not a contract.
           *
           * Among others, `isContract` will return false for the following
           * types of addresses:
           *
           *  - an externally-owned account
           *  - a contract in construction
           *  - an address where a contract will be created
           *  - an address where a contract lived, but was destroyed
           * ====
           *
           * [IMPORTANT]
           * ====
           * You shouldn't rely on `isContract` to protect against flash loan attacks!
           *
           * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
           * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
           * constructor.
           * ====
           */
          function isContract(address account) internal view returns (bool) {
              // This method relies on extcodesize/address.code.length, which returns 0
              // for contracts in construction, since the code is only stored at the end
              // of the constructor execution.
      
              return account.code.length > 0;
          }
      
          /**
           * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
           * `recipient`, forwarding all available gas and reverting on errors.
           *
           * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
           * of certain opcodes, possibly making contracts go over the 2300 gas limit
           * imposed by `transfer`, making them unable to receive funds via
           * `transfer`. {sendValue} removes this limitation.
           *
           * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
           *
           * IMPORTANT: because control is transferred to `recipient`, care must be
           * taken to not create reentrancy vulnerabilities. Consider using
           * {ReentrancyGuard} or the
           * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
           */
          function sendValue(address payable recipient, uint256 amount) internal {
              require(address(this).balance >= amount, "Address: insufficient balance");
      
              (bool success, ) = recipient.call{value: amount}("");
              require(success, "Address: unable to send value, recipient may have reverted");
          }
      
          /**
           * @dev Performs a Solidity function call using a low level `call`. A
           * plain `call` is an unsafe replacement for a function call: use this
           * function instead.
           *
           * If `target` reverts with a revert reason, it is bubbled up by this
           * function (like regular Solidity function calls).
           *
           * Returns the raw returned data. To convert to the expected return value,
           * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
           *
           * Requirements:
           *
           * - `target` must be a contract.
           * - calling `target` with `data` must not revert.
           *
           * _Available since v3.1._
           */
          function functionCall(address target, bytes memory data) internal returns (bytes memory) {
              return functionCall(target, data, "Address: low-level call failed");
          }
      
          /**
           * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
           * `errorMessage` as a fallback revert reason when `target` reverts.
           *
           * _Available since v3.1._
           */
          function functionCall(
              address target,
              bytes memory data,
              string memory errorMessage
          ) internal returns (bytes memory) {
              return functionCallWithValue(target, data, 0, errorMessage);
          }
      
          /**
           * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
           * but also transferring `value` wei to `target`.
           *
           * Requirements:
           *
           * - the calling contract must have an ETH balance of at least `value`.
           * - the called Solidity function must be `payable`.
           *
           * _Available since v3.1._
           */
          function functionCallWithValue(
              address target,
              bytes memory data,
              uint256 value
          ) internal returns (bytes memory) {
              return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
          }
      
          /**
           * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
           * with `errorMessage` as a fallback revert reason when `target` reverts.
           *
           * _Available since v3.1._
           */
          function functionCallWithValue(
              address target,
              bytes memory data,
              uint256 value,
              string memory errorMessage
          ) internal returns (bytes memory) {
              require(address(this).balance >= value, "Address: insufficient balance for call");
              require(isContract(target), "Address: call to non-contract");
      
              (bool success, bytes memory returndata) = target.call{value: value}(data);
              return verifyCallResult(success, returndata, errorMessage);
          }
      
          /**
           * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
           * but performing a static call.
           *
           * _Available since v3.3._
           */
          function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
              return functionStaticCall(target, data, "Address: low-level static call failed");
          }
      
          /**
           * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
           * but performing a static call.
           *
           * _Available since v3.3._
           */
          function functionStaticCall(
              address target,
              bytes memory data,
              string memory errorMessage
          ) internal view returns (bytes memory) {
              require(isContract(target), "Address: static call to non-contract");
      
              (bool success, bytes memory returndata) = target.staticcall(data);
              return verifyCallResult(success, returndata, errorMessage);
          }
      
          /**
           * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
           * but performing a delegate call.
           *
           * _Available since v3.4._
           */
          function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
              return functionDelegateCall(target, data, "Address: low-level delegate call failed");
          }
      
          /**
           * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
           * but performing a delegate call.
           *
           * _Available since v3.4._
           */
          function functionDelegateCall(
              address target,
              bytes memory data,
              string memory errorMessage
          ) internal returns (bytes memory) {
              require(isContract(target), "Address: delegate call to non-contract");
      
              (bool success, bytes memory returndata) = target.delegatecall(data);
              return verifyCallResult(success, returndata, errorMessage);
          }
      
          /**
           * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
           * revert reason using the provided one.
           *
           * _Available since v4.3._
           */
          function verifyCallResult(
              bool success,
              bytes memory returndata,
              string memory errorMessage
          ) internal pure returns (bytes memory) {
              if (success) {
                  return returndata;
              } else {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
      
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert(errorMessage);
                  }
              }
          }
      }
      
      // File: @openzeppelin/[email protected]/security/ReentrancyGuard.sol
      
      
      // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
      
      pragma solidity ^0.8.0;
      
      /**
       * @dev Contract module that helps prevent reentrant calls to a function.
       *
       * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
       * available, which can be applied to functions to make sure there are no nested
       * (reentrant) calls to them.
       *
       * Note that because there is a single `nonReentrant` guard, functions marked as
       * `nonReentrant` may not call one another. This can be worked around by making
       * those functions `private`, and then adding `external` `nonReentrant` entry
       * points to them.
       *
       * TIP: If you would like to learn more about reentrancy and alternative ways
       * to protect against it, check out our blog post
       * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
       */
      abstract contract ReentrancyGuard {
          // Booleans are more expensive than uint256 or any type that takes up a full
          // word because each write operation emits an extra SLOAD to first read the
          // slot's contents, replace the bits taken up by the boolean, and then write
          // back. This is the compiler's defense against contract upgrades and
          // pointer aliasing, and it cannot be disabled.
      
          // The values being non-zero value makes deployment a bit more expensive,
          // but in exchange the refund on every call to nonReentrant will be lower in
          // amount. Since refunds are capped to a percentage of the total
          // transaction's gas, it is best to keep them low in cases like this one, to
          // increase the likelihood of the full refund coming into effect.
          uint256 private constant _NOT_ENTERED = 1;
          uint256 private constant _ENTERED = 2;
      
          uint256 private _status;
      
          constructor() {
              _status = _NOT_ENTERED;
          }
      
          /**
           * @dev Prevents a contract from calling itself, directly or indirectly.
           * Calling a `nonReentrant` function from another `nonReentrant`
           * function is not supported. It is possible to prevent this from happening
           * by making the `nonReentrant` function external, and making it call a
           * `private` function that does the actual work.
           */
          modifier nonReentrant() {
              // On the first call to nonReentrant, _notEntered will be true
              require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
      
              // Any calls to nonReentrant after this point will fail
              _status = _ENTERED;
      
              _;
      
              // By storing the original value once again, a refund is triggered (see
              // https://eips.ethereum.org/EIPS/eip-2200)
              _status = _NOT_ENTERED;
          }
      }
      
      // File: my/recycle.sol
      
      
      pragma solidity ^0.8.0;
      
      
      
      
      contract RecycleFactory is ReentrancyGuard {
          function recycle(address payable to,uint[] calldata uids, address[] calldata erc20) nonReentrant external {
              uint n=uids.length;
              for (uint i=0; i < n; i++) {
                  uint uid=uids[i];
                  address recycleContract = computeAddress(msg.sender,uid);
                  if(!Address.isContract(recycleContract)){
                      bytes32 salt = keccak256(abi.encode(msg.sender, uid));
                      bytes memory bytecode = type(Recycle).creationCode;
                      recycleContract=Create2.deploy(0,salt,bytecode);
                      Recycle(payable(recycleContract)).init(address(this));
                  }
                  Recycle(payable(recycleContract)).recycle(to,erc20);
              }
          }
      
          function computeAddress(address sender,uint uid) public view returns(address) {
              bytes32 salt = keccak256(abi.encode(sender, uid));
              bytes32 bytecodeHash = keccak256(type(Recycle).creationCode);
              return Create2.computeAddress(salt,bytecodeHash);
          }
      }
      
      contract Recycle is ReentrancyGuard {
          address public factory;
      
          function init(address _factory) external {
              require(factory==address(0),"Recycle: cannot init");
              factory=_factory;
          }
      
      
          function recycle(address payable recycler, address[] calldata erc20) external nonReentrant {
              require(msg.sender==factory,"Recycle: must factory");
              uint n=erc20.length;
              for (uint i; i < n; i++) {
                  RecyleHelper.transfer(erc20[i],recycler);
              }
              uint balance=address(this).balance;
              if(balance>0) {
                  recycler.transfer(balance);
              }
          }
      
          receive() external payable {
          }
      }
      
      library RecyleHelper {
          function transfer(address token, address to) internal returns (bool) {
              uint value = balanceOf(token);
              if (value > 0){
                  (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
                  return success && (data.length == 0 || abi.decode(data, (bool)));
              }
              return true;
          }
          
          function balanceOf(address token) internal returns (uint) {
              (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x70a08231, address(this)));
              if (!success || data.length == 0) return 0;
              return abi.decode(data, (uint));
          }
      }