ETH Price: $3,295.15 (-1.05%)

Contract

0xe9A7EbFB4D1728a7E2A62701bA0E00e068156480
 

Overview

ETH Balance

0.000516779100585301 ETH

Eth Value

$1.70 (@ $3,295.15/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute176357422023-07-06 15:38:23535 days ago1688657903IN
0xe9A7EbFB...068156480
0 ETH0.0022316537.05412874
Transfer176357332023-07-06 15:36:35535 days ago1688657795IN
0xe9A7EbFB...068156480
0.00531231 ETH0.000782633.0046874
Execute176357262023-07-06 15:35:11535 days ago1688657711IN
0xe9A7EbFB...068156480
0 ETH0.0060561436.45666668
Execute176357212023-07-06 15:34:11535 days ago1688657651IN
0xe9A7EbFB...068156480
0 ETH0.0040304936.38777711
Execute175646522023-06-26 16:01:35545 days ago1687795295IN
0xe9A7EbFB...068156480
0 ETH0.0017576719.82351426
Execute175646452023-06-26 16:00:11545 days ago1687795211IN
0xe9A7EbFB...068156480
0 ETH0.0020962815.67888154
Execute175485762023-06-24 9:44:35547 days ago1687599875IN
0xe9A7EbFB...068156480
0 ETH0.0020691315.48682453
Execute174170172023-06-05 21:36:59566 days ago1686001019IN
0xe9A7EbFB...068156480
0 ETH0.0070602329.96893384
Execute174168092023-06-05 20:54:35566 days ago1685998475IN
0xe9A7EbFB...068156480
0 ETH0.0032137340.47518944
Transfer174167982023-06-05 20:52:23566 days ago1685998343IN
0xe9A7EbFB...068156480
0.00830596 ETH0.0009433139.78206957
Execute174167312023-06-05 20:38:47566 days ago1685997527IN
0xe9A7EbFB...068156480
0 ETH0.0031119939.15639563
Transfer174167142023-06-05 20:35:23566 days ago1685997323IN
0xe9A7EbFB...068156480
0.00941869 ETH0.0009694740.88562453
Execute174166982023-06-05 20:32:11566 days ago1685997131IN
0xe9A7EbFB...068156480
0 ETH0.0052633140.72825652
Transfer174155322023-06-05 16:35:35566 days ago1685982935IN
0xe9A7EbFB...068156480
0.00550912 ETH0.00239071100.82309822
Execute172720152023-05-16 11:37:23586 days ago1684237043IN
0xe9A7EbFB...068156480
0 ETH0.0059724342.31960441
Transfer172720112023-05-16 11:36:35586 days ago1684236995IN
0xe9A7EbFB...068156480
0.01100412 ETH0.0010172442.89982621
Execute168703362023-03-20 17:21:11643 days ago1679332871IN
0xe9A7EbFB...068156480
0 ETH0.0049229232.37404055
Transfer168703292023-03-20 17:19:47643 days ago1679332787IN
0xe9A7EbFB...068156480
0.00849728 ETH0.0007663232.31795489
Execute165543572023-02-04 8:54:11687 days ago1675500851IN
0xe9A7EbFB...068156480
0 ETH0.0028220318.56808855
Execute165044472023-01-28 9:33:47694 days ago1674898427IN
0xe9A7EbFB...068156480
0 ETH0.0022183414.59159501
Execute165044412023-01-28 9:32:35694 days ago1674898355IN
0xe9A7EbFB...068156480
0 ETH0.0022506814.80136314
Execute165044362023-01-28 9:31:35694 days ago1674898295IN
0xe9A7EbFB...068156480
0 ETH0.0023494315.4518334
Transfer165044332023-01-28 9:30:59694 days ago1674898259IN
0xe9A7EbFB...068156480
0.01256439 ETH0.0003405814.36328793
Execute163549832023-01-07 12:44:11715 days ago1673095451IN
0xe9A7EbFB...068156480
0 ETH0.002547716.75175996
Transfer163549802023-01-07 12:43:35715 days ago1673095415IN
0xe9A7EbFB...068156480
0.00633658 ETH0.0003467714.62432338
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
176357422023-07-06 15:38:23535 days ago1688657903
0xe9A7EbFB...068156480
0.00341255 ETH
176357422023-07-06 15:38:23535 days ago1688657903
0xe9A7EbFB...068156480
0.313 ETH
176357262023-07-06 15:35:11535 days ago1688657711
0xe9A7EbFB...068156480
0.01048163 ETH
176357262023-07-06 15:35:11535 days ago1688657711
0xe9A7EbFB...068156480
0.31995573 ETH
174170172023-06-05 21:36:59566 days ago1686001019
0xe9A7EbFB...068156480
0.00930493 ETH
174168092023-06-05 20:54:35566 days ago1685998475
0xe9A7EbFB...068156480
0.00494855 ETH
174167312023-06-05 20:38:47566 days ago1685997527
0xe9A7EbFB...068156480
0.00473078 ETH
174166982023-06-05 20:32:11566 days ago1685997131
0xe9A7EbFB...068156480
0.00617305 ETH
172720152023-05-16 11:37:23586 days ago1684237043
0xe9A7EbFB...068156480
0.00794551 ETH
168703362023-03-20 17:21:11643 days ago1679332871
0xe9A7EbFB...068156480
0.00905291 ETH
165543572023-02-04 8:54:11687 days ago1675500851
0xe9A7EbFB...068156480
0.00398473 ETH
165044472023-01-28 9:33:47694 days ago1674898427
0xe9A7EbFB...068156480
0.00357928 ETH
165044412023-01-28 9:32:35694 days ago1674898355
0xe9A7EbFB...068156480
0.00330803 ETH
165044362023-01-28 9:31:35694 days ago1674898295
0xe9A7EbFB...068156480
0.00316397 ETH
163549832023-01-07 12:44:11715 days ago1673095451
0xe9A7EbFB...068156480
0.0033786 ETH
162850452022-12-28 18:28:23725 days ago1672252103
0xe9A7EbFB...068156480
0.00555602 ETH
158101842022-10-23 10:21:59791 days ago1666520519
0xe9A7EbFB...068156480
0.0009316 ETH
158101842022-10-23 10:21:59791 days ago1666520519
0xe9A7EbFB...068156480
0.02 ETH
158099692022-10-23 9:38:59791 days ago1666517939
0xe9A7EbFB...068156480
0.00108145 ETH
158099692022-10-23 9:38:59791 days ago1666517939
0xe9A7EbFB...068156480
0.3 ETH
158099582022-10-23 9:36:47791 days ago1666517807
0xe9A7EbFB...068156480
0.00657849 ETH
158099582022-10-23 9:36:47791 days ago1666517807
0xe9A7EbFB...068156480
0.32694562 ETH
157687822022-10-17 15:41:35797 days ago1666021295
0xe9A7EbFB...068156480
0.0088238 ETH
157403362022-10-13 16:18:11801 days ago1665677891
0xe9A7EbFB...068156480
0.00328876 ETH
157403362022-10-13 16:18:11801 days ago1665677891
0xe9A7EbFB...068156480
0.16 ETH
View All Internal Transactions
Loading...
Loading

Minimal Proxy Contract for 0x2a2b85eb1054d6f0c6c2e37da05ed3e5fea684ef

Contract Name:
Identity

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2021-11-14
*/

pragma solidity 0.8.7;

// @TODO: Formatting
library LibBytes {
  // @TODO: see if we can just set .length = 
  function trimToSize(bytes memory b, uint newLen)
    internal
    pure
  {
    require(b.length > newLen, "BytesLib: only shrinking");
    assembly {
      mstore(b, newLen)
    }
  }


  /***********************************|
  |        Read Bytes Functions       |
  |__________________________________*/

  /**
   * @dev Reads a bytes32 value from a position in a byte array.
   * @param b Byte array containing a bytes32 value.
   * @param index Index in byte array of bytes32 value.
   * @return result bytes32 value from byte array.
   */
  function readBytes32(
    bytes memory b,
    uint256 index
  )
    internal
    pure
    returns (bytes32 result)
  {
    // Arrays are prefixed by a 256 bit length parameter
    index += 32;

    require(b.length >= index, "BytesLib: length");

    // Read the bytes32 from array memory
    assembly {
      result := mload(add(b, index))
    }
    return result;
  }
}



interface IERC1271Wallet {
	function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue);
}

library SignatureValidator {
	using LibBytes for bytes;

	enum SignatureMode {
		EIP712,
		EthSign,
		SmartWallet,
		Spoof
	}

	// bytes4(keccak256("isValidSignature(bytes32,bytes)"))
	bytes4 constant internal ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e;

	function recoverAddr(bytes32 hash, bytes memory sig) internal view returns (address) {
		return recoverAddrImpl(hash, sig, false);
	}

	function recoverAddrImpl(bytes32 hash, bytes memory sig, bool allowSpoofing) internal view returns (address) {
		require(sig.length >= 1, "SV_SIGLEN");
		uint8 modeRaw;
		unchecked { modeRaw = uint8(sig[sig.length - 1]); }
		SignatureMode mode = SignatureMode(modeRaw);

		// {r}{s}{v}{mode}
		if (mode == SignatureMode.EIP712 || mode == SignatureMode.EthSign) {
			require(sig.length == 66, "SV_LEN");
			bytes32 r = sig.readBytes32(0);
			bytes32 s = sig.readBytes32(32);
			uint8 v = uint8(sig[64]);
			// Hesitant about this check: seems like this is something that has no business being checked on-chain
			require(v == 27 || v == 28, "SV_INVALID_V");
			if (mode == SignatureMode.EthSign) hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
			address signer = ecrecover(hash, v, r, s);
			require(signer != address(0), "SV_ZERO_SIG");
			return signer;
		// {sig}{verifier}{mode}
		} else if (mode == SignatureMode.SmartWallet) {
			// 32 bytes for the addr, 1 byte for the type = 33
			require(sig.length > 33, "SV_LEN_WALLET");
			uint newLen;
			unchecked {
				newLen = sig.length - 33;
			}
			IERC1271Wallet wallet = IERC1271Wallet(address(uint160(uint256(sig.readBytes32(newLen)))));
			sig.trimToSize(newLen);
			require(ERC1271_MAGICVALUE_BYTES32 == wallet.isValidSignature(hash, sig), "SV_WALLET_INVALID");
			return address(wallet);
		// {address}{mode}; the spoof mode is used when simulating calls
		} else if (mode == SignatureMode.Spoof && allowSpoofing) {
			require(tx.origin == address(1), "SV_SPOOF_ORIGIN");
			require(sig.length == 33, "SV_SPOOF_LEN");
			sig.trimToSize(32);
			return abi.decode(sig, (address));
		} else revert("SV_SIGMODE");
	}
}


contract Identity {
	mapping (address => bytes32) public privileges;
	// The next allowed nonce
	uint public nonce;

	// Events
	event LogPrivilegeChanged(address indexed addr, bytes32 priv);
	event LogErr(address indexed to, uint value, bytes data, bytes returnData); // only used in tryCatch

	// Transaction structure
	// we handle replay protection separately by requiring (address(this), chainID, nonce) as part of the sig
	struct Transaction {
		address to;
		uint value;
		bytes data;
	}

	constructor(address[] memory addrs) {
		uint len = addrs.length;
		for (uint i=0; i<len; i++) {
			// @TODO should we allow setting to any arb value here?
			privileges[addrs[i]] = bytes32(uint(1));
			emit LogPrivilegeChanged(addrs[i], bytes32(uint(1)));
		}
	}

	// This contract can accept ETH without calldata
	receive() external payable {}

	// This contract can accept ETH with calldata
	// However, to support EIP 721 and EIP 1155, we need to respond to those methods with their own method signature
	fallback() external payable {
		bytes4 method = msg.sig;
		if (
			method == 0x150b7a02 // bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))
				|| method == 0xf23a6e61 // bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))
				|| method == 0xbc197c81 // bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
		) {
			// Copy back the method
			// solhint-disable-next-line no-inline-assembly
			assembly {
				calldatacopy(0, 0, 0x04)
				return (0, 0x20)
			}
		}
	}

	function setAddrPrivilege(address addr, bytes32 priv)
		external
	{
		require(msg.sender == address(this), 'ONLY_IDENTITY_CAN_CALL');
		// Anti-bricking measure: if the privileges slot is used for special data (not 0x01),
		// don't allow to set it to true
		if (uint(privileges[addr]) > 1) require(priv != bytes32(uint(1)), 'UNSETTING_SPECIAL_DATA');
		privileges[addr] = priv;
		emit LogPrivilegeChanged(addr, priv);
	}

	function tipMiner(uint amount)
		external
	{
		require(msg.sender == address(this), 'ONLY_IDENTITY_CAN_CALL');
		// See https://docs.flashbots.net/flashbots-auction/searchers/advanced/coinbase-payment/#managing-payments-to-coinbaseaddress-when-it-is-a-contract
		// generally this contract is reentrancy proof cause of the nonce
		executeCall(block.coinbase, amount, new bytes(0));
	}

	function tryCatch(address to, uint value, bytes calldata data)
		external
	{
		require(msg.sender == address(this), 'ONLY_IDENTITY_CAN_CALL');
		(bool success, bytes memory returnData) = to.call{value: value, gas: gasleft()}(data);
		if (!success) emit LogErr(to, value, data, returnData);
	}


	// WARNING: if the signature of this is changed, we have to change IdentityFactory
	function execute(Transaction[] calldata txns, bytes calldata signature)
		external
	{
		require(txns.length > 0, 'MUST_PASS_TX');
		uint currentNonce = nonce;
		// NOTE: abi.encode is safer than abi.encodePacked in terms of collision safety
		bytes32 hash = keccak256(abi.encode(address(this), block.chainid, currentNonce, txns));
		// We have to increment before execution cause it protects from reentrancies
		nonce = currentNonce + 1;

		address signer = SignatureValidator.recoverAddrImpl(hash, signature, true);
		require(privileges[signer] != bytes32(0), 'INSUFFICIENT_PRIVILEGE');
		uint len = txns.length;
		for (uint i=0; i<len; i++) {
			Transaction memory txn = txns[i];
			executeCall(txn.to, txn.value, txn.data);
		}
		// The actual anti-bricking mechanism - do not allow a signer to drop their own priviledges
		require(privileges[signer] != bytes32(0), 'PRIVILEGE_NOT_DOWNGRADED');
	}

	// no need for nonce management here cause we're not dealing with sigs
	function executeBySender(Transaction[] calldata txns) external {
		require(txns.length > 0, 'MUST_PASS_TX');
		require(privileges[msg.sender] != bytes32(0), 'INSUFFICIENT_PRIVILEGE');
		uint len = txns.length;
		for (uint i=0; i<len; i++) {
			Transaction memory txn = txns[i];
			executeCall(txn.to, txn.value, txn.data);
		}
		// again, anti-bricking
		require(privileges[msg.sender] != bytes32(0), 'PRIVILEGE_NOT_DOWNGRADED');
	}

	function executeBySelf(Transaction[] calldata txns) external {
		require(msg.sender == address(this), 'ONLY_IDENTITY_CAN_CALL');
		require(txns.length > 0, 'MUST_PASS_TX');
		uint len = txns.length;
		for (uint i=0; i<len; i++) {
			Transaction memory txn = txns[i];
			executeCall(txn.to, txn.value, txn.data);
		}
	}

	// we shouldn't use address.call(), cause: https://github.com/ethereum/solidity/issues/2884
	// copied from https://github.com/uport-project/uport-identity/blob/develop/contracts/Proxy.sol
	// there's also
	// https://github.com/gnosis/MultiSigWallet/commit/e1b25e8632ca28e9e9e09c81bd20bf33fdb405ce
	// https://github.com/austintgriffith/bouncer-proxy/blob/master/BouncerProxy/BouncerProxy.sol
	// https://github.com/gnosis/safe-contracts/blob/7e2eeb3328bb2ae85c36bc11ea6afc14baeb663c/contracts/base/Executor.sol
	function executeCall(address to, uint256 value, bytes memory data)
		internal
	{
		assembly {
			let result := call(gas(), to, value, add(data, 0x20), mload(data), 0, 0)

			switch result case 0 {
				let size := returndatasize()
				let ptr := mload(0x40)
				returndatacopy(ptr, 0, size)
				revert(ptr, size)
			}
			default {}
		}
		// A single call consumes around 477 more gas with the pure solidity version, for whatever reason
		// WARNING: do not use this, it corrupts the returnData string (returns it in a slightly different format)
		//(bool success, bytes memory returnData) = to.call{value: value, gas: gasleft()}(data);
		//if (!success) revert(string(data));
	}

	// EIP 1271 implementation
	// see https://eips.ethereum.org/EIPS/eip-1271
	function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4) {
		if (privileges[SignatureValidator.recoverAddr(hash, signature)] != bytes32(0)) {
			// bytes4(keccak256("isValidSignature(bytes32,bytes)")
			return 0x1626ba7e;
		} else {
			return 0xffffffff;
		}
	}

	// EIP 1155 implementation
	// we pretty much only need to signal that we support the interface for 165, but for 1155 we also need the fallback function
	function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
		return
			interfaceID == 0x01ffc9a7 ||    // ERC-165 support (i.e. `bytes4(keccak256('supportsInterface(bytes4)'))`).
			interfaceID == 0x4e2312e0;      // ERC-1155 `ERC1155TokenReceiver` support (i.e. `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)")) ^ bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`).
	}
}

Contract ABI

[{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"LogErr","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bytes32","name":"priv","type":"bytes32"}],"name":"LogPrivilegeChanged","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Identity.Transaction[]","name":"txns","type":"tuple[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Identity.Transaction[]","name":"txns","type":"tuple[]"}],"name":"executeBySelf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Identity.Transaction[]","name":"txns","type":"tuple[]"}],"name":"executeBySender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"privileges","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"priv","type":"bytes32"}],"name":"setAddrPrivilege","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"tipMiner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"tryCatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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