ETH Price: $3,270.84 (+1.61%)

Contract

0xc0B16b40c6079b0A317a2fEBc062509CDF447f5c
 

Overview

ETH Balance

7.549475403925499487 ETH

Eth Value

$24,693.11 (@ $3,270.84/ETH)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer215950902025-01-10 15:52:117 hrs ago1736524331IN
0xc0B16b40...CDF447f5c
0.04550301 ETH0.0002789110.83602571
Transfer215892712025-01-09 20:20:5926 hrs ago1736454059IN
0xc0B16b40...CDF447f5c
0.11148724 ETH0.0004120916.0098159
Transfer215870082025-01-09 12:45:4734 hrs ago1736426747IN
0xc0B16b40...CDF447f5c
0.03104078 ETH0.000126524.9155269
Transfer215830352025-01-08 23:26:1147 hrs ago1736378771IN
0xc0B16b40...CDF447f5c
0.03360852 ETH0.000140475.45740591
Transfer215685082025-01-06 22:48:354 days ago1736203715IN
0xc0B16b40...CDF447f5c
0.02044669 ETH0.0002958811.49504358
Transfer215645652025-01-06 9:35:234 days ago1736156123IN
0xc0B16b40...CDF447f5c
0.10585306 ETH0.000192827.49126502
Transfer215583072025-01-05 12:34:355 days ago1736080475IN
0xc0B16b40...CDF447f5c
0.05182827 ETH0.000240549.34532264
Transfer215313062025-01-01 18:07:599 days ago1735754879IN
0xc0B16b40...CDF447f5c
0.03271141 ETH0.0006929926.92292703
Transfer215242582024-12-31 18:31:5910 days ago1735669919IN
0xc0B16b40...CDF447f5c
0.03057646 ETH0.000232919.04889091
Transfer215212112024-12-31 8:17:3510 days ago1735633055IN
0xc0B16b40...CDF447f5c
0.10287189 ETH0.000242519.42176561
Transfer215069492024-12-29 8:31:3512 days ago1735461095IN
0xc0B16b40...CDF447f5c
0.02566965 ETH0.000068292.65328608
Transfer214952242024-12-27 17:15:2314 days ago1735319723IN
0xc0B16b40...CDF447f5c
0.02667037 ETH0.000178276.92583569
Send Multi Sig214949462024-12-27 16:19:2314 days ago1735316363IN
0xc0B16b40...CDF447f5c
0 ETH0.000765429.19492731
Transfer214930842024-12-27 10:05:4714 days ago1735293947IN
0xc0B16b40...CDF447f5c
0.02582828 ETH0.000139555.42179616
Transfer214914222024-12-27 4:30:3514 days ago1735273835IN
0xc0B16b40...CDF447f5c
0.03205605 ETH0.000110264.28375423
Transfer214852912024-12-26 7:57:3515 days ago1735199855IN
0xc0B16b40...CDF447f5c
0.02541142 ETH0.000136145.28939216
Transfer214827772024-12-25 23:30:3515 days ago1735169435IN
0xc0B16b40...CDF447f5c
0.01389485 ETH0.000096363.74359987
Transfer214814382024-12-25 19:00:4716 days ago1735153247IN
0xc0B16b40...CDF447f5c
0.01658732 ETH0.000107364.1710447
Transfer214767132024-12-25 3:10:3516 days ago1735096235IN
0xc0B16b40...CDF447f5c
0.02328761 ETH0.000102183.97001708
Transfer214756652024-12-24 23:39:5916 days ago1735083599IN
0xc0B16b40...CDF447f5c
0.02194628 ETH0.000096663.75527562
Transfer214693652024-12-24 2:31:1117 days ago1735007471IN
0xc0B16b40...CDF447f5c
0.02583106 ETH0.000162856.32690039
Transfer214676622024-12-23 20:47:3518 days ago1734986855IN
0xc0B16b40...CDF447f5c
0.02595222 ETH0.000385314.9692427
Transfer214558922024-12-22 5:17:1119 days ago1734844631IN
0xc0B16b40...CDF447f5c
0.02574471 ETH0.000154345.99614967
Transfer214528182024-12-21 18:57:3520 days ago1734807455IN
0xc0B16b40...CDF447f5c
0.03495342 ETH0.00023929.29305783
Transfer214508752024-12-21 12:26:2320 days ago1734783983IN
0xc0B16b40...CDF447f5c
0.05110498 ETH0.000165256.42009937
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
214949462024-12-27 16:19:2314 days ago1735316363
0xc0B16b40...CDF447f5c
70 ETH
214161282024-12-16 15:58:4725 days ago1734364727
0xc0B16b40...CDF447f5c
70 ETH
213660502024-12-09 16:10:3532 days ago1733760635
0xc0B16b40...CDF447f5c
38 ETH
212801472024-11-27 16:01:2344 days ago1732723283
0xc0B16b40...CDF447f5c
100 ETH
212165552024-11-18 19:00:1153 days ago1731956411
0xc0B16b40...CDF447f5c
133 ETH
211727872024-11-12 16:26:3559 days ago1731428795
0xc0B16b40...CDF447f5c
6 ETH
210937332024-11-01 15:36:2370 days ago1730475383
0xc0B16b40...CDF447f5c
38 ETH
210163012024-10-21 20:19:1181 days ago1729541951
0xc0B16b40...CDF447f5c
8.1 ETH
209440172024-10-11 17:58:1191 days ago1728669491
0xc0B16b40...CDF447f5c
41 ETH
208636002024-09-30 12:54:35102 days ago1727700875
0xc0B16b40...CDF447f5c
41 ETH
207425322024-09-13 15:17:11119 days ago1726240631
0xc0B16b40...CDF447f5c
11 ETH
206215582024-08-27 17:57:11136 days ago1724781431
0xc0B16b40...CDF447f5c
7 ETH
205632672024-08-19 14:27:47144 days ago1724077667
0xc0B16b40...CDF447f5c
6 ETH
204917292024-08-09 14:46:11154 days ago1723214771
0xc0B16b40...CDF447f5c
5.7 ETH
204129462024-07-29 14:53:59165 days ago1722264839
0xc0B16b40...CDF447f5c
18 ETH
202194562024-07-02 14:34:11192 days ago1719930851
0xc0B16b40...CDF447f5c
12 ETH
201122322024-06-17 14:53:59207 days ago1718636039
0xc0B16b40...CDF447f5c
45 ETH
199911632024-05-31 16:59:59224 days ago1717174799
0xc0B16b40...CDF447f5c
96 ETH
199696392024-05-28 16:44:35227 days ago1716914675
0xc0B16b40...CDF447f5c
1,005 ETH
199632952024-05-27 19:28:47228 days ago1716838127
0xc0B16b40...CDF447f5c
0.12738626 ETH
196859832024-04-19 0:41:35266 days ago1713487295
0xc0B16b40...CDF447f5c
32 ETH
196859832024-04-19 0:41:35266 days ago1713487295
0xc0B16b40...CDF447f5c
32 ETH
196830132024-04-18 14:43:11267 days ago1713451391
0xc0B16b40...CDF447f5c
32 ETH
196830132024-04-18 14:43:11267 days ago1713451391
0xc0B16b40...CDF447f5c
32 ETH
196330412024-04-11 14:42:23274 days ago1712846543
0xc0B16b40...CDF447f5c
32 ETH
View All Internal Transactions
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 25 blocks (From a total of 32 blocks with 1.32 Ether produced)

Block Transaction Difficulty Gas Used Reward
213842132024-12-12 5:03:5929 days ago1733979839490.00 TH2,671,835 (8.91%)
0.005561569750195691 ETH
209745382024-10-16 0:27:2386 days ago1729038443580.00 TH4,004,262 (13.35%)
0.0035371878928174 ETH
197723732024-05-01 2:43:11254 days ago17145313912090.00 TH17,855,962 (59.52%)
0.009880256735158744 ETH
195212342024-03-26 21:21:47290 days ago17114881071870.00 TH13,903,901 (46.35%)
0.029209398008699379 ETH
195010022024-03-24 0:58:47292 days ago17112419271900.00 TH16,992,224 (56.64%)
0.034818079039614986 ETH
193123292024-02-26 14:27:11319 days ago17089576312830.00 TH19,687,863 (65.63%)
0.072058968144926428 ETH
191786622024-02-07 20:21:47338 days ago1707337307690.00 TH9,167,552 (30.56%)
0.167897018186990004 ETH
189624142024-01-08 12:52:23368 days ago17047183431540.00 TH10,935,204 (36.45%)
0.025794761595206493 ETH
189589512024-01-08 1:07:35368 days ago17046760553600.00 TH28,195,267 (93.98%)
0.053384300459001953 ETH
189313212024-01-04 3:34:47372 days ago17043392871180.00 TH8,878,538 (29.60%)
0.02154440831539685 ETH
188640852023-12-25 17:00:23382 days ago17035236231830.00 TH12,946,815 (43.16%)
0.04188916105502496 ETH
188352902023-12-21 15:59:47386 days ago17031743871610.00 TH16,832,753 (56.11%)
0.039337664998128744 ETH
188062672023-12-17 14:13:47390 days ago17028224271270.00 TH10,894,383 (36.31%)
0.032296432592266274 ETH
187931902023-12-15 18:06:23392 days ago17026635831120.00 TH11,567,285 (38.56%)
0.044544581628858552 ETH
187803652023-12-13 22:56:59394 days ago17025082191330.00 TH11,298,644 (37.66%)
0.044979472068018978 ETH
187770212023-12-13 11:41:47394 days ago17024677071320.00 TH22,346,607 (74.49%)
0.035737766421676681 ETH
187271552023-12-06 12:01:35401 days ago17018640951840.00 TH20,279,513 (67.60%)
0.024885554423260855 ETH
186589662023-11-26 22:57:47411 days ago17010394671220.00 TH17,167,761 (57.23%)
0.026143963892818946 ETH
186520202023-11-25 23:35:47411 days ago17009553471150.00 TH9,396,716 (31.32%)
0.020241403204322183 ETH
186217612023-11-21 17:55:35416 days ago17005893351550.00 TH11,379,083 (37.93%)
0.068144186041246455 ETH
186134302023-11-20 13:54:59417 days ago17004884991490.00 TH12,675,354 (42.25%)
0.037025119348387257 ETH
186025342023-11-19 1:18:23418 days ago17003567031600.00 TH18,099,811 (60.33%)
0.033353583731970546 ETH
185401882023-11-10 7:55:11427 days ago16996029111890.00 TH14,754,000 (49.18%)
0.016423849298251949 ETH
185079792023-11-05 19:47:23432 days ago16992136431140.00 TH9,801,166 (32.67%)
0.138064761331600186 ETH
185077762023-11-05 19:06:11432 days ago16992111711760.00 TH15,710,455 (52.37%)
0.024244819362441314 ETH
View All Blocks Produced

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

Latest 25 from a total of 16333 withdrawals (3,143.350249743 ETH withdrawn)

Validator Index Block Amount
630066215972182025-01-10 22:59:1117 mins ago17365499510.019254936 ETH
630065215972182025-01-10 22:59:1117 mins ago17365499510.019219416 ETH
626229215971232025-01-10 22:40:1136 mins ago17365488110.019229754 ETH
626228215971232025-01-10 22:40:1136 mins ago17365488110.019221685 ETH
604395215964852025-01-10 20:32:112 hrs ago17365411310.019243726 ETH
604391215964842025-01-10 20:31:592 hrs ago17365411190.063997602 ETH
604385215964842025-01-10 20:31:592 hrs ago17365411190.019229945 ETH
604382215964842025-01-10 20:31:592 hrs ago17365411190.019253422 ETH
604381215964842025-01-10 20:31:592 hrs ago17365411190.019248307 ETH
604364215964842025-01-10 20:31:592 hrs ago17365411190.019231683 ETH
604361215964842025-01-10 20:31:592 hrs ago17365411190.019190108 ETH
604357215964842025-01-10 20:31:592 hrs ago17365411190.019241358 ETH
595031215961722025-01-10 19:29:353 hrs ago17365373750.019267189 ETH
594471215961592025-01-10 19:26:593 hrs ago17365372190.019249215 ETH
587315215960032025-01-10 18:55:354 hrs ago17365353350.019160257 ETH
587314215960032025-01-10 18:55:354 hrs ago17365353350.019168412 ETH
584524215959002025-01-10 18:34:594 hrs ago17365340990.019214878 ETH
584520215959002025-01-10 18:34:594 hrs ago17365340990.019188582 ETH
584518215959002025-01-10 18:34:594 hrs ago17365340990.019234429 ETH
581379215957812025-01-10 18:11:115 hrs ago17365326710.019231018 ETH
574697215955542025-01-10 17:25:355 hrs ago17365299350.019118638 ETH
574695215955542025-01-10 17:25:355 hrs ago17365299350.019194891 ETH
574694215955542025-01-10 17:25:355 hrs ago17365299350.019242274 ETH
574691215955542025-01-10 17:25:355 hrs ago17365299350.019241899 ETH
574690215955542025-01-10 17:25:355 hrs ago17365299350.019242866 ETH
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.