ETH Price: $2,486.93 (+3.18%)

Contract

0x6B49fd103e4fAdc132840837A6f2E751081fBb7f
 

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Execute199126752024-05-20 17:39:23139 days ago1716226763IN
0x6B49fd10...1081fBb7f
0 ETH0.0019592528.19198683
Execute199126402024-05-20 17:31:59139 days ago1716226319IN
0x6B49fd10...1081fBb7f
0 ETH0.0024057527.02341253
Execute199126162024-05-20 17:26:47139 days ago1716226007IN
0x6B49fd10...1081fBb7f
0 ETH0.0023213822.54431231
Execute194923172024-03-22 19:42:23198 days ago1711136543IN
0x6B49fd10...1081fBb7f
0 ETH0.0026346131.66029294
Execute194922562024-03-22 19:29:59198 days ago1711135799IN
0x6B49fd10...1081fBb7f
0 ETH0.0020656225.05094863
Execute194922482024-03-22 19:28:23198 days ago1711135703IN
0x6B49fd10...1081fBb7f
0 ETH0.0026076526.1894602
Execute194914982024-03-22 16:56:59198 days ago1711126619IN
0x6B49fd10...1081fBb7f
0 ETH0.0073316429.31322667
Execute194914852024-03-22 16:54:23198 days ago1711126463IN
0x6B49fd10...1081fBb7f
0 ETH0.004139630.92993234
Execute194777472024-03-20 18:38:59200 days ago1710959939IN
0x6B49fd10...1081fBb7f
0 ETH0.0046778434.31464093
Execute194777312024-03-20 18:35:47200 days ago1710959747IN
0x6B49fd10...1081fBb7f
0 ETH0.0024142634.69967845
Execute194777062024-03-20 18:30:35200 days ago1710959435IN
0x6B49fd10...1081fBb7f
0 ETH0.003299539.21675921
Execute194776892024-03-20 18:27:11200 days ago1710959231IN
0x6B49fd10...1081fBb7f
0 ETH0.0049687330.3517771
Execute194776022024-03-20 18:09:35200 days ago1710958175IN
0x6B49fd10...1081fBb7f
0 ETH0.0051607540.30300048
Transfer194775822024-03-20 18:05:35200 days ago1710957935IN
0x6B49fd10...1081fBb7f
0.03 ETH0.0009114538.43847603
Execute192704032024-02-20 17:28:59229 days ago1708450139IN
0x6B49fd10...1081fBb7f
0 ETH0.0075109153.8193168
Execute192703982024-02-20 17:27:59229 days ago1708450079IN
0x6B49fd10...1081fBb7f
0 ETH0.0078403353.57506351
Execute191920952024-02-09 17:36:23240 days ago1707500183IN
0x6B49fd10...1081fBb7f
0 ETH0.0050859281.11131886
Execute191920562024-02-09 17:27:59240 days ago1707499679IN
0x6B49fd10...1081fBb7f
0 ETH0.0041225668.51071397
Execute191920322024-02-09 17:22:47240 days ago1707499367IN
0x6B49fd10...1081fBb7f
0 ETH0.0120838472.67909236
Execute191911982024-02-09 14:34:47240 days ago1707489287IN
0x6B49fd10...1081fBb7f
0 ETH0.0053876693.38832508
Transfer191910112024-02-09 13:57:11240 days ago1707487031IN
0x6B49fd10...1081fBb7f
0.0332 ETH0.0022271593.9252409
Transfer191909712024-02-09 13:48:59240 days ago1707486539IN
0x6B49fd10...1081fBb7f
0.005 ETH0.0022228693.74412737
Execute191909382024-02-09 13:42:23240 days ago1707486143IN
0x6B49fd10...1081fBb7f
0 ETH0.01278602106.51026173
Execute191133272024-01-29 16:18:59251 days ago1706545139IN
0x6B49fd10...1081fBb7f
0 ETH0.0016104524.86846043
Execute191133202024-01-29 16:17:35251 days ago1706545055IN
0x6B49fd10...1081fBb7f
0 ETH0.0019138122.08137844
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
199126752024-05-20 17:39:23139 days ago1716226763
0x6B49fd10...1081fBb7f
0.00224843 ETH
194777472024-03-20 18:38:59200 days ago1710959939
0x6B49fd10...1081fBb7f
0.00675477 ETH
194777312024-03-20 18:35:47200 days ago1710959747
0x6B49fd10...1081fBb7f
0.00332795 ETH
194777062024-03-20 18:30:35200 days ago1710959435
0x6B49fd10...1081fBb7f
0.00480286 ETH
194776892024-03-20 18:27:11200 days ago1710959231
0x6B49fd10...1081fBb7f
0.00951877 ETH
194776022024-03-20 18:09:35200 days ago1710958175
0x6B49fd10...1081fBb7f
0.00762274 ETH
192703982024-02-20 17:27:59229 days ago1708450079
0x6B49fd10...1081fBb7f
0.01207229 ETH
191920952024-02-09 17:36:23240 days ago1707500183
0x6B49fd10...1081fBb7f
0.00797625 ETH
191920952024-02-09 17:36:23240 days ago1707500183
0x6B49fd10...1081fBb7f
0.48 ETH
191920562024-02-09 17:27:59240 days ago1707499679
0x6B49fd10...1081fBb7f
0.00618111 ETH
191920562024-02-09 17:27:59240 days ago1707499679
0x6B49fd10...1081fBb7f
0.01 ETH
191920322024-02-09 17:22:47240 days ago1707499367
0x6B49fd10...1081fBb7f
0.01877075 ETH
191920322024-02-09 17:22:47240 days ago1707499367
0x6B49fd10...1081fBb7f
0.51981083 ETH
191911982024-02-09 14:34:47240 days ago1707489287
0x6B49fd10...1081fBb7f
0.00964327 ETH
191911982024-02-09 14:34:47240 days ago1707489287
0x6B49fd10...1081fBb7f
0.01 ETH
191133272024-01-29 16:18:59251 days ago1706545139
0x6B49fd10...1081fBb7f
0.00249729 ETH
191133202024-01-29 16:17:35251 days ago1706545055
0x6B49fd10...1081fBb7f
0.00283319 ETH
191132962024-01-29 16:12:47251 days ago1706544767
0x6B49fd10...1081fBb7f
0.00376108 ETH
185097112023-11-06 1:36:23335 days ago1699234583
0x6B49fd10...1081fBb7f
0.00181823 ETH
183643422023-10-16 17:10:47356 days ago1697476247
0x6B49fd10...1081fBb7f
0.00308363 ETH
183643382023-10-16 17:09:59356 days ago1697476199
0x6B49fd10...1081fBb7f
0.00382054 ETH
183531802023-10-15 3:45:47357 days ago1697341547
0x6B49fd10...1081fBb7f
0.00127758 ETH
177865722023-07-27 19:44:47437 days ago1690487087
0x6B49fd10...1081fBb7f
0.00030141 ETH
176572602023-07-09 16:13:35455 days ago1688919215
0x6B49fd10...1081fBb7f
0.00336879 ETH
171306802023-04-26 13:24:47529 days ago1682515487
0x6B49fd10...1081fBb7f
0.0044037 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.