ETH Price: $2,093.76 (+3.12%)

Contract

0xfDAc3Fff3Ca01c9d61a09C36A9fbDB6bB36DaB68
 

Overview

ETH Balance

0.03005786585480129 ETH

Eth Value

$62.93 (@ $2,093.76/ETH)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute161699182022-12-12 16:49:111186 days ago1670863751IN
0xfDAc3Fff...bB36DaB68
0 ETH0.002161423.12827804
Execute161698952022-12-12 16:44:111186 days ago1670863451IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0022200621.47685833
Execute156243552022-09-27 11:20:591262 days ago1664277659IN
0xfDAc3Fff...bB36DaB68
0 ETH0.000787629.11665898
Execute153647312022-08-18 11:25:411302 days ago1660821941IN
0xfDAc3Fff...bB36DaB68
0 ETH0.000880526.17476817
Execute153647282022-08-18 11:25:131302 days ago1660821913IN
0xfDAc3Fff...bB36DaB68
0 ETH0.000700616.13383068
Execute153647142022-08-18 11:22:551302 days ago1660821775IN
0xfDAc3Fff...bB36DaB68
0 ETH0.001051918.01344195
Execute152580012022-08-01 17:29:011319 days ago1659374941IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0025889127.3577201
Execute152579432022-08-01 17:13:301319 days ago1659374010IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0016105411.90753464
Execute152579332022-08-01 17:12:241319 days ago1659373944IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0030977917.41642758
Transfer150222802022-06-25 6:05:531357 days ago1656137153IN
0xfDAc3Fff...bB36DaB68
0.1 ETH0.0006551327.62876841
Execute150222312022-06-25 5:51:341357 days ago1656136294IN
0xfDAc3Fff...bB36DaB68
0 ETH0.00145517.77626255
Transfer150222052022-06-25 5:44:171357 days ago1656135857IN
0xfDAc3Fff...bB36DaB68
1.4994 ETH0.0004574719.29312541
Execute149322212022-06-09 11:00:081372 days ago1654772408IN
0xfDAc3Fff...bB36DaB68
0 ETH0.002822734.805716
Execute147864852022-05-16 13:16:451396 days ago1652707005IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0025565115.60689371
Execute147667542022-05-13 10:14:001399 days ago1652436840IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0187695156.79144116
Transfer147664972022-05-13 9:11:221399 days ago1652433082IN
0xfDAc3Fff...bB36DaB68
1.843 ETH0.0020564786.72729946
Execute143795232022-03-13 17:12:541460 days ago1647191574IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0019910431.93534803
Execute143795102022-03-13 17:09:421460 days ago1647191382IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0054431732.3989122
Execute143794912022-03-13 17:04:361460 days ago1647191076IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0024360928.22529502
Transfer143792512022-03-13 16:08:021460 days ago1647187682IN
0xfDAc3Fff...bB36DaB68
0.00377422 ETH0.0008624336.37110993
Execute143790912022-03-13 15:27:011460 days ago1647185221IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0012303820.44137628
Execute143612382022-03-10 20:23:471463 days ago1646943827IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0079984932.09010849
Execute143612322022-03-10 20:23:141463 days ago1646943794IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0035700543.85601649
Execute143606462022-03-10 18:16:121463 days ago1646936172IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0070768428.83319617
Execute143606362022-03-10 18:14:511463 days ago1646936091IN
0xfDAc3Fff...bB36DaB68
0 ETH0.0038815838.74877496
View all transactions

Latest 21 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer161699182022-12-12 16:49:111186 days ago1670863751
0xfDAc3Fff...bB36DaB68
0.00304257 ETH
Transfer156243662022-09-27 11:23:111262 days ago1664277791
0xfDAc3Fff...bB36DaB68
0.03310044 ETH
Transfer152580012022-08-01 17:29:011319 days ago1659374941
0xfDAc3Fff...bB36DaB68
3.40936808 ETH
Transfer150222312022-06-25 5:51:341357 days ago1656136294
0xfDAc3Fff...bB36DaB68
0.00179058 ETH
-149322212022-06-09 11:00:081372 days ago1654772408
0xfDAc3Fff...bB36DaB68
0.00350932 ETH
-147864852022-05-16 13:16:451396 days ago1652707005
0xfDAc3Fff...bB36DaB68
0.00334937 ETH
-147667542022-05-13 10:14:001399 days ago1652436840
0xfDAc3Fff...bB36DaB68
0.0269307 ETH
-143795232022-03-13 17:12:541460 days ago1647191574
0xfDAc3Fff...bB36DaB68
0.00309715 ETH
-143794912022-03-13 17:04:361460 days ago1647191076
0xfDAc3Fff...bB36DaB68
0.00297806 ETH
-143790912022-03-13 15:27:011460 days ago1647185221
0xfDAc3Fff...bB36DaB68
0.00154683 ETH
-143790912022-03-13 15:27:011460 days ago1647185221
0xfDAc3Fff...bB36DaB68
0.003 ETH
-143612382022-03-10 20:23:471463 days ago1646943827
0xfDAc3Fff...bB36DaB68
0.01090107 ETH
-143612322022-03-10 20:23:141463 days ago1646943794
0xfDAc3Fff...bB36DaB68
0.00521746 ETH
-143606462022-03-10 18:16:121463 days ago1646936172
0xfDAc3Fff...bB36DaB68
0.01512409 ETH
-143606362022-03-10 18:14:511463 days ago1646936091
0xfDAc3Fff...bB36DaB68
0.00584977 ETH
-143606232022-03-10 18:11:491463 days ago1646935909
0xfDAc3Fff...bB36DaB68
0.00769106 ETH
-143606232022-03-10 18:11:491463 days ago1646935909
0xfDAc3Fff...bB36DaB68
1.01 ETH
-143598532022-03-10 15:17:061463 days ago1646925426
0xfDAc3Fff...bB36DaB68
0.97584375 ETH
-143594562022-03-10 13:51:041463 days ago1646920264
0xfDAc3Fff...bB36DaB68
0.01066437 ETH
-143594562022-03-10 13:51:041463 days ago1646920264
0xfDAc3Fff...bB36DaB68
0.9 ETH
-143594562022-03-10 13:51:041463 days ago1646920264  Contract Creation0 ETH
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
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.