ETH Price: $2,139.93 (+0.35%)

Contract

0xD4717059eCd0EB605a1605cfdA8d842e14F4BB3d
 

More Info

Private Name Tags

Multichain Info

Transaction Hash
Method
Block
From
To
Execute229749972025-07-22 13:24:35240 days ago1753190675IN
0xD4717059...e14F4BB3d
0 ETH0.000373541.66639779
Execute206774412024-09-04 13:12:47561 days ago1725455567IN
0xD4717059...e14F4BB3d
0 ETH0.000500865.77035743
Execute206773982024-09-04 13:04:11561 days ago1725455051IN
0xD4717059...e14F4BB3d
0 ETH0.000824583.64264243
Execute206212522024-08-27 16:55:23569 days ago1724777723IN
0xD4717059...e14F4BB3d
0 ETH0.000486295.60358427
Execute206212482024-08-27 16:54:35569 days ago1724777675IN
0xD4717059...e14F4BB3d
0 ETH0.000967145.67853278
Execute206212422024-08-27 16:53:23569 days ago1724777603IN
0xD4717059...e14F4BB3d
0 ETH0.001200635.12556805
Execute206212322024-08-27 16:51:23569 days ago1724777483IN
0xD4717059...e14F4BB3d
0 ETH0.000650855.12258479
Execute201908572024-06-28 14:43:11629 days ago1719585791IN
0xD4717059...e14F4BB3d
0 ETH0.0008524110.00372046
Execute201752812024-06-26 10:31:23632 days ago1719397883IN
0xD4717059...e14F4BB3d
0 ETH0.000718564.90918196
Execute191985112024-02-10 15:13:11768 days ago1707577991IN
0xD4717059...e14F4BB3d
0 ETH0.0058327231.29062301
Execute191985022024-02-10 15:11:11768 days ago1707577871IN
0xD4717059...e14F4BB3d
0 ETH0.002194436.45308755
Execute185483222023-11-11 11:14:23860 days ago1699701263IN
0xD4717059...e14F4BB3d
0 ETH0.0017204123.20780289
Execute185483172023-11-11 11:13:23860 days ago1699701203IN
0xD4717059...e14F4BB3d
0 ETH0.0024568922.91579931
Execute179274342023-08-16 12:36:47947 days ago1692189407IN
0xD4717059...e14F4BB3d
0 ETH0.0039205529.42832309
Execute172376982023-05-11 14:27:591043 days ago1683815279IN
0xD4717059...e14F4BB3d
0 ETH0.00716268103.11809672
Execute172376242023-05-11 14:12:111043 days ago1683814331IN
0xD4717059...e14F4BB3d
0 ETH0.02398566136.33483474
Execute172376162023-05-11 14:10:351043 days ago1683814235IN
0xD4717059...e14F4BB3d
0 ETH0.01587771143.36792041
Execute161901302022-12-15 12:35:351191 days ago1671107735IN
0xD4717059...e14F4BB3d
0 ETH0.0009743714.64527263
Execute161901222022-12-15 12:33:591191 days ago1671107639IN
0xD4717059...e14F4BB3d
0 ETH0.0019817314.87521839
Execute161900882022-12-15 12:27:111191 days ago1671107231IN
0xD4717059...e14F4BB3d
0 ETH0.0015365114.76068057
Execute161900842022-12-15 12:26:231191 days ago1671107183IN
0xD4717059...e14F4BB3d
0 ETH0.0021563915.12874396
Execute161688292022-12-12 13:08:591193 days ago1670850539IN
0xD4717059...e14F4BB3d
0 ETH0.0045403418.21172684
Execute161688072022-12-12 13:04:351193 days ago1670850275IN
0xD4717059...e14F4BB3d
0 ETH0.0025227717.69646528
Execute161682022022-12-12 11:02:591194 days ago1670842979IN
0xD4717059...e14F4BB3d
0 ETH0.0006284814.07741776
Transfer147640122022-05-12 23:40:151407 days ago1652398815IN
0xD4717059...e14F4BB3d
0.04601058 ETH0.0024521103.41196722
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer229749972025-07-22 13:24:35240 days ago1753190675
0xD4717059...e14F4BB3d
0.00150289 ETH
Transfer206212482024-08-27 16:54:35569 days ago1724777675
0xD4717059...e14F4BB3d
0.00058403 ETH
Multicall206212482024-08-27 16:54:35569 days ago1724777675
0xD4717059...e14F4BB3d
0.11739057 ETH
Transfer206212322024-08-27 16:51:23569 days ago1724777483
0xD4717059...e14F4BB3d
0.00172622 ETH
Transfer201908572024-06-28 14:43:11629 days ago1719585791
0xD4717059...e14F4BB3d
0.00123156 ETH
Transfer201908572024-06-28 14:43:11629 days ago1719585791
0xD4717059...e14F4BB3d
0.175 ETH
Transfer201752812024-06-26 10:31:23632 days ago1719397883
0xD4717059...e14F4BB3d
0.00109718 ETH
Transfer191985112024-02-10 15:13:11768 days ago1707577991
0xD4717059...e14F4BB3d
0.0094561 ETH
Transfer191985022024-02-10 15:11:11768 days ago1707577871
0xD4717059...e14F4BB3d
0.00323108 ETH
Transfer191985022024-02-10 15:11:11768 days ago1707577871
0xD4717059...e14F4BB3d
0.48 ETH
Transfer172376982023-05-11 14:27:591043 days ago1683815279
0xD4717059...e14F4BB3d
0.01 ETH
Transfer160560912022-11-26 18:56:351209 days ago1669488995
0xD4717059...e14F4BB3d
0.00130524 ETH
Transfer159280982022-11-08 21:48:231227 days ago1667944103
0xD4717059...e14F4BB3d
2.35191266 ETH
Transfer159280932022-11-08 21:47:231227 days ago1667944043
0xD4717059...e14F4BB3d
2.33198564 ETH
Transfer153520742022-08-16 11:24:091312 days ago1660649049
0xD4717059...e14F4BB3d
0.2 ETH
Transfer151932992022-07-22 15:51:431336 days ago1658505103
0xD4717059...e14F4BB3d
0.2 ETH
Transfer151595662022-07-17 10:12:491342 days ago1658052769
0xD4717059...e14F4BB3d
0.00076865 ETH
Transfer151595662022-07-17 10:12:491342 days ago1658052769
0xD4717059...e14F4BB3d
1 ETH
Transfer151595642022-07-17 10:11:301342 days ago1658052690
0xD4717059...e14F4BB3d
0.00129359 ETH
Transfer151595582022-07-17 10:10:191342 days ago1658052619
0xD4717059...e14F4BB3d
0.00097353 ETH
Transfer151595582022-07-17 10:10:191342 days ago1658052619
0xD4717059...e14F4BB3d
0.65814941 ETH
Transfer151595502022-07-17 10:09:241342 days ago1658052564
0xD4717059...e14F4BB3d
0.00261482 ETH
Transfer151595502022-07-17 10:09:241342 days ago1658052564
0xD4717059...e14F4BB3d
1.44462128 ETH
Transfer151595032022-07-17 9:57:581342 days ago1658051878
0xD4717059...e14F4BB3d
0.00089591 ETH
Transfer151594832022-07-17 9:54:241342 days ago1658051664
0xD4717059...e14F4BB3d
0.00196916 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code (Solidity)

/**
 *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

API
[{"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 Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
0xD4717059eCd0EB605a1605cfdA8d842e14F4BB3d
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.