More Info
Private Name Tags
ContractCreator
Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 16857681 | 549 days ago | IN | 0.0121866 ETH | 0.00038425 | ||||
Transfer | 14855557 | 845 days ago | IN | 0.2194 ETH | 0.00088582 | ||||
Transfer | 14268065 | 937 days ago | IN | 1.6791833 ETH | 0.00107511 | ||||
Transfer | 14254735 | 939 days ago | IN | 0.01609969 ETH | 0.00135462 | ||||
Transfer | 13965945 | 984 days ago | IN | 0.00658433 ETH | 0.00246051 | ||||
Transfer | 13818985 | 1006 days ago | IN | 0.00225044 ETH | 0.00259264 |
Latest 18 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16887906 | 545 days ago | 0.00199839 ETH | ||||
16864735 | 548 days ago | 0.00584159 ETH | ||||
16857692 | 549 days ago | 0.00372578 ETH | ||||
16497516 | 600 days ago | 0 ETH | ||||
16200922 | 641 days ago | 0 ETH | ||||
16192663 | 643 days ago | 0 ETH | ||||
15982252 | 672 days ago | 0 ETH | ||||
15003436 | 820 days ago | 0 ETH | ||||
14858784 | 844 days ago | 0.00147909 ETH | ||||
14855615 | 845 days ago | 0.22173572 ETH | ||||
14391018 | 918 days ago | 0.00411234 ETH | ||||
14339560 | 926 days ago | 0.00467874 ETH | ||||
14313602 | 930 days ago | 0.0055542 ETH | ||||
14268146 | 937 days ago | 0.0222971 ETH | ||||
14268146 | 937 days ago | 1.64 ETH | ||||
14254741 | 939 days ago | 0.02366054 ETH | ||||
14254741 | 939 days ago | Contract Creation | 0 ETH | |||
14091780 | 964 days ago | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0x2a2b85eb1054d6f0c6c2e37da05ed3e5fea684ef
Contract Name:
Identity
Compiler Version
v0.8.7+commit.e28d00a7
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)"))`). } }
[{"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"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 54.05% | $0.142928 | 51,936.1507 | $7,423.13 | |
ETH | 37.00% | $0.015895 | 319,707.0061 | $5,081.76 | |
ETH | Ether (ETH) | 0.01% | $2,336.35 | 0.00062082 | $1.45 |
BSC | 4.28% | $548.97 | 1.0718 | $588.38 | |
BSC | 0.85% | $1.74 | 67.0391 | $116.65 | |
BSC | 0.68% | $549.15 | 0.1701 | $93.41 | |
OP | 2.53% | $2,336.35 | 0.1484 | $346.83 | |
OP | <0.01% | $2,336.25 | 0.0003 | $0.7008 | |
POL | 0.60% | $0.384793 | 212.4077 | $81.73 | |
POL | <0.01% | $0.015898 | 7.1606 | $0.1138 |
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.