ETH Price: $2,520.83 (-5.17%)
Gas: 5.57 Gwei

Contract

0x77f33dA6046A03EBB0e6D33A26Cb49bD738774ff
 

Overview

ETH Balance

0.012195857 ETH

Eth Value

$30.74 (@ $2,520.83/ETH)

Token Holdings

Transaction Hash
Method
Block
From
To
Send Multi Sig T...209938682024-10-18 17:13:4713 days ago1729271627IN
FTX: Banruptcy Dust Collector
0 ETH0.0019837820.99976767
Send Multi Sig T...209878362024-10-17 21:00:5914 days ago1729198859IN
FTX: Banruptcy Dust Collector
0 ETH0.0011949914.14562774
Send Multi Sig T...209873242024-10-17 19:18:1114 days ago1729192691IN
FTX: Banruptcy Dust Collector
0 ETH0.0018227322.18762742
Send Multi Sig T...209808662024-10-16 21:39:4715 days ago1729114787IN
FTX: Banruptcy Dust Collector
0 ETH0.0011132412.47280043
Send Multi Sig T...209230812024-10-08 19:54:2323 days ago1728417263IN
FTX: Banruptcy Dust Collector
0 ETH0.0056050264.60458847
Send Multi Sig T...209222822024-10-08 17:13:2323 days ago1728407603IN
FTX: Banruptcy Dust Collector
0 ETH0.0043483641.99213319
Send Multi Sig T...209173722024-10-08 0:48:4723 days ago1728348527IN
FTX: Banruptcy Dust Collector
0 ETH0.0010390910.48994485
Send Multi Sig T...209173722024-10-08 0:48:4723 days ago1728348527IN
FTX: Banruptcy Dust Collector
0 ETH0.0011396110.48994485
Send Multi Sig T...208372182024-09-26 20:35:2335 days ago1727382923IN
FTX: Banruptcy Dust Collector
0 ETH0.0024226431.12458013
Send Multi Sig T...208320042024-09-26 3:09:3535 days ago1727320175IN
FTX: Banruptcy Dust Collector
0 ETH0.0018292218.34117373
Send Multi Sig T...206940952024-09-06 20:59:2355 days ago1725656363IN
FTX: Banruptcy Dust Collector
0 ETH0.0012421213.98980578
Send Multi Sig T...206857762024-09-05 17:07:5956 days ago1725556079IN
FTX: Banruptcy Dust Collector
0 ETH0.000503655.7220923
Send Multi Sig T...206714522024-09-03 17:09:4758 days ago1725383387IN
FTX: Banruptcy Dust Collector
0 ETH0.000244892.63905526
Send Multi Sig T...206439352024-08-30 20:59:1162 days ago1725051551IN
FTX: Banruptcy Dust Collector
0 ETH0.000101061.07990579
Send Multi Sig T...206230142024-08-27 22:49:1165 days ago1724798951IN
FTX: Banruptcy Dust Collector
0 ETH0.000388054.6790763
Send Multi Sig T...206198942024-08-27 12:22:4765 days ago1724761367IN
FTX: Banruptcy Dust Collector
0 ETH0.000202042.30301281
Send Multi Sig T...205926262024-08-23 16:54:4769 days ago1724432087IN
FTX: Banruptcy Dust Collector
0 ETH0.000184742.00829332
Send Multi Sig T...205868182024-08-22 21:24:5970 days ago1724361899IN
FTX: Banruptcy Dust Collector
0 ETH0.00032511.69530429
Send Multi Sig T...205868182024-08-22 21:24:5970 days ago1724361899IN
FTX: Banruptcy Dust Collector
0 ETH0.000131191.69530429
Send Multi Sig T...205856362024-08-22 17:28:1170 days ago1724347691IN
FTX: Banruptcy Dust Collector
0 ETH0.00024892.50795211
Send Multi Sig T...205856362024-08-22 17:28:1170 days ago1724347691IN
FTX: Banruptcy Dust Collector
0 ETH0.000494712.50795211
Send Multi Sig T...204291672024-07-31 21:18:2392 days ago1722460703IN
FTX: Banruptcy Dust Collector
0 ETH0.0010543211.51354034
Send Multi Sig T...204147432024-07-29 20:54:2394 days ago1722286463IN
FTX: Banruptcy Dust Collector
0 ETH0.000225542.83313111
Send Multi Sig T...204147432024-07-29 20:54:2394 days ago1722286463IN
FTX: Banruptcy Dust Collector
0 ETH0.000230232.83313111
Send Multi Sig T...203932432024-07-26 20:55:1197 days ago1722027311IN
FTX: Banruptcy Dust Collector
0 ETH0.000215122.5486237
View all transactions

Latest 16 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
198136702024-05-06 21:17:23178 days ago1715030243
FTX: Banruptcy Dust Collector
1,609.55057871 ETH
195205262024-03-26 18:57:47219 days ago1711479467
FTX: Banruptcy Dust Collector
1,350 ETH
194856842024-03-21 21:24:11224 days ago1711056251
FTX: Banruptcy Dust Collector
1,500 ETH
194238222024-03-13 4:39:11232 days ago1710304751
FTX: Banruptcy Dust Collector
14.81976728 ETH
194160172024-03-12 2:27:47233 days ago1710210467
FTX: Banruptcy Dust Collector
0.0027 ETH
192147892024-02-12 22:01:11262 days ago1707775271
FTX: Banruptcy Dust Collector
346.75570278 ETH
192059602024-02-11 16:18:23263 days ago1707668303
FTX: Banruptcy Dust Collector
0.04 ETH
191938342024-02-09 23:26:35264 days ago1707521195
FTX: Banruptcy Dust Collector
240.90716305 ETH
191919102024-02-09 16:58:23265 days ago1707497903
FTX: Banruptcy Dust Collector
0.004 ETH
187999762023-12-16 17:01:59320 days ago1702746119
FTX: Banruptcy Dust Collector
0.04610958 ETH
187654992023-12-11 20:59:47325 days ago1702328387
FTX: Banruptcy Dust Collector
0.1391888 ETH
184978252023-11-04 9:37:23362 days ago1699090643
FTX: Banruptcy Dust Collector
0.08293545 ETH
183453392023-10-14 1:26:59383 days ago1697246819
FTX: Banruptcy Dust Collector
608 ETH
183453392023-10-14 1:26:59383 days ago1697246819
FTX: Banruptcy Dust Collector
3,200 ETH
183453392023-10-14 1:26:59383 days ago1697246819
FTX: Banruptcy Dust Collector
608 ETH
159521362022-11-12 6:27:11719 days ago1668234431  Contract Creation0 ETH
Loading...
Loading

Minimal Proxy Contract for 0xe8e847cf573fc8ed75621660a36affd18c543d7e

Contract Name:
WalletSimple

Compiler Version
v0.7.5+commit.eb77ed08

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity Multiple files format)

File 1 of 4: WalletSimple.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.5;
import './TransferHelper.sol';
import './Forwarder.sol';
import './ERC20Interface.sol';

/**
 *
 * WalletSimple
 * ============
 *
 * Basic multi-signer wallet designed for use in a co-signing environment where 2 signatures are required to move funds.
 * Typically used in a 2-of-3 signing configuration. Uses ecrecover to allow for 2 signatures in a single transaction.
 *
 * The first signature is created on the operation hash (see Data Formats) and passed to sendMultiSig/sendMultiSigToken
 * The signer is determined by verifyMultiSig().
 *
 * The second signature is created by the submitter of the transaction and determined by msg.signer.
 *
 * Data Formats
 * ============
 *
 * The signature is created with ethereumjs-util.ecsign(operationHash).
 * Like the eth_sign RPC call, it packs the values as a 65-byte array of [r, s, v].
 * Unlike eth_sign, the message is not prefixed.
 *
 * The operationHash the result of keccak256(prefix, toAddress, value, data, expireTime).
 * For ether transactions, `prefix` is "ETHER".
 * For token transaction, `prefix` is "ERC20" and `data` is the tokenContractAddress.
 *
 *
 */
contract WalletSimple {
  // Events
  event Deposited(address from, uint256 value, bytes data);
  event SafeModeActivated(address msgSender);
  event Transacted(
    address msgSender, // Address of the sender of the message initiating the transaction
    address otherSigner, // Address of the signer (second signature) used to initiate the transaction
    bytes32 operation, // Operation hash (see Data Formats)
    address toAddress, // The address the transaction was sent to
    uint256 value, // Amount of Wei sent to the address
    bytes data // Data sent when invoking the transaction
  );

  event BatchTransfer(address sender, address recipient, uint256 value);
  // this event shows the other signer and the operation hash that they signed
  // specific batch transfer events are emitted in Batcher
  event BatchTransacted(
    address msgSender, // Address of the sender of the message initiating the transaction
    address otherSigner, // Address of the signer (second signature) used to initiate the transaction
    bytes32 operation // Operation hash (see Data Formats)
  );

  // Public fields
  mapping(address => bool) public signers; // The addresses that can co-sign transactions on the wallet
  bool public safeMode = false; // When active, wallet may only send to signer addresses
  bool public initialized = false; // True if the contract has been initialized

  // Internal fields
  uint256 private constant MAX_SEQUENCE_ID_INCREASE = 10000;
  uint256 constant SEQUENCE_ID_WINDOW_SIZE = 10;
  uint256[SEQUENCE_ID_WINDOW_SIZE] recentSequenceIds;

  /**
   * Set up a simple multi-sig wallet by specifying the signers allowed to be used on this wallet.
   * 2 signers will be required to send a transaction from this wallet.
   * Note: The sender is NOT automatically added to the list of signers.
   * Signers CANNOT be changed once they are set
   *
   * @param allowedSigners An array of signers on the wallet
   */
  function init(address[] calldata allowedSigners) external onlyUninitialized {
    require(allowedSigners.length == 3, 'Invalid number of signers');

    for (uint8 i = 0; i < allowedSigners.length; i++) {
      require(allowedSigners[i] != address(0), 'Invalid signer');
      signers[allowedSigners[i]] = true;
    }
    initialized = true;
  }

  /**
   * Get the network identifier that signers must sign over
   * This provides protection signatures being replayed on other chains
   * This must be a virtual function because chain-specific contracts will need
   *    to override with their own network ids. It also can't be a field
   *    to allow this contract to be used by proxy with delegatecall, which will
   *    not pick up on state variables
   */
  function getNetworkId() internal virtual pure returns (string memory) {
    return 'ETHER';
  }

  /**
   * Get the network identifier that signers must sign over for token transfers
   * This provides protection signatures being replayed on other chains
   * This must be a virtual function because chain-specific contracts will need
   *    to override with their own network ids. It also can't be a field
   *    to allow this contract to be used by proxy with delegatecall, which will
   *    not pick up on state variables
   */
  function getTokenNetworkId() internal virtual pure returns (string memory) {
    return 'ERC20';
  }

  /**
   * Get the network identifier that signers must sign over for batch transfers
   * This provides protection signatures being replayed on other chains
   * This must be a virtual function because chain-specific contracts will need
   *    to override with their own network ids. It also can't be a field
   *    to allow this contract to be used by proxy with delegatecall, which will
   *    not pick up on state variables
   */
  function getBatchNetworkId() internal virtual pure returns (string memory) {
    return 'ETHER-Batch';
  }

  /**
   * Determine if an address is a signer on this wallet
   * @param signer address to check
   * returns boolean indicating whether address is signer or not
   */
  function isSigner(address signer) public view returns (bool) {
    return signers[signer];
  }

  /**
   * Modifier that will execute internal code block only if the sender is an authorized signer on this wallet
   */
  modifier onlySigner {
    require(isSigner(msg.sender), 'Non-signer in onlySigner method');
    _;
  }

  /**
   * Modifier that will execute internal code block only if the contract has not been initialized yet
   */
  modifier onlyUninitialized {
    require(!initialized, 'Contract already initialized');
    _;
  }

  /**
   * Gets called when a transaction is received with data that does not match any other method
   */
  fallback() external payable {
    if (msg.value > 0) {
      // Fire deposited event if we are receiving funds
      Deposited(msg.sender, msg.value, msg.data);
    }
  }

  /**
   * Gets called when a transaction is received with ether and no data
   */
  receive() external payable {
    if (msg.value > 0) {
      // Fire deposited event if we are receiving funds
      Deposited(msg.sender, msg.value, msg.data);
    }
  }

  /**
   * Execute a multi-signature transaction from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
   * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
   *
   * @param toAddress the destination address to send an outgoing transaction
   * @param value the amount in Wei to be sent
   * @param data the data to send to the toAddress when invoking the transaction
   * @param expireTime the number of seconds since 1970 for which this transaction is valid
   * @param sequenceId the unique sequence id obtainable from getNextSequenceId
   * @param signature see Data Formats
   */
  function sendMultiSig(
    address toAddress,
    uint256 value,
    bytes calldata data,
    uint256 expireTime,
    uint256 sequenceId,
    bytes calldata signature
  ) external onlySigner {
    // Verify the other signer
    bytes32 operationHash = keccak256(
      abi.encodePacked(
        getNetworkId(),
        toAddress,
        value,
        data,
        expireTime,
        sequenceId
      )
    );

    address otherSigner = verifyMultiSig(
      toAddress,
      operationHash,
      signature,
      expireTime,
      sequenceId
    );

    // Success, send the transaction
    (bool success, ) = toAddress.call{ value: value }(data);
    require(success, 'Call execution failed');

    emit Transacted(
      msg.sender,
      otherSigner,
      operationHash,
      toAddress,
      value,
      data
    );
  }

  /**
   * Execute a batched multi-signature transaction from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
   * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
   * The recipients and values to send are encoded in two arrays, where for index i, recipients[i] will be sent values[i].
   *
   * @param recipients The list of recipients to send to
   * @param values The list of values to send to
   * @param expireTime the number of seconds since 1970 for which this transaction is valid
   * @param sequenceId the unique sequence id obtainable from getNextSequenceId
   * @param signature see Data Formats
   */
  function sendMultiSigBatch(
    address[] calldata recipients,
    uint256[] calldata values,
    uint256 expireTime,
    uint256 sequenceId,
    bytes calldata signature
  ) external onlySigner {
    require(recipients.length != 0, 'Not enough recipients');
    require(
      recipients.length == values.length,
      'Unequal recipients and values'
    );
    require(recipients.length < 256, 'Too many recipients, max 255');

    // Verify the other signer
    bytes32 operationHash = keccak256(
      abi.encodePacked(
        getBatchNetworkId(),
        recipients,
        values,
        expireTime,
        sequenceId
      )
    );

    // the first parameter (toAddress) is used to ensure transactions in safe mode only go to a signer
    // if in safe mode, we should use normal sendMultiSig to recover, so this check will always fail if in safe mode
    require(!safeMode, 'Batch in safe mode');
    address otherSigner = verifyMultiSig(
      address(0x0),
      operationHash,
      signature,
      expireTime,
      sequenceId
    );

    batchTransfer(recipients, values);
    emit BatchTransacted(msg.sender, otherSigner, operationHash);
  }

  /**
   * Transfer funds in a batch to each of recipients
   * @param recipients The list of recipients to send to
   * @param values The list of values to send to recipients.
   *  The recipient with index i in recipients array will be sent values[i].
   *  Thus, recipients and values must be the same length
   */
  function batchTransfer(
    address[] calldata recipients,
    uint256[] calldata values
  ) internal {
    for (uint256 i = 0; i < recipients.length; i++) {
      require(address(this).balance >= values[i], 'Insufficient funds');

      (bool success, ) = recipients[i].call{ value: values[i] }('');
      require(success, 'Call failed');

      emit BatchTransfer(msg.sender, recipients[i], values[i]);
    }
  }

  /**
   * Execute a multi-signature token transfer from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
   * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
   *
   * @param toAddress the destination address to send an outgoing transaction
   * @param value the amount in tokens to be sent
   * @param tokenContractAddress the address of the erc20 token contract
   * @param expireTime the number of seconds since 1970 for which this transaction is valid
   * @param sequenceId the unique sequence id obtainable from getNextSequenceId
   * @param signature see Data Formats
   */
  function sendMultiSigToken(
    address toAddress,
    uint256 value,
    address tokenContractAddress,
    uint256 expireTime,
    uint256 sequenceId,
    bytes calldata signature
  ) external onlySigner {
    // Verify the other signer
    bytes32 operationHash = keccak256(
      abi.encodePacked(
        getTokenNetworkId(),
        toAddress,
        value,
        tokenContractAddress,
        expireTime,
        sequenceId
      )
    );

    verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);

    TransferHelper.safeTransfer(tokenContractAddress, toAddress, value);
  }

  /**
   * Execute a token flush from one of the forwarder addresses. This transfer needs only a single signature and can be done by any signer
   *
   * @param forwarderAddress the address of the forwarder address to flush the tokens from
   * @param tokenContractAddress the address of the erc20 token contract
   */
  function flushForwarderTokens(
    address payable forwarderAddress,
    address tokenContractAddress
  ) external onlySigner {
    Forwarder forwarder = Forwarder(forwarderAddress);
    forwarder.flushTokens(tokenContractAddress);
  }

  /**
   * Do common multisig verification for both eth sends and erc20token transfers
   *
   * @param toAddress the destination address to send an outgoing transaction
   * @param operationHash see Data Formats
   * @param signature see Data Formats
   * @param expireTime the number of seconds since 1970 for which this transaction is valid
   * @param sequenceId the unique sequence id obtainable from getNextSequenceId
   * returns address that has created the signature
   */
  function verifyMultiSig(
    address toAddress,
    bytes32 operationHash,
    bytes calldata signature,
    uint256 expireTime,
    uint256 sequenceId
  ) private returns (address) {
    address otherSigner = recoverAddressFromSignature(operationHash, signature);

    // Verify if we are in safe mode. In safe mode, the wallet can only send to signers
    require(!safeMode || isSigner(toAddress), 'External transfer in safe mode');

    // Verify that the transaction has not expired
    require(expireTime >= block.timestamp, 'Transaction expired');

    // Try to insert the sequence ID. Will revert if the sequence id was invalid
    tryInsertSequenceId(sequenceId);

    require(isSigner(otherSigner), 'Invalid signer');

    require(otherSigner != msg.sender, 'Signers cannot be equal');

    return otherSigner;
  }

  /**
   * Irrevocably puts contract into safe mode. When in this mode, transactions may only be sent to signing addresses.
   */
  function activateSafeMode() external onlySigner {
    safeMode = true;
    SafeModeActivated(msg.sender);
  }

  /**
   * Gets signer's address using ecrecover
   * @param operationHash see Data Formats
   * @param signature see Data Formats
   * returns address recovered from the signature
   */
  function recoverAddressFromSignature(
    bytes32 operationHash,
    bytes memory signature
  ) private pure returns (address) {
    require(signature.length == 65, 'Invalid signature - wrong length');

    // We need to unpack the signature, which is given as an array of 65 bytes (like eth.sign)
    bytes32 r;
    bytes32 s;
    uint8 v;

    // solhint-disable-next-line
    assembly {
      r := mload(add(signature, 32))
      s := mload(add(signature, 64))
      v := and(mload(add(signature, 65)), 255)
    }
    if (v < 27) {
      v += 27; // Ethereum versions are 27 or 28 as opposed to 0 or 1 which is submitted by some signing libs
    }

    // protect against signature malleability
    // S value must be in the lower half orader
    // reference: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/051d340171a93a3d401aaaea46b4b62fa81e5d7c/contracts/cryptography/ECDSA.sol#L53
    require(
      uint256(s) <=
        0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
      "ECDSA: invalid signature 's' value"
    );

    // note that this returns 0 if the signature is invalid
    // Since 0x0 can never be a signer, when the recovered signer address
    // is checked against our signer list, that 0x0 will cause an invalid signer failure
    return ecrecover(operationHash, v, r, s);
  }

  /**
   * Verify that the sequence id has not been used before and inserts it. Throws if the sequence ID was not accepted.
   * We collect a window of up to 10 recent sequence ids, and allow any sequence id that is not in the window and
   * greater than the minimum element in the window.
   * @param sequenceId to insert into array of stored ids
   */
  function tryInsertSequenceId(uint256 sequenceId) private onlySigner {
    // Keep a pointer to the lowest value element in the window
    uint256 lowestValueIndex = 0;
    // fetch recentSequenceIds into memory for function context to avoid unnecessary sloads
    uint256[SEQUENCE_ID_WINDOW_SIZE] memory _recentSequenceIds = recentSequenceIds;
    for (uint256 i = 0; i < SEQUENCE_ID_WINDOW_SIZE; i++) {
      require(_recentSequenceIds[i] != sequenceId, 'Sequence ID already used');

      if (_recentSequenceIds[i] < _recentSequenceIds[lowestValueIndex]) {
        lowestValueIndex = i;
      }
    }

    // The sequence ID being used is lower than the lowest value in the window
    // so we cannot accept it as it may have been used before
    require(
      sequenceId > _recentSequenceIds[lowestValueIndex],
      'Sequence ID below window'
    );

    // Block sequence IDs which are much higher than the lowest value
    // This prevents people blocking the contract by using very large sequence IDs quickly
    require(
      sequenceId <=
        (_recentSequenceIds[lowestValueIndex] + MAX_SEQUENCE_ID_INCREASE),
      'Sequence ID above maximum'
    );

    recentSequenceIds[lowestValueIndex] = sequenceId;
  }

  /**
   * Gets the next available sequence ID for signing when using executeAndConfirm
   * returns the sequenceId one higher than the highest currently stored
   */
  function getNextSequenceId() public view returns (uint256) {
    uint256 highestSequenceId = 0;
    for (uint256 i = 0; i < SEQUENCE_ID_WINDOW_SIZE; i++) {
      if (recentSequenceIds[i] > highestSequenceId) {
        highestSequenceId = recentSequenceIds[i];
      }
    }
    return highestSequenceId + 1;
  }
}

File 2 of 4: ERC20Interface.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.5;

/**
 * Contract that exposes the needed erc20 token functions
 */

abstract contract ERC20Interface {
  // Send _value amount of tokens to address _to
  function transfer(address _to, uint256 _value)
    public
    virtual
    returns (bool success);

  // Get the account balance of another account with address _owner
  function balanceOf(address _owner)
    public
    virtual
    view
    returns (uint256 balance);
}

File 3 of 4: Forwarder.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.5;
import './TransferHelper.sol';
import './ERC20Interface.sol';

/**
 * Contract that will forward any incoming Ether to the creator of the contract
 *
 */
contract Forwarder {
  // Address to which any funds sent to this contract will be forwarded
  address public parentAddress;
  event ForwarderDeposited(address from, uint256 value, bytes data);

  /**
   * Initialize the contract, and sets the destination address to that of the creator
   */
  function init(address _parentAddress) external onlyUninitialized {
    parentAddress = _parentAddress;
    uint256 value = address(this).balance;

    if (value == 0) {
      return;
    }

    (bool success, ) = parentAddress.call{ value: value }('');
    require(success, 'Flush failed');
    // NOTE: since we are forwarding on initialization,
    // we don't have the context of the original sender.
    // We still emit an event about the forwarding but set
    // the sender to the forwarder itself
    emit ForwarderDeposited(address(this), value, msg.data);
  }

  /**
   * Modifier that will execute internal code block only if the sender is the parent address
   */
  modifier onlyParent {
    require(msg.sender == parentAddress, 'Only Parent');
    _;
  }

  /**
   * Modifier that will execute internal code block only if the contract has not been initialized yet
   */
  modifier onlyUninitialized {
    require(parentAddress == address(0x0), 'Already initialized');
    _;
  }

  /**
   * Default function; Gets called when data is sent but does not match any other function
   */
  fallback() external payable {
    flush();
  }

  /**
   * Default function; Gets called when Ether is deposited with no data, and forwards it to the parent address
   */
  receive() external payable {
    flush();
  }

  /**
   * Execute a token transfer of the full balance from the forwarder token to the parent address
   * @param tokenContractAddress the address of the erc20 token contract
   */
  function flushTokens(address tokenContractAddress) external onlyParent {
    ERC20Interface instance = ERC20Interface(tokenContractAddress);
    address forwarderAddress = address(this);
    uint256 forwarderBalance = instance.balanceOf(forwarderAddress);
    if (forwarderBalance == 0) {
      return;
    }

    TransferHelper.safeTransfer(
      tokenContractAddress,
      parentAddress,
      forwarderBalance
    );
  }

  /**
   * Flush the entire balance of the contract to the parent address.
   */
  function flush() public {
    uint256 value = address(this).balance;

    if (value == 0) {
      return;
    }

    (bool success, ) = parentAddress.call{ value: value }('');
    require(success, 'Flush failed');
    emit ForwarderDeposited(msg.sender, value, msg.data);
  }
}

File 4 of 4: TransferHelper.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity >=0.7.5;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            'TransferHelper::safeApprove: approve failed'
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            'TransferHelper::safeTransfer: transfer failed'
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            'TransferHelper::transferFrom: transferFrom failed'
        );
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');
    }
}

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"msgSender","type":"address"},{"indexed":false,"internalType":"address","name":"otherSigner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"operation","type":"bytes32"}],"name":"BatchTransacted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"BatchTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"msgSender","type":"address"}],"name":"SafeModeActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"msgSender","type":"address"},{"indexed":false,"internalType":"address","name":"otherSigner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"operation","type":"bytes32"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Transacted","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"activateSafeMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"forwarderAddress","type":"address"},{"internalType":"address","name":"tokenContractAddress","type":"address"}],"name":"flushForwarderTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getNextSequenceId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"allowedSigners","type":"address[]"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safeMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"uint256","name":"sequenceId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"sendMultiSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"uint256","name":"sequenceId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"sendMultiSigBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"tokenContractAddress","type":"address"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"uint256","name":"sequenceId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"sendMultiSigToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"signers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

 Latest 13 blocks produced

Block Transaction Difficulty Gas Used Reward
194183662024-03-12 10:21:23233 days ago17102388831570.00 TH13,358,167 (44.53%)
0.018466839240776737 ETH
193925352024-03-08 19:28:11237 days ago17099260912210.00 TH15,650,267 (52.17%)
0.032512132381185165 ETH
192695122024-02-20 14:29:59254 days ago17084393991370.00 TH12,868,566 (42.90%)
0.094895528517510182 ETH
192146802024-02-12 21:39:23262 days ago17077739631250.00 TH10,814,582 (36.05%)
0.320511300889581629 ETH
188138562023-12-18 15:47:11318 days ago17029144311780.00 TH12,824,696 (42.75%)
0.067895759099496156 ETH
187999762023-12-16 17:01:59320 days ago17027461191810.00 TH11,138,571 (37.13%)
0.033795036065531447 ETH
187854142023-12-14 15:57:35322 days ago17025694552440.00 TH12,847,846 (42.83%)
0.019418358759924961 ETH
187732732023-12-12 23:06:59324 days ago17024224191050.00 TH11,503,146 (38.34%)
0.037956715290180652 ETH
186478172023-11-25 9:28:23341 days ago1700904503920.00 TH9,731,787 (32.44%)
0.11449200331825522 ETH
186086742023-11-19 21:56:59347 days ago17004310191430.00 TH25,823,054 (86.08%)
0.042484299562733141 ETH
185905672023-11-17 9:00:35349 days ago17002116351650.00 TH11,506,643 (38.36%)
0.015336935810233567 ETH
185728322023-11-14 21:29:35352 days ago16999973751150.00 TH8,318,586 (27.73%)
0.020685404698802459 ETH
184816582023-11-02 3:13:59364 days ago16988948391130.00 TH14,905,281 (49.68%)
0.055392296516534082 ETH

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Latest 25 from a total of 2936 withdrawals (4,472.818485205 ETH withdrawn)

Validator Index Block Amount
973649195306092024-03-28 5:45:11217 days ago171160471132.00213246 ETH
973646195306092024-03-28 5:45:11217 days ago171160471132.00213241 ETH
973642195306092024-03-28 5:45:11217 days ago171160471132.002129957 ETH
973640195306092024-03-28 5:45:11217 days ago171160471132.00213722 ETH
973636195306092024-03-28 5:45:11217 days ago171160471132.002136703 ETH
973635195306092024-03-28 5:45:11217 days ago171160471132.002130016 ETH
973631195306092024-03-28 5:45:11217 days ago171160471132.002129456 ETH
973630195306092024-03-28 5:45:11217 days ago171160471132.002124573 ETH
973629195306092024-03-28 5:45:11217 days ago171160471132.002139516 ETH
973628195306092024-03-28 5:45:11217 days ago171160471132.002113328 ETH
973627195306092024-03-28 5:45:11217 days ago171160471132.002143506 ETH
973623195306092024-03-28 5:45:11217 days ago171160471132.00212198 ETH
973621195306092024-03-28 5:45:11217 days ago171160471132.002110896 ETH
973620195306092024-03-28 5:45:11217 days ago171160471132.002113319 ETH
973614195306092024-03-28 5:45:11217 days ago171160471132.002127043 ETH
973613195306082024-03-28 5:44:59217 days ago171160469932.002112836 ETH
973612195306082024-03-28 5:44:59217 days ago171160469932.002136536 ETH
973611195306082024-03-28 5:44:59217 days ago171160469932.002112963 ETH
973610195306082024-03-28 5:44:59217 days ago171160469932.002117493 ETH
973608195306082024-03-28 5:44:59217 days ago171160469932.00213643 ETH
973605195306082024-03-28 5:44:59217 days ago171160469932.00213888 ETH
973596195306082024-03-28 5:44:59217 days ago171160469932.002136552 ETH
973592195306082024-03-28 5:44:59217 days ago171160469932.002136422 ETH
973586195306082024-03-28 5:44:59217 days ago171160469932.002122289 ETH
973585195306082024-03-28 5:44:59217 days ago171160469932.002126681 ETH
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Chain Token Portfolio % Price Amount Value
ETH98.30%$1.7511,661,642.548$20,407,874.46
ETH0.24%$0.0232682,163,241.2166$50,334.75
ETH0.20%$0.99936341,047.21$41,021.06
ETH0.15%$0.0211691,508,064.5161$31,924.43
ETH0.13%$126,697.5543$26,777.65
ETH0.11%$2,748.038.2599$22,698.52
ETH0.09%$0.024124773,623.6241$18,663.19
ETH0.08%$1.115,661.5471$17,227.7
ETH0.08%$117,157.6554$17,209.13
ETH0.06%$0.59109722,415.744$13,249.88
ETH0.05%$0.39549725,974.6949$10,272.91
ETH0.05%<$0.00000169,877,509,844.2496$9,600.82
ETH0.04%$0.000018477,688,208.4814$8,541.07
ETH0.03%$58.85110.2647$6,489.08
ETH0.03%$10.55524.4702$5,533.16
ETH0.02%$3.511,090.542$3,827.8
ETH0.02%$0.00001370,721,122.0268$3,719.63
ETH0.02%$169.0220.8228$3,519.46
ETH0.02%$0.023819145,718.2059$3,470.91
ETH0.02%$0.900633,647.1222$3,284.71
ETH0.02%$0.0025391,256,168.0107$3,189.52
ETH0.01%$0.008219350,572.2507$2,881.48
ETH0.01%$0.5108945,251.4933$2,682.96
ETH0.01%$1.192,179.9171$2,594.1
ETH0.01%$0.5473514,202.8646$2,300.44
ETH0.01%$0.9919872,174.8632$2,157.44
ETH0.01%$0.2652318,029.4845$2,129.67
ETH<0.01%$1.281,379.603$1,765.89
ETH<0.01%$0.602442,616.24$1,576.13
ETH<0.01%$2.86523.0649$1,495.97
ETH<0.01%$0.9986771,465.8468$1,463.91
ETH<0.01%$0.9998781,453.6396$1,453.46
ETH<0.01%$0.5678392,475.415$1,405.64
ETH<0.01%$34.1935.8229$1,224.78
ETH<0.01%$1.041,039.0034$1,076.41
ETH<0.01%$2,515.690.427$1,074.08
ETH<0.01%$0.04051425,006.8842$1,013.14
ETH<0.01%$0.01765557,073.5648$1,007.63
ETH<0.01%$1.07801.7002$858.62
ETH<0.01%$3.01275.0407$827.87
ETH<0.01%$2.03384.0218$779.56
ETH<0.01%$77.99.4345$734.95
ETH<0.01%$1,272.270.556$707.43
ETH<0.01%$0.01964735,546.5637$698.39
ETH<0.01%$0.01826937,137.2328$678.47
ETH<0.01%$1.51411.7286$622.9
ETH<0.01%$0.295722,081.1311$615.43
ETH<0.01%$0.1115554,986.9343$556.32
ETH<0.01%$0.196242,465.6682$483.86
ETH<0.01%$0.001609298,986.0715$481.19
ETH<0.01%$0.3189551,499.9392$478.41
ETH<0.01%$4,719.280.1005$474.41
ETH<0.01%$1441$441.28
ETH<0.01%$0.000725605,453$438.91
ETH<0.01%$0.00432798,052.0559$424.24
ETH<0.01%$9.0444.19$399.48
ETH<0.01%$0.1593382,499.895$398.33
ETH<0.01%$0.987951399.114$394.31
ETH<0.01%$0.1334052,830.9364$377.66
ETH<0.01%$0.0001392,543,234.9949$353.31
ETH<0.01%$0.211761,582.6074$335.13
ETH<0.01%$0.02441613,658.8941$333.49
ETH<0.01%$0.02422413,717.752$332.3
ETH<0.01%$0.090133,561.369$320.99
ETH<0.01%$0.02985210,658.5842$318.18
ETH<0.01%$0.001113251,134.729$279.52
ETH<0.01%<$0.0000013,931,030,451.0459$241.07
ETH<0.01%$0.001182200,000$236.38
ETH<0.01%$0.00653935,848.5111$234.41
ETH<0.01%$0.0161314,169.9702$228.56
ETH<0.01%$0.0799282,805.0542$224.2
ETH<0.01%$1.13190.5623$215.46
ETH<0.01%$2.12100$211.72
ETH<0.01%$0.0149613,957$208.79
ETH<0.01%$0.0377465,521.4724$208.42
ETH<0.01%$0.408269509.9289$208.19
ETH<0.01%$0.247466759$187.83
ETH<0.01%$1.23146.37$180.04
ETH<0.01%$1.53112.4683$172.08
ETH<0.01%$50.533.2413$163.79
ETH<0.01%$0.0327055,000$163.53
ETH<0.01%$573.230.284$162.79
ETH<0.01%<$0.00000138,513,946,815.8887$148.43
ETH<0.01%$0.0376363,822.2701$143.85
ETH<0.01%$0.0398583,561.6341$141.96
ETH<0.01%$0.0703552,000$140.71
ETH<0.01%$0.00402734,420.5424$138.6
ETH<0.01%$0.0000275,000,000$132.75
ETH<0.01%$0.0380013,489.7704$132.61
ETH<0.01%$0.01092911,671.521$127.56
ETH<0.01%$0.0392273,102.471$121.7
ETH<0.01%$0.360317321.415$115.81
ETH<0.01%$0.00555920,509$114
ETH<0.01%$0.00198357,201$113.41
ETH<0.01%$1.13100.282$113.32
ETH<0.01%$0.0337063,331.637$112.3
ETH<0.01%$0.000576192,500$110.91
ETH<0.01%$1109.0709$109.4
ETH<0.01%$1108.4836$108.81
ETH<0.01%$0.00512819,952.5839$102.31
ETH<0.01%$0.00398125,000.9524$99.54
ETH<0.01%$0.0770171,276$98.27
ETH<0.01%$0.243091402.8$97.92
ETH<0.01%$0.000517185,010$95.61
ETH<0.01%$0.147284613.8083$90.4
ETH<0.01%$0.000613142,400$87.29
ETH<0.01%$0.288541284.8084$82.18
ETH<0.01%$2,701.950.0302$81.56
ETH<0.01%$0.000484156,440.0534$75.66
ETH<0.01%$0.00252130,004.0537$75.65
ETH<0.01%<$0.0000012,627,517,426,366,210,000$73.57
ETH<0.01%$0.0676391,080.4288$73.08
ETH<0.01%$0.0095437,467.5$71.27
ETH<0.01%$0.00133152,906$70.42
ETH<0.01%$0.123841567.2971$70.25
ETH<0.01%$0.117641596.2056$70.14
ETH<0.01%$0.000001116,462,426.5605$67.16
ETH<0.01%$4.7513.935$66.19
ETH<0.01%$0.482803133.7443$64.57
ETH<0.01%$0.252334255.0411$64.36
ETH<0.01%$0.00203131,621.6591$64.22
ETH<0.01%$0.319777183.4397$58.66
ETH<0.01%$0.0500421,125.713$56.33
ETH<0.01%$0.00201327,437.1466$55.22
ETH<0.01%$0.275373200$55.07
ETH<0.01%$0.317502170.8483$54.24
ETH<0.01%$154.1384$54.14
ETH<0.01%$0.471662113.9031$53.72
ETH<0.01%$0.0033615,251.957$51.25
ETH<0.01%$0.0347281,472.82$51.15
ETH<0.01%$0.000109466,666$50.73
ETH<0.01%$0.0205132,429.4107$49.83
ETH<0.01%$0.00493910,000$49.39
ETH<0.01%$0.0335681,416$47.53
ETH<0.01%$1.3932.9332$45.78
ETH<0.01%$0.440498102.183$45.01
ETH<0.01%$0.1469297.0251$43.63
ETH<0.01%$0.403697100$40.37
ETH<0.01%$0.00122732,000$39.26
ETH<0.01%$0.0337011,077.5065$36.31
ETH<0.01%$0.00171120,000$34.22
ETH<0.01%$0.0132222,531.5053$33.47
ETH<0.01%$11.652.8$32.62
ETH<0.01%$0.000236136,782.261$32.3
ETH<0.01%$0.00000311,984,845.4614$31.88
ETH
Ether (ETH)
<0.01%$2,520.030.0122$30.73
ETH<0.01%$0.000395,967.667$28.78
ETH<0.01%<$0.000001332,861,257.1001$27.55
ETH<0.01%$0.41087966.897$27.49
ETH<0.01%$0.117927228.1907$26.91
ETH<0.01%$0.000055472,461$25.91
ETH<0.01%$0.000186139,119.5738$25.85
ETH<0.01%$0.00109823,448$25.75
ETH<0.01%$0.044763500$22.38
ETH<0.01%$0.003755,798$21.74
ETH<0.01%$0.41170350.372$20.74
ETH<0.01%$0.00105417,771.1166$18.73
ETH<0.01%$0.036846495.009$18.24
ETH<0.01%<$0.00000150,000,000$17.78
ETH<0.01%$0.00123111,475.4098$14.13
ETH<0.01%$0.0091411,420.3958$12.98
ETH<0.01%$0.0099551,164.23$11.59
ETH<0.01%$0.0019675,759.4888$11.33
ETH<0.01%$0.61715215$9.26
ETH<0.01%$69,2820.000133$9.21
ETH<0.01%$0.68389713.1301$8.98
ETH<0.01%$0.0033162,000$6.63
ETH<0.01%$0.01482377.465$5.59
ETH<0.01%$0.0009236,000$5.54
ETH<0.01%$0.0000016,054,534.2078$5.01
ETH<0.01%$0.000007507,056.0927$3.64
ETH<0.01%$0.0004326,760.3087$2.92
ETH<0.01%$0.00007431,560$2.34
ETH<0.01%$0.09418414.3397$1.35
ETH<0.01%<$0.000001178,192,341.6604$1.34
ETH<0.01%$0.0007291,000$0.7288
ETH<0.01%$0.00002817,041.3043$0.4756
BASE<0.01%$0.0055184,324.6182$23.86
BASE<0.01%<$0.000001295,774,647$9.88
BASE<0.01%<$0.00000117,761,776$0.1634
BSC<0.01%$0.000028181,718.7097$5.03
POL<0.01%$0.3211490.0001$0.000032
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.