Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
GuardianLib
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "./WalletData.sol"; import "./ApprovalLib.sol"; import "../../lib/SignatureUtil.sol"; import "../../thirdparty/SafeCast.sol"; /// @title GuardianModule /// @author Brecht Devos - <[email protected]> /// @author Daniel Wang - <[email protected]> library GuardianLib { using AddressUtil for address; using SafeCast for uint; using SignatureUtil for bytes32; using ApprovalLib for Wallet; uint public constant MAX_GUARDIANS = 10; uint public constant GUARDIAN_PENDING_PERIOD = 3 days; bytes32 public constant ADD_GUARDIAN_TYPEHASH = keccak256( "addGuardian(address wallet,uint256 validUntil,address guardian)" ); bytes32 public constant REMOVE_GUARDIAN_TYPEHASH = keccak256( "removeGuardian(address wallet,uint256 validUntil,address guardian)" ); bytes32 public constant RESET_GUARDIANS_TYPEHASH = keccak256( "resetGuardians(address wallet,uint256 validUntil,address[] guardians)" ); event GuardianAdded (address guardian, uint effectiveTime); event GuardianRemoved (address guardian, uint effectiveTime); function addGuardiansImmediately( Wallet storage wallet, address[] memory _guardians ) external { address guardian = address(0); for (uint i = 0; i < _guardians.length; i++) { require(_guardians[i] > guardian, "INVALID_ORDERING"); guardian = _guardians[i]; _addGuardian(wallet, guardian, 0, true); } } function addGuardian( Wallet storage wallet, address guardian ) external { _addGuardian(wallet, guardian, GUARDIAN_PENDING_PERIOD, false); } function addGuardianWA( Wallet storage wallet, bytes32 domainSeparator, Approval calldata approval, address guardian ) external returns (bytes32 approvedHash) { approvedHash = wallet.verifyApproval( domainSeparator, SigRequirement.MAJORITY_OWNER_REQUIRED, approval, abi.encode( ADD_GUARDIAN_TYPEHASH, approval.wallet, approval.validUntil, guardian ) ); _addGuardian(wallet, guardian, 0, true); } function removeGuardian( Wallet storage wallet, address guardian ) external { _removeGuardian(wallet, guardian, GUARDIAN_PENDING_PERIOD, false); } function removeGuardianWA( Wallet storage wallet, bytes32 domainSeparator, Approval calldata approval, address guardian ) external returns (bytes32 approvedHash) { approvedHash = wallet.verifyApproval( domainSeparator, SigRequirement.MAJORITY_OWNER_REQUIRED, approval, abi.encode( REMOVE_GUARDIAN_TYPEHASH, approval.wallet, approval.validUntil, guardian ) ); _removeGuardian(wallet, guardian, 0, true); } function resetGuardians( Wallet storage wallet, address[] calldata newGuardians ) external { Guardian[] memory allGuardians = guardians(wallet, true); for (uint i = 0; i < allGuardians.length; i++) { _removeGuardian(wallet, allGuardians[i].addr, GUARDIAN_PENDING_PERIOD, false); } for (uint j = 0; j < newGuardians.length; j++) { _addGuardian(wallet, newGuardians[j], GUARDIAN_PENDING_PERIOD, false); } } function resetGuardiansWA( Wallet storage wallet, bytes32 domainSeparator, Approval calldata approval, address[] calldata newGuardians ) external returns (bytes32 approvedHash) { approvedHash = wallet.verifyApproval( domainSeparator, SigRequirement.MAJORITY_OWNER_REQUIRED, approval, abi.encode( RESET_GUARDIANS_TYPEHASH, approval.wallet, approval.validUntil, keccak256(abi.encodePacked(newGuardians)) ) ); removeAllGuardians(wallet); for (uint i = 0; i < newGuardians.length; i++) { _addGuardian(wallet, newGuardians[i], 0, true); } } function requireMajority( Wallet storage wallet, address[] memory signers, SigRequirement requirement ) internal view returns (bool) { // We always need at least one signer if (signers.length == 0) { return false; } // Calculate total group sizes Guardian[] memory allGuardians = guardians(wallet, false); require(allGuardians.length > 0, "NO_GUARDIANS"); address lastSigner; bool walletOwnerSigned = false; address owner = wallet.owner; for (uint i = 0; i < signers.length; i++) { // Check for duplicates require(signers[i] > lastSigner, "INVALID_SIGNERS_ORDER"); lastSigner = signers[i]; if (signers[i] == owner) { walletOwnerSigned = true; } else { bool _isGuardian = false; for (uint j = 0; j < allGuardians.length; j++) { if (allGuardians[j].addr == signers[i]) { _isGuardian = true; break; } } require(_isGuardian, "SIGNER_NOT_GUARDIAN"); } } if (requirement == SigRequirement.OWNER_OR_ANY_GUARDIAN) { return signers.length == 1; } else if (requirement == SigRequirement.ANY_GUARDIAN) { require(!walletOwnerSigned, "WALLET_OWNER_SIGNATURE_NOT_ALLOWED"); return signers.length == 1; } // Check owner requirements if (requirement == SigRequirement.MAJORITY_OWNER_REQUIRED) { require(walletOwnerSigned, "WALLET_OWNER_SIGNATURE_REQUIRED"); } else if (requirement == SigRequirement.MAJORITY_OWNER_NOT_ALLOWED) { require(!walletOwnerSigned, "WALLET_OWNER_SIGNATURE_NOT_ALLOWED"); } uint numExtendedSigners = allGuardians.length; if (walletOwnerSigned) { numExtendedSigners += 1; require(signers.length > 1, "NO_GUARDIAN_SIGNED_BESIDES_OWNER"); } return signers.length >= (numExtendedSigners >> 1) + 1; } function isGuardian( Wallet storage wallet, address addr, bool includePendingAddition ) public view returns (bool) { Guardian memory g = _getGuardian(wallet, addr); return _isActiveOrPendingAddition(g, includePendingAddition); } function guardians( Wallet storage wallet, bool includePendingAddition ) public view returns (Guardian[] memory _guardians) { _guardians = new Guardian[](wallet.guardians.length); uint index = 0; for (uint i = 0; i < wallet.guardians.length; i++) { Guardian memory g = wallet.guardians[i]; if (_isActiveOrPendingAddition(g, includePendingAddition)) { _guardians[index] = g; index++; } } assembly { mstore(_guardians, index) } } function numGuardians( Wallet storage wallet, bool includePendingAddition ) public view returns (uint count) { for (uint i = 0; i < wallet.guardians.length; i++) { Guardian memory g = wallet.guardians[i]; if (_isActiveOrPendingAddition(g, includePendingAddition)) { count++; } } } function removeAllGuardians( Wallet storage wallet ) internal { uint size = wallet.guardians.length; if (size == 0) return; for (uint i = 0; i < wallet.guardians.length; i++) { delete wallet.guardianIdx[wallet.guardians[i].addr]; } delete wallet.guardians; } function cancelPendingGuardians(Wallet storage wallet) internal { bool cancelled = false; for (uint i = 0; i < wallet.guardians.length; i++) { Guardian memory g = wallet.guardians[i]; if (_isPendingAddition(g)) { wallet.guardians[i].status = uint8(GuardianStatus.REMOVE); wallet.guardians[i].timestamp = 0; cancelled = true; } if (_isPendingRemoval(g)) { wallet.guardians[i].status = uint8(GuardianStatus.ADD); wallet.guardians[i].timestamp = 0; cancelled = true; } } _cleanRemovedGuardians(wallet, true); } function storeGuardian( Wallet storage wallet, address addr, uint validSince, bool alwaysOverride ) internal returns (uint) { require(validSince >= block.timestamp, "INVALID_VALID_SINCE"); require(addr != address(0), "ZERO_ADDRESS"); require(addr != address(this), "INVALID_ADDRESS"); uint pos = wallet.guardianIdx[addr]; if (pos == 0) { // Add the new guardian Guardian memory _g = Guardian( addr, uint8(GuardianStatus.ADD), validSince.toUint64() ); wallet.guardians.push(_g); wallet.guardianIdx[addr] = wallet.guardians.length; _cleanRemovedGuardians(wallet, false); return validSince; } Guardian memory g = wallet.guardians[pos - 1]; if (_isRemoved(g)) { wallet.guardians[pos - 1].status = uint8(GuardianStatus.ADD); wallet.guardians[pos - 1].timestamp = validSince.toUint64(); return validSince; } if (_isPendingRemoval(g)) { wallet.guardians[pos - 1].status = uint8(GuardianStatus.ADD); wallet.guardians[pos - 1].timestamp = 0; return 0; } if (_isPendingAddition(g)) { if (!alwaysOverride) return g.timestamp; wallet.guardians[pos - 1].timestamp = validSince.toUint64(); return validSince; } require(_isAdded(g), "UNEXPECTED_RESULT"); return 0; } function deleteGuardian( Wallet storage wallet, address addr, uint validUntil, bool alwaysOverride ) internal returns (uint) { require(validUntil >= block.timestamp, "INVALID_VALID_UNTIL"); require(addr != address(0), "ZERO_ADDRESS"); uint pos = wallet.guardianIdx[addr]; require(pos > 0, "GUARDIAN_NOT_EXISTS"); Guardian memory g = wallet.guardians[pos - 1]; if (_isAdded(g)) { wallet.guardians[pos - 1].status = uint8(GuardianStatus.REMOVE); wallet.guardians[pos - 1].timestamp = validUntil.toUint64(); return validUntil; } if (_isPendingAddition(g)) { wallet.guardians[pos - 1].status = uint8(GuardianStatus.REMOVE); wallet.guardians[pos - 1].timestamp = 0; return 0; } if (_isPendingRemoval(g)) { if (!alwaysOverride) return g.timestamp; wallet.guardians[pos - 1].timestamp = validUntil.toUint64(); return validUntil; } require(_isRemoved(g), "UNEXPECTED_RESULT"); return 0; } // --- Internal functions --- function _addGuardian( Wallet storage wallet, address guardian, uint pendingPeriod, bool alwaysOverride ) internal { uint _numGuardians = numGuardians(wallet, true); require(_numGuardians < MAX_GUARDIANS, "TOO_MANY_GUARDIANS"); require(guardian != wallet.owner, "GUARDIAN_CAN_NOT_BE_OWNER"); uint validSince = block.timestamp; if (_numGuardians >= 2) { validSince = block.timestamp + pendingPeriod; } validSince = storeGuardian(wallet, guardian, validSince, alwaysOverride); emit GuardianAdded(guardian, validSince); } function _removeGuardian( Wallet storage wallet, address guardian, uint pendingPeriod, bool alwaysOverride ) private { uint validUntil = block.timestamp + pendingPeriod; validUntil = deleteGuardian(wallet, guardian, validUntil, alwaysOverride); emit GuardianRemoved(guardian, validUntil); } function _getGuardian( Wallet storage wallet, address addr ) private view returns (Guardian memory guardian) { uint pos = wallet.guardianIdx[addr]; if (pos > 0) { guardian = wallet.guardians[pos - 1]; } } function _isAdded(Guardian memory guardian) private view returns (bool) { return guardian.status == uint8(GuardianStatus.ADD) && guardian.timestamp <= block.timestamp; } function _isPendingAddition(Guardian memory guardian) private view returns (bool) { return guardian.status == uint8(GuardianStatus.ADD) && guardian.timestamp > block.timestamp; } function _isRemoved(Guardian memory guardian) private view returns (bool) { return guardian.status == uint8(GuardianStatus.REMOVE) && guardian.timestamp <= block.timestamp; } function _isPendingRemoval(Guardian memory guardian) private view returns (bool) { return guardian.status == uint8(GuardianStatus.REMOVE) && guardian.timestamp > block.timestamp; } function _isActive(Guardian memory guardian) private view returns (bool) { return _isAdded(guardian) || _isPendingRemoval(guardian); } function _isActiveOrPendingAddition( Guardian memory guardian, bool includePendingAddition ) private view returns (bool) { return _isActive(guardian) || includePendingAddition && _isPendingAddition(guardian); } function _cleanRemovedGuardians( Wallet storage wallet, bool force ) private { uint count = wallet.guardians.length; if (!force && count < 10) return; for (int i = int(count) - 1; i >= 0; i--) { Guardian memory g = wallet.guardians[uint(i)]; if (_isRemoved(g)) { Guardian memory lastGuardian = wallet.guardians[wallet.guardians.length - 1]; if (g.addr != lastGuardian.addr) { wallet.guardians[uint(i)] = lastGuardian; wallet.guardianIdx[lastGuardian.addr] = uint(i) + 1; } wallet.guardians.pop(); delete wallet.guardianIdx[g.addr]; } } } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; enum SigRequirement { MAJORITY_OWNER_NOT_ALLOWED, MAJORITY_OWNER_ALLOWED, MAJORITY_OWNER_REQUIRED, OWNER_OR_ANY_GUARDIAN, ANY_GUARDIAN } struct Approval { address[] signers; bytes[] signatures; uint validUntil; address wallet; } // Optimized to fit into 64 bytes (2 slots) struct Quota { uint128 currentQuota; uint128 pendingQuota; uint128 spentAmount; uint64 spentTimestamp; uint64 pendingUntil; } enum GuardianStatus { REMOVE, // Being removed or removed after validUntil timestamp ADD // Being added or added after validSince timestamp. } // Optimized to fit into 32 bytes (1 slot) struct Guardian { address addr; uint8 status; uint64 timestamp; // validSince if status = ADD; validUntil if adding = REMOVE; } struct Wallet { address owner; uint64 creationTimestamp; // relayer => nonce uint nonce; // hash => consumed mapping (bytes32 => bool) hashes; bool locked; Guardian[] guardians; mapping (address => uint) guardianIdx; address inheritor; uint32 inheritWaitingPeriod; uint64 lastActive; // the latest timestamp the owner is considered to be active Quota quota; // whitelisted address => effective timestamp mapping (address => uint) whitelisted; }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "../../lib/EIP712.sol"; import "../../lib/SignatureUtil.sol"; import "./GuardianLib.sol"; import "./WalletData.sol"; /// @title ApprovalLib /// @dev Utility library for better handling of signed wallet requests. /// This library must be deployed and linked to other modules. /// /// @author Daniel Wang - <[email protected]> library ApprovalLib { using SignatureUtil for bytes32; function verifyApproval( Wallet storage wallet, bytes32 domainSeparator, SigRequirement sigRequirement, Approval memory approval, bytes memory encodedRequest ) internal returns (bytes32 approvedHash) { require(address(this) == approval.wallet, "INVALID_WALLET"); require(block.timestamp <= approval.validUntil, "EXPIRED_SIGNED_REQUEST"); approvedHash = EIP712.hashPacked(domainSeparator, keccak256(encodedRequest)); // Save hash to prevent replay attacks require(!wallet.hashes[approvedHash], "HASH_EXIST"); wallet.hashes[approvedHash] = true; require( approvedHash.verifySignatures(approval.signers, approval.signatures), "INVALID_SIGNATURES" ); require( GuardianLib.requireMajority( wallet, approval.signers, sigRequirement ), "PERMISSION_DENIED" ); } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "../thirdparty/BytesUtil.sol"; import "./AddressUtil.sol"; import "./ERC1271.sol"; import "./MathUint.sol"; /// @title SignatureUtil /// @author Daniel Wang - <[email protected]> /// @dev This method supports multihash standard. Each signature's last byte indicates /// the signature's type. library SignatureUtil { using BytesUtil for bytes; using MathUint for uint; using AddressUtil for address; enum SignatureType { ILLEGAL, INVALID, EIP_712, ETH_SIGN, WALLET // deprecated } bytes4 constant internal ERC1271_MAGICVALUE = 0x1626ba7e; function verifySignatures( bytes32 signHash, address[] memory signers, bytes[] memory signatures ) internal view returns (bool) { require(signers.length == signatures.length, "BAD_SIGNATURE_DATA"); address lastSigner; for (uint i = 0; i < signers.length; i++) { require(signers[i] > lastSigner, "INVALID_SIGNERS_ORDER"); lastSigner = signers[i]; if (!verifySignature(signHash, signers[i], signatures[i])) { return false; } } return true; } function verifySignature( bytes32 signHash, address signer, bytes memory signature ) internal view returns (bool) { if (signer == address(0)) { return false; } return signer.isContract()? verifyERC1271Signature(signHash, signer, signature): verifyEOASignature(signHash, signer, signature); } function recoverECDSASigner( bytes32 signHash, bytes memory signature ) internal pure returns (address) { if (signature.length != 65) { return address(0); } bytes32 r; bytes32 s; uint8 v; // we jump 32 (0x20) as the first slot of bytes contains the length // we jump 65 (0x41) per signature // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := and(mload(add(signature, 0x41)), 0xff) } // See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return address(0); } if (v == 27 || v == 28) { return ecrecover(signHash, v, r, s); } else { return address(0); } } function verifyEOASignature( bytes32 signHash, address signer, bytes memory signature ) private pure returns (bool success) { if (signer == address(0)) { return false; } uint signatureTypeOffset = signature.length.sub(1); SignatureType signatureType = SignatureType(signature.toUint8(signatureTypeOffset)); // Strip off the last byte of the signature by updating the length assembly { mstore(signature, signatureTypeOffset) } if (signatureType == SignatureType.EIP_712) { success = (signer == recoverECDSASigner(signHash, signature)); } else if (signatureType == SignatureType.ETH_SIGN) { bytes32 hash = keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", signHash) ); success = (signer == recoverECDSASigner(hash, signature)); } else { success = false; } // Restore the signature length assembly { mstore(signature, add(signatureTypeOffset, 1)) } return success; } function verifyERC1271Signature( bytes32 signHash, address signer, bytes memory signature ) private view returns (bool) { bytes memory callData = abi.encodeWithSelector( ERC1271.isValidSignature.selector, signHash, signature ); (bool success, bytes memory result) = signer.staticcall(callData); return ( success && result.length == 32 && result.toBytes4(0) == ERC1271_MAGICVALUE ); } }
// SPDX-License-Identifier: MIT // Taken from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value < 2**96, "SafeCast: value doesn\'t fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { require(value < 2**40, "SafeCast: value doesn\'t fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { require(value < 2**255, "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; library EIP712 { struct Domain { string name; string version; address verifyingContract; } bytes32 constant internal EIP712_DOMAIN_TYPEHASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); string constant internal EIP191_HEADER = "\x19\x01"; function hash(Domain memory domain) internal pure returns (bytes32) { uint _chainid; assembly { _chainid := chainid() } return keccak256( abi.encode( EIP712_DOMAIN_TYPEHASH, keccak256(bytes(domain.name)), keccak256(bytes(domain.version)), _chainid, domain.verifyingContract ) ); } function hashPacked( bytes32 domainSeparator, bytes32 dataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( EIP191_HEADER, domainSeparator, dataHash ) ); } }
// SPDX-License-Identifier: UNLICENSED // Taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol pragma solidity ^0.7.0; library BytesUtil { function slice( bytes memory _bytes, uint _start, uint _length ) internal pure returns (bytes memory) { require(_bytes.length >= (_start + _length)); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) { require(_bytes.length >= (_start + 20)); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) { require(_bytes.length >= (_start + 1)); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) { require(_bytes.length >= (_start + 2)); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint24(bytes memory _bytes, uint _start) internal pure returns (uint24) { require(_bytes.length >= (_start + 3)); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) { require(_bytes.length >= (_start + 4)); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) { require(_bytes.length >= (_start + 8)); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) { require(_bytes.length >= (_start + 12)); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) { require(_bytes.length >= (_start + 16)); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint(bytes memory _bytes, uint _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32)); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes4(bytes memory _bytes, uint _start) internal pure returns (bytes4) { require(_bytes.length >= (_start + 4)); bytes4 tempBytes4; assembly { tempBytes4 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes4; } function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) { require(_bytes.length >= (_start + 32)); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function fastSHA256( bytes memory data ) internal view returns (bytes32) { bytes32[] memory result = new bytes32[](1); bool success; assembly { let ptr := add(data, 32) success := staticcall(sub(gas(), 2000), 2, ptr, mload(data), add(result, 32), 32) } require(success, "SHA256_FAILED"); return result[0]; } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title Utility Functions for addresses /// @author Daniel Wang - <[email protected]> /// @author Brecht Devos - <[email protected]> library AddressUtil { using AddressUtil for *; function isContract( address addr ) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(addr) } return (codehash != 0x0 && codehash != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470); } function toPayable( address addr ) internal pure returns (address payable) { return payable(addr); } // Works like address.send but with a customizable gas limit // Make sure your code is safe for reentrancy when using this function! function sendETH( address to, uint amount, uint gasLimit ) internal returns (bool success) { if (amount == 0) { return true; } address payable recipient = to.toPayable(); /* solium-disable-next-line */ (success,) = recipient.call{value: amount, gas: gasLimit}(""); } // Works like address.transfer but with a customizable gas limit // Make sure your code is safe for reentrancy when using this function! function sendETHAndVerify( address to, uint amount, uint gasLimit ) internal returns (bool success) { success = to.sendETH(amount, gasLimit); require(success, "TRANSFER_FAILURE"); } // Works like call but is slightly more efficient when data // needs to be copied from memory to do the call. function fastCall( address to, uint gasLimit, uint value, bytes memory data ) internal returns (bool success, bytes memory returnData) { if (to != address(0)) { assembly { // Do the call success := call(gasLimit, to, value, add(data, 32), mload(data), 0, 0) // Copy the return data let size := returndatasize() returnData := mload(0x40) mstore(returnData, size) returndatacopy(add(returnData, 32), 0, size) // Update free memory pointer mstore(0x40, add(returnData, add(32, size))) } } } // Like fastCall, but throws when the call is unsuccessful. function fastCallAndVerify( address to, uint gasLimit, uint value, bytes memory data ) internal returns (bytes memory returnData) { bool success; (success, returnData) = fastCall(to, gasLimit, value, data); if (!success) { assembly { revert(add(returnData, 32), mload(returnData)) } } } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; abstract contract ERC1271 { // bytes4(keccak256("isValidSignature(bytes32,bytes)") bytes4 constant internal ERC1271_MAGICVALUE = 0x1626ba7e; function isValidSignature( bytes32 _hash, bytes memory _signature) public view virtual returns (bytes4 magicValue); }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title Utility Functions for uint /// @author Daniel Wang - <[email protected]> library MathUint { function mul( uint a, uint b ) internal pure returns (uint c) { c = a * b; require(a == 0 || c / a == b, "MUL_OVERFLOW"); } function sub( uint a, uint b ) internal pure returns (uint) { require(b <= a, "SUB_UNDERFLOW"); return a - b; } function add( uint a, uint b ) internal pure returns (uint c) { c = a + b; require(c >= a, "ADD_OVERFLOW"); } }
{ "optimizer": { "enabled": true, "runs": 100000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"effectiveTime","type":"uint256"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"effectiveTime","type":"uint256"}],"name":"GuardianRemoved","type":"event"},{"inputs":[],"name":"ADD_GUARDIAN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GUARDIAN_PENDING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_GUARDIANS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REMOVE_GUARDIAN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESET_GUARDIANS_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
612ed2610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100ff5760003560e01c8063a643b107116100a1578063d132d1db11610070578063d132d1db14610234578063dd2225f81461023c578063ee3da3e31461024f578063f26cfb661461026f576100ff565b8063a643b107146101cc578063abe61cdd146101ec578063b4f212fa146101f4578063b9d8df1414610214576100ff565b8063422c1d37116100dd578063422c1d371461017c5780637abbb0d514610184578063912fce541461018c5780639668d94c146101ac576100ff565b806318d9ad711461010457806328c809351461012d5780633140f8cf1461014f575b600080fd5b61011761011236600461257b565b610277565b604051610124919061275e565b60405180910390f35b81801561013957600080fd5b5061014d6101483660046124ec565b6103b5565b005b81801561015b57600080fd5b5061016f61016a3660046125fc565b61044a565b60405161012491906127e5565b61016f61055b565b61016f610560565b81801561019857600080fd5b5061016f6101a736600461259d565b610584565b8180156101b857600080fd5b5061016f6101c736600461259d565b61062f565b6101df6101da3660046124b1565b610681565b60405161012491906127da565b61016f6106a5565b81801561020057600080fd5b5061014d61020f366004612536565b6106c9565b81801561022057600080fd5b5061014d61022f366004612486565b610789565b61016f61079d565b61016f61024a36600461257b565b6107c1565b81801561025b57600080fd5b5061014d61026a366004612486565b61088a565b61016f61089a565b600482015460609067ffffffffffffffff8111801561029557600080fd5b506040519080825280602002602001820160405280156102cf57816020015b6102bc612222565b8152602001906001900390816102b45790505b5090506000805b60048501548110156103ac5760008560040182815481106102f357fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff75010000000000000000000000000000000000000000009093049290921690820152905061037f81866108a1565b156103a3578084848151811061039157fe5b60209081029190910101526001909201915b506001016102d6565b50815292915050565b60006103c2846001610277565b905060005b81518110156103ff576103f7858383815181106103e057fe5b6020026020010151600001516203f48060006108cc565b6001016103c7565b5060005b828110156104435761043b8585858481811061041b57fe5b9050602002016020810190610430919061246c565b6203f480600061091d565b600101610403565b5050505050565b600061050585600261045b87612db2565b7f102814d4a80680694a960b0e7e29965fdc37164004692cb5868555ae49f38d4561048c60808a0160608b0161246c565b896040013589896040516020016104a4929190612677565b604051602081830303815290604052805190602001206040516020016104cd9493929190612822565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528a93929190610a17565b905061051086610bf0565b60005b82811015610551576105498785858481811061052b57fe5b9050602002016020810190610540919061246c565b6000600161091d565b600101610513565b5095945050505050565b600a81565b7fc2d601f9b2c71cd1f247d67d83d55307ed88800236d40a2069c0a6d2b207ef8481565b600061061784600261059586612db2565b7fc2d601f9b2c71cd1f247d67d83d55307ed88800236d40a2069c0a6d2b207ef846105c66080890160608a0161246c565b8860400135886040516020016105df94939291906127ee565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528993929190610a17565b90506106278583600060016108cc565b949350505050565b600061067184600261064086612db2565b7f3aea25321405f61fb6d5dfb4b53be5d64671d80dc2149264e167060f5996b67a6105c66080890160608a0161246c565b905061062785836000600161091d565b60008061068e8585610c70565b905061069a81846108a1565b9150505b9392505050565b7f102814d4a80680694a960b0e7e29965fdc37164004692cb5868555ae49f38d4581565b6000805b8251811015610783578173ffffffffffffffffffffffffffffffffffffffff168382815181106106f957fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1611610757576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c94565b60405180910390fd5b82818151811061076357fe5b6020026020010151915061077b84836000600161091d565b6001016106cd565b50505050565b61079982826203f480600061091d565b5050565b7f3aea25321405f61fb6d5dfb4b53be5d64671d80dc2149264e167060f5996b67a81565b6000805b60048401548110156108835760008460040182815481106107e257fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff75010000000000000000000000000000000000000000009093049290921690820152905061086e81856108a1565b1561087a576001909201915b506001016107c5565b5092915050565b61079982826203f48060006108cc565b6203f48081565b60006108ac83610d40565b806108c357508180156108c357506108c383610d62565b90505b92915050565b4282016108db85858385610d90565b90507fbc92161fee7c8f66fcc67cb974d0c9b1439030462bd0d5201c21b01f89355b23848260405161090e929190612738565b60405180910390a15050505050565b600061092a8560016107c1565b9050600a8110610966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c00565b845473ffffffffffffffffffffffffffffffffffffffff858116911614156109ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612d39565b42600282106109c857504283015b6109d4868683866110c7565b90507f6276832b43b1ca1eab9c38b577dc5ba939a807f5ca7b7e5b6f1f09e80e487fad8582604051610a07929190612738565b60405180910390a1505050505050565b6000826060015173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612b5b565b8260400151421115610ac0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e9061296e565b610ad185838051906020012061141f565b600081815260028801602052604090205490915060ff1615610b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612d02565b6000818152600287016020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055835190840151610b6c918391611489565b610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612ccb565b610bb1868460000151866115b5565b610be7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612a4a565b95945050505050565b600481015480610c005750610c6d565b60005b6004830154811015610c5e57826005016000846004018381548110610c2457fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101610c03565b50610799600483016000612242565b50565b610c78612222565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600584016020526040902054801561088357836004016001820381548110610cb857fe5b600091825260209182902060408051606081018252929091015473ffffffffffffffffffffffffffffffffffffffff8116835274010000000000000000000000000000000000000000810460ff1693830193909352750100000000000000000000000000000000000000000090920467ffffffffffffffff1691810191909152949350505050565b6000610d4b82611957565b80610d5a5750610d5a82611986565b90505b919050565b600060015b60ff16826020015160ff16148015610d5a575050604001514267ffffffffffffffff9091161190565b600042831015610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e906128c9565b73ffffffffffffffffffffffffffffffffffffffff8416610e19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612ab8565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260058601602052604090205480610e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612bc9565b6000866004016001830381548110610e8c57fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff750100000000000000000000000000000000000000000090930492909216908201529050610f1781611957565b15610fae5760005b876004016001840381548110610f3157fe5b9060005260206000200160000160146101000a81548160ff021916908360ff160217905550610f5f8561198e565b876004016001840381548110610f7157fe5b9060005260206000200160000160156101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508492505050610627565b610fb781610d62565b156110485760005b876004016001840381548110610fd157fe5b9060005260206000200160000160146101000a81548160ff021916908360ff160217905550600087600401600184038154811061100a57fe5b9060005260206000200160000160156101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600092505050610627565b61105181611986565b1561107b5783611072576040015167ffffffffffffffff1691506106279050565b610f5f8561198e565b611084816119f5565b6110ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612937565b5060009695505050505050565b600042831015611103576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612b92565b73ffffffffffffffffffffffffffffffffffffffff8416611150576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612ab8565b73ffffffffffffffffffffffffffffffffffffffff84163014156111a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612900565b73ffffffffffffffffffffffffffffffffffffffff841660009081526005860160205260409020548061132c576040805160608101825273ffffffffffffffffffffffffffffffffffffffff871681526001602082015260009181016112058761198e565b67ffffffffffffffff90811690915260048901805460018101825560008281526020808220865193018054828801516040808a01519098167501000000000000000000000000000000000000000000027fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff60ff90921674010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff9889167fffffffffffffffffffffffff0000000000000000000000000000000000000000909516949094179390931692909217161790559254918b16815260058c01909252918120919091559091506113229088906119fd565b8492505050610627565b600086600401600183038154811061134057fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff7501000000000000000000000000000000000000000000909304929092169082015290506113cb816119f5565b156113d7576001610f1f565b6113e081611986565b156113ec576001610fbf565b6113f581610d62565b156114165783611072576040015167ffffffffffffffff1691506106279050565b61108481611957565b60006040518060400160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250838360405160200161146b939291906126e0565b60405160208183030381529060405280519060200120905092915050565b600081518351146114c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e906129dc565b6000805b84518110156115a9578173ffffffffffffffffffffffffffffffffffffffff168582815181106114f657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff161161154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612aef565b84818151811061155757fe5b602002602001015191506115928686838151811061157157fe5b602002602001015186848151811061158557fe5b6020026020010151611d6d565b6115a15760009250505061069e565b6001016114ca565b50600195945050505050565b60008251600014156115c95750600061069e565b60006115d6856000610277565b90506000815111611613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612a81565b8454600090819073ffffffffffffffffffffffffffffffffffffffff16815b87518110156117d7578373ffffffffffffffffffffffffffffffffffffffff1688828151811061165e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16116116b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612aef565b8781815181106116bf57fe5b602002602001015193508173ffffffffffffffffffffffffffffffffffffffff168882815181106116ec57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16141561171957600192506117cf565b6000805b86518110156117955789838151811061173257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687828151811061175c57fe5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16141561178d5760019150611795565b60010161171d565b50806117cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e906129a5565b505b600101611632565b5060038660048111156117e657fe5b14156117fc57865160011494505050505061069e565b600486600481111561180a57fe5b1415611858578115611848576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c37565b865160011494505050505061069e565b600286600481111561186657fe5b14156118a857816118a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612a13565b6118f4565b60008660048111156118b657fe5b14156118f45781156118f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c37565b8351821561193d57600181019050600188511161193d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612b26565b600181901c60010188511015955050505050509392505050565b600060015b60ff16826020015160ff16148015610d5a575050604001514267ffffffffffffffff909116111590565b600080610d67565b60006801000000000000000082106119f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612e776026913960400191505060405180910390fd5b5090565b60008061195c565b600482015481158015611a105750600a81105b15611a1b5750610799565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81015b60008112610783576000846004018281548110611a5857fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff750100000000000000000000000000000000000000000090930492909216908201529050611ae3816119f5565b15611d4557600485018054600091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110611b1e57fe5b600091825260209182902060408051606081018252929091015473ffffffffffffffffffffffffffffffffffffffff80821680855274010000000000000000000000000000000000000000830460ff1695850195909552750100000000000000000000000000000000000000000090910467ffffffffffffffff169183019190915284519193501614611cb55780866004018481548110611bbb57fe5b60009182526020808320845192018054858301516040968701517fffffffffffffffffffffffff000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff958616177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff90921691909102177fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000067ffffffffffffffff9092169190910217905584519091168252600589019052206001840190555b85600401805480611cc257fe5b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffff0000000000000000000000000000000000000000000000000000000000169055909201909255835173ffffffffffffffffffffffffffffffffffffffff1682526005880190526040812055505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611a3f565b600073ffffffffffffffffffffffffffffffffffffffff8316611d925750600061069e565b611db18373ffffffffffffffffffffffffffffffffffffffff16611dd0565b611dc557611dc0848484611e07565b610627565b610627848484611f41565b6000813f801580159061069e57507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b600073ffffffffffffffffffffffffffffffffffffffff8316611e2c5750600061069e565b8151600090611e3c90600161209b565b90506000611e4a8483612112565b60ff166004811115611e5857fe5b82855290506002816004811115611e6b57fe5b1415611eb057611e7b868561212e565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16149250611f34565b6003816004811115611ebe57fe5b1415611f2f57600086604051602001611ed79190612707565b604051602081830303815290604052805190602001209050611ef9818661212e565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614935050611f34565b600092505b5060010182529392505050565b600080631626ba7e60e01b8584604051602401611f5f929190612853565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808573ffffffffffffffffffffffffffffffffffffffff1683604051611fe691906126c4565b600060405180830381855afa9150503d8060008114612021576040519150601f19603f3d011682016040523d82523d6000602084013e612026565b606091505b5091509150818015612039575080516020145b801561209057507f1626ba7e0000000000000000000000000000000000000000000000000000000061206c826000612206565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b979650505050505050565b60008282111561210c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f5355425f554e444552464c4f5700000000000000000000000000000000000000604482015290519081900360640190fd5b50900390565b6000816001018351101561212557600080fd5b50016001015190565b60008151604114612141575060006108c6565b60208201516040830151604184015160ff167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561218757600093505050506108c6565b8060ff16601b148061219c57508060ff16601c145b156121fa57600186828585604051600081526020016040526040516121c494939291906128ab565b6020604051602081039080840390855afa1580156121e6573d6000803e3d6000fd5b5050506020604051035193505050506108c6565b600093505050506108c6565b6000816004018351101561221957600080fd5b50016020015190565b604080516060810182526000808252602082018190529181019190915290565b5080546000825590600052602060002090810190610c6d91905b808211156119f15780547fffffff000000000000000000000000000000000000000000000000000000000016815560010161225c565b803573ffffffffffffffffffffffffffffffffffffffff81168114610d5d57600080fd5b60008083601f8401126122c7578182fd5b50813567ffffffffffffffff8111156122de578182fd5b60208301915083602080830285010111156122f857600080fd5b9250929050565b600082601f83011261230f578081fd5b8135602061232461231f83612d94565b612d70565b8281528181019085830183850287018401881015612340578586fd5b855b858110156123655761235382612292565b84529284019290840190600101612342565b5090979650505050505050565b6000601f8381840112612383578182fd5b8235602061239361231f83612d94565b82815281810190868301865b8581101561243757813589018a603f8201126123b9578889fd5b85810135604067ffffffffffffffff8211156123d157fe5b612400887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601612d70565b8281528d82848601011115612413578b8cfd5b828285018a83013791820188018b905250855250928401929084019060010161239f565b509098975050505050505050565b80358015158114610d5d57600080fd5b600060808284031215612466578081fd5b50919050565b60006020828403121561247d578081fd5b6108c382612292565b60008060408385031215612498578081fd5b823591506124a860208401612292565b90509250929050565b6000806000606084860312156124c5578081fd5b833592506124d560208501612292565b91506124e360408501612445565b90509250925092565b600080600060408486031215612500578283fd5b83359250602084013567ffffffffffffffff81111561251d578283fd5b612529868287016122b6565b9497909650939450505050565b60008060408385031215612548578182fd5b82359150602083013567ffffffffffffffff811115612565578182fd5b612571858286016122ff565b9150509250929050565b6000806040838503121561258d578182fd5b823591506124a860208401612445565b600080600080608085870312156125b2578081fd5b8435935060208501359250604085013567ffffffffffffffff8111156125d6578182fd5b6125e287828801612455565b9250506125f160608601612292565b905092959194509250565b600080600080600060808688031215612613578081fd5b8535945060208601359350604086013567ffffffffffffffff80821115612638578283fd5b61264489838a01612455565b94506060880135915080821115612659578283fd5b50612666888289016122b6565b969995985093965092949392505050565b60008184825b858110156126b95773ffffffffffffffffffffffffffffffffffffffff6126a383612292565b168352602092830192919091019060010161267d565b509095945050505050565b600082516126d6818460208701612e4a565b9190910192915050565b600084516126f2818460208901612e4a565b91909101928352506020820152604001919050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b828110156127cd578151805173ffffffffffffffffffffffffffffffffffffffff1685528681015160ff168786015285015167ffffffffffffffff16858501526060909301929085019060010161277b565b5091979650505050505050565b901515815260200190565b90815260200190565b93845273ffffffffffffffffffffffffffffffffffffffff9283166020850152604084019190915216606082015260800190565b93845273ffffffffffffffffffffffffffffffffffffffff9290921660208401526040830152606082015260800190565b6000838252604060208301528251806040840152612878816060850160208701612e4a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b93845260ff9290921660208401526040830152606082015260800190565b60208082526013908201527f494e56414c49445f56414c49445f554e54494c00000000000000000000000000604082015260600190565b6020808252600f908201527f494e56414c49445f414444524553530000000000000000000000000000000000604082015260600190565b60208082526011908201527f554e45585045435445445f524553554c54000000000000000000000000000000604082015260600190565b60208082526016908201527f455850495245445f5349474e45445f5245515545535400000000000000000000604082015260600190565b60208082526013908201527f5349474e45525f4e4f545f475541524449414e00000000000000000000000000604082015260600190565b60208082526012908201527f4241445f5349474e41545552455f444154410000000000000000000000000000604082015260600190565b6020808252601f908201527f57414c4c45545f4f574e45525f5349474e41545552455f524551554952454400604082015260600190565b60208082526011908201527f5045524d495353494f4e5f44454e494544000000000000000000000000000000604082015260600190565b6020808252600c908201527f4e4f5f475541524449414e530000000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f5a45524f5f414444524553530000000000000000000000000000000000000000604082015260600190565b60208082526015908201527f494e56414c49445f5349474e4552535f4f524445520000000000000000000000604082015260600190565b6020808252818101527f4e4f5f475541524449414e5f5349474e45445f424553494445535f4f574e4552604082015260600190565b6020808252600e908201527f494e56414c49445f57414c4c4554000000000000000000000000000000000000604082015260600190565b60208082526013908201527f494e56414c49445f56414c49445f53494e434500000000000000000000000000604082015260600190565b60208082526013908201527f475541524449414e5f4e4f545f45584953545300000000000000000000000000604082015260600190565b60208082526012908201527f544f4f5f4d414e595f475541524449414e530000000000000000000000000000604082015260600190565b60208082526022908201527f57414c4c45545f4f574e45525f5349474e41545552455f4e4f545f414c4c4f5760408201527f4544000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526010908201527f494e56414c49445f4f52444552494e4700000000000000000000000000000000604082015260600190565b60208082526012908201527f494e56414c49445f5349474e4154555245530000000000000000000000000000604082015260600190565b6020808252600a908201527f484153485f455849535400000000000000000000000000000000000000000000604082015260600190565b60208082526019908201527f475541524449414e5f43414e5f4e4f545f42455f4f574e455200000000000000604082015260600190565b60405181810167ffffffffffffffff81118282101715612d8c57fe5b604052919050565b600067ffffffffffffffff821115612da857fe5b5060209081020190565b600060808236031215612dc3578081fd5b6040516080810167ffffffffffffffff8282108183111715612de157fe5b816040528435915080821115612df5578384fd5b612e01368387016122ff565b83526020850135915080821115612e16578384fd5b50612e2336828601612372565b60208301525060408301356040820152612e3f60608401612292565b606082015292915050565b60005b83811015612e65578181015183820152602001612e4d565b83811115610783575050600091015256fe53616665436173743a2076616c756520646f65736e27742066697420696e2036342062697473a264697066735822122032de4f17b1ee9c352873347acdc3586968a6c4debfdd725595ed5b41a4bf9a1d64736f6c63430007060033
Deployed Bytecode
0x7368d9686e4b4706c425e91e4cf762c09d7686cde730146080604052600436106100ff5760003560e01c8063a643b107116100a1578063d132d1db11610070578063d132d1db14610234578063dd2225f81461023c578063ee3da3e31461024f578063f26cfb661461026f576100ff565b8063a643b107146101cc578063abe61cdd146101ec578063b4f212fa146101f4578063b9d8df1414610214576100ff565b8063422c1d37116100dd578063422c1d371461017c5780637abbb0d514610184578063912fce541461018c5780639668d94c146101ac576100ff565b806318d9ad711461010457806328c809351461012d5780633140f8cf1461014f575b600080fd5b61011761011236600461257b565b610277565b604051610124919061275e565b60405180910390f35b81801561013957600080fd5b5061014d6101483660046124ec565b6103b5565b005b81801561015b57600080fd5b5061016f61016a3660046125fc565b61044a565b60405161012491906127e5565b61016f61055b565b61016f610560565b81801561019857600080fd5b5061016f6101a736600461259d565b610584565b8180156101b857600080fd5b5061016f6101c736600461259d565b61062f565b6101df6101da3660046124b1565b610681565b60405161012491906127da565b61016f6106a5565b81801561020057600080fd5b5061014d61020f366004612536565b6106c9565b81801561022057600080fd5b5061014d61022f366004612486565b610789565b61016f61079d565b61016f61024a36600461257b565b6107c1565b81801561025b57600080fd5b5061014d61026a366004612486565b61088a565b61016f61089a565b600482015460609067ffffffffffffffff8111801561029557600080fd5b506040519080825280602002602001820160405280156102cf57816020015b6102bc612222565b8152602001906001900390816102b45790505b5090506000805b60048501548110156103ac5760008560040182815481106102f357fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff75010000000000000000000000000000000000000000009093049290921690820152905061037f81866108a1565b156103a3578084848151811061039157fe5b60209081029190910101526001909201915b506001016102d6565b50815292915050565b60006103c2846001610277565b905060005b81518110156103ff576103f7858383815181106103e057fe5b6020026020010151600001516203f48060006108cc565b6001016103c7565b5060005b828110156104435761043b8585858481811061041b57fe5b9050602002016020810190610430919061246c565b6203f480600061091d565b600101610403565b5050505050565b600061050585600261045b87612db2565b7f102814d4a80680694a960b0e7e29965fdc37164004692cb5868555ae49f38d4561048c60808a0160608b0161246c565b896040013589896040516020016104a4929190612677565b604051602081830303815290604052805190602001206040516020016104cd9493929190612822565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528a93929190610a17565b905061051086610bf0565b60005b82811015610551576105498785858481811061052b57fe5b9050602002016020810190610540919061246c565b6000600161091d565b600101610513565b5095945050505050565b600a81565b7fc2d601f9b2c71cd1f247d67d83d55307ed88800236d40a2069c0a6d2b207ef8481565b600061061784600261059586612db2565b7fc2d601f9b2c71cd1f247d67d83d55307ed88800236d40a2069c0a6d2b207ef846105c66080890160608a0161246c565b8860400135886040516020016105df94939291906127ee565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528993929190610a17565b90506106278583600060016108cc565b949350505050565b600061067184600261064086612db2565b7f3aea25321405f61fb6d5dfb4b53be5d64671d80dc2149264e167060f5996b67a6105c66080890160608a0161246c565b905061062785836000600161091d565b60008061068e8585610c70565b905061069a81846108a1565b9150505b9392505050565b7f102814d4a80680694a960b0e7e29965fdc37164004692cb5868555ae49f38d4581565b6000805b8251811015610783578173ffffffffffffffffffffffffffffffffffffffff168382815181106106f957fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1611610757576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c94565b60405180910390fd5b82818151811061076357fe5b6020026020010151915061077b84836000600161091d565b6001016106cd565b50505050565b61079982826203f480600061091d565b5050565b7f3aea25321405f61fb6d5dfb4b53be5d64671d80dc2149264e167060f5996b67a81565b6000805b60048401548110156108835760008460040182815481106107e257fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff75010000000000000000000000000000000000000000009093049290921690820152905061086e81856108a1565b1561087a576001909201915b506001016107c5565b5092915050565b61079982826203f48060006108cc565b6203f48081565b60006108ac83610d40565b806108c357508180156108c357506108c383610d62565b90505b92915050565b4282016108db85858385610d90565b90507fbc92161fee7c8f66fcc67cb974d0c9b1439030462bd0d5201c21b01f89355b23848260405161090e929190612738565b60405180910390a15050505050565b600061092a8560016107c1565b9050600a8110610966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c00565b845473ffffffffffffffffffffffffffffffffffffffff858116911614156109ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612d39565b42600282106109c857504283015b6109d4868683866110c7565b90507f6276832b43b1ca1eab9c38b577dc5ba939a807f5ca7b7e5b6f1f09e80e487fad8582604051610a07929190612738565b60405180910390a1505050505050565b6000826060015173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612b5b565b8260400151421115610ac0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e9061296e565b610ad185838051906020012061141f565b600081815260028801602052604090205490915060ff1615610b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612d02565b6000818152600287016020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055835190840151610b6c918391611489565b610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612ccb565b610bb1868460000151866115b5565b610be7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612a4a565b95945050505050565b600481015480610c005750610c6d565b60005b6004830154811015610c5e57826005016000846004018381548110610c2457fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101610c03565b50610799600483016000612242565b50565b610c78612222565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600584016020526040902054801561088357836004016001820381548110610cb857fe5b600091825260209182902060408051606081018252929091015473ffffffffffffffffffffffffffffffffffffffff8116835274010000000000000000000000000000000000000000810460ff1693830193909352750100000000000000000000000000000000000000000090920467ffffffffffffffff1691810191909152949350505050565b6000610d4b82611957565b80610d5a5750610d5a82611986565b90505b919050565b600060015b60ff16826020015160ff16148015610d5a575050604001514267ffffffffffffffff9091161190565b600042831015610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e906128c9565b73ffffffffffffffffffffffffffffffffffffffff8416610e19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612ab8565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260058601602052604090205480610e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612bc9565b6000866004016001830381548110610e8c57fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff750100000000000000000000000000000000000000000090930492909216908201529050610f1781611957565b15610fae5760005b876004016001840381548110610f3157fe5b9060005260206000200160000160146101000a81548160ff021916908360ff160217905550610f5f8561198e565b876004016001840381548110610f7157fe5b9060005260206000200160000160156101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508492505050610627565b610fb781610d62565b156110485760005b876004016001840381548110610fd157fe5b9060005260206000200160000160146101000a81548160ff021916908360ff160217905550600087600401600184038154811061100a57fe5b9060005260206000200160000160156101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600092505050610627565b61105181611986565b1561107b5783611072576040015167ffffffffffffffff1691506106279050565b610f5f8561198e565b611084816119f5565b6110ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612937565b5060009695505050505050565b600042831015611103576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612b92565b73ffffffffffffffffffffffffffffffffffffffff8416611150576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612ab8565b73ffffffffffffffffffffffffffffffffffffffff84163014156111a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612900565b73ffffffffffffffffffffffffffffffffffffffff841660009081526005860160205260409020548061132c576040805160608101825273ffffffffffffffffffffffffffffffffffffffff871681526001602082015260009181016112058761198e565b67ffffffffffffffff90811690915260048901805460018101825560008281526020808220865193018054828801516040808a01519098167501000000000000000000000000000000000000000000027fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff60ff90921674010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff9889167fffffffffffffffffffffffff0000000000000000000000000000000000000000909516949094179390931692909217161790559254918b16815260058c01909252918120919091559091506113229088906119fd565b8492505050610627565b600086600401600183038154811061134057fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff7501000000000000000000000000000000000000000000909304929092169082015290506113cb816119f5565b156113d7576001610f1f565b6113e081611986565b156113ec576001610fbf565b6113f581610d62565b156114165783611072576040015167ffffffffffffffff1691506106279050565b61108481611957565b60006040518060400160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250838360405160200161146b939291906126e0565b60405160208183030381529060405280519060200120905092915050565b600081518351146114c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e906129dc565b6000805b84518110156115a9578173ffffffffffffffffffffffffffffffffffffffff168582815181106114f657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff161161154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612aef565b84818151811061155757fe5b602002602001015191506115928686838151811061157157fe5b602002602001015186848151811061158557fe5b6020026020010151611d6d565b6115a15760009250505061069e565b6001016114ca565b50600195945050505050565b60008251600014156115c95750600061069e565b60006115d6856000610277565b90506000815111611613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612a81565b8454600090819073ffffffffffffffffffffffffffffffffffffffff16815b87518110156117d7578373ffffffffffffffffffffffffffffffffffffffff1688828151811061165e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16116116b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612aef565b8781815181106116bf57fe5b602002602001015193508173ffffffffffffffffffffffffffffffffffffffff168882815181106116ec57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16141561171957600192506117cf565b6000805b86518110156117955789838151811061173257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687828151811061175c57fe5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16141561178d5760019150611795565b60010161171d565b50806117cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e906129a5565b505b600101611632565b5060038660048111156117e657fe5b14156117fc57865160011494505050505061069e565b600486600481111561180a57fe5b1415611858578115611848576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c37565b865160011494505050505061069e565b600286600481111561186657fe5b14156118a857816118a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612a13565b6118f4565b60008660048111156118b657fe5b14156118f45781156118f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612c37565b8351821561193d57600181019050600188511161193d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074e90612b26565b600181901c60010188511015955050505050509392505050565b600060015b60ff16826020015160ff16148015610d5a575050604001514267ffffffffffffffff909116111590565b600080610d67565b60006801000000000000000082106119f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612e776026913960400191505060405180910390fd5b5090565b60008061195c565b600482015481158015611a105750600a81105b15611a1b5750610799565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81015b60008112610783576000846004018281548110611a5857fe5b600091825260209182902060408051606081018252919092015473ffffffffffffffffffffffffffffffffffffffff8116825260ff740100000000000000000000000000000000000000008204169382019390935267ffffffffffffffff750100000000000000000000000000000000000000000090930492909216908201529050611ae3816119f5565b15611d4557600485018054600091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110611b1e57fe5b600091825260209182902060408051606081018252929091015473ffffffffffffffffffffffffffffffffffffffff80821680855274010000000000000000000000000000000000000000830460ff1695850195909552750100000000000000000000000000000000000000000090910467ffffffffffffffff169183019190915284519193501614611cb55780866004018481548110611bbb57fe5b60009182526020808320845192018054858301516040968701517fffffffffffffffffffffffff000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff958616177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff90921691909102177fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000067ffffffffffffffff9092169190910217905584519091168252600589019052206001840190555b85600401805480611cc257fe5b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffff0000000000000000000000000000000000000000000000000000000000169055909201909255835173ffffffffffffffffffffffffffffffffffffffff1682526005880190526040812055505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611a3f565b600073ffffffffffffffffffffffffffffffffffffffff8316611d925750600061069e565b611db18373ffffffffffffffffffffffffffffffffffffffff16611dd0565b611dc557611dc0848484611e07565b610627565b610627848484611f41565b6000813f801580159061069e57507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b600073ffffffffffffffffffffffffffffffffffffffff8316611e2c5750600061069e565b8151600090611e3c90600161209b565b90506000611e4a8483612112565b60ff166004811115611e5857fe5b82855290506002816004811115611e6b57fe5b1415611eb057611e7b868561212e565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16149250611f34565b6003816004811115611ebe57fe5b1415611f2f57600086604051602001611ed79190612707565b604051602081830303815290604052805190602001209050611ef9818661212e565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614935050611f34565b600092505b5060010182529392505050565b600080631626ba7e60e01b8584604051602401611f5f929190612853565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808573ffffffffffffffffffffffffffffffffffffffff1683604051611fe691906126c4565b600060405180830381855afa9150503d8060008114612021576040519150601f19603f3d011682016040523d82523d6000602084013e612026565b606091505b5091509150818015612039575080516020145b801561209057507f1626ba7e0000000000000000000000000000000000000000000000000000000061206c826000612206565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b979650505050505050565b60008282111561210c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f5355425f554e444552464c4f5700000000000000000000000000000000000000604482015290519081900360640190fd5b50900390565b6000816001018351101561212557600080fd5b50016001015190565b60008151604114612141575060006108c6565b60208201516040830151604184015160ff167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561218757600093505050506108c6565b8060ff16601b148061219c57508060ff16601c145b156121fa57600186828585604051600081526020016040526040516121c494939291906128ab565b6020604051602081039080840390855afa1580156121e6573d6000803e3d6000fd5b5050506020604051035193505050506108c6565b600093505050506108c6565b6000816004018351101561221957600080fd5b50016020015190565b604080516060810182526000808252602082018190529181019190915290565b5080546000825590600052602060002090810190610c6d91905b808211156119f15780547fffffff000000000000000000000000000000000000000000000000000000000016815560010161225c565b803573ffffffffffffffffffffffffffffffffffffffff81168114610d5d57600080fd5b60008083601f8401126122c7578182fd5b50813567ffffffffffffffff8111156122de578182fd5b60208301915083602080830285010111156122f857600080fd5b9250929050565b600082601f83011261230f578081fd5b8135602061232461231f83612d94565b612d70565b8281528181019085830183850287018401881015612340578586fd5b855b858110156123655761235382612292565b84529284019290840190600101612342565b5090979650505050505050565b6000601f8381840112612383578182fd5b8235602061239361231f83612d94565b82815281810190868301865b8581101561243757813589018a603f8201126123b9578889fd5b85810135604067ffffffffffffffff8211156123d157fe5b612400887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601612d70565b8281528d82848601011115612413578b8cfd5b828285018a83013791820188018b905250855250928401929084019060010161239f565b509098975050505050505050565b80358015158114610d5d57600080fd5b600060808284031215612466578081fd5b50919050565b60006020828403121561247d578081fd5b6108c382612292565b60008060408385031215612498578081fd5b823591506124a860208401612292565b90509250929050565b6000806000606084860312156124c5578081fd5b833592506124d560208501612292565b91506124e360408501612445565b90509250925092565b600080600060408486031215612500578283fd5b83359250602084013567ffffffffffffffff81111561251d578283fd5b612529868287016122b6565b9497909650939450505050565b60008060408385031215612548578182fd5b82359150602083013567ffffffffffffffff811115612565578182fd5b612571858286016122ff565b9150509250929050565b6000806040838503121561258d578182fd5b823591506124a860208401612445565b600080600080608085870312156125b2578081fd5b8435935060208501359250604085013567ffffffffffffffff8111156125d6578182fd5b6125e287828801612455565b9250506125f160608601612292565b905092959194509250565b600080600080600060808688031215612613578081fd5b8535945060208601359350604086013567ffffffffffffffff80821115612638578283fd5b61264489838a01612455565b94506060880135915080821115612659578283fd5b50612666888289016122b6565b969995985093965092949392505050565b60008184825b858110156126b95773ffffffffffffffffffffffffffffffffffffffff6126a383612292565b168352602092830192919091019060010161267d565b509095945050505050565b600082516126d6818460208701612e4a565b9190910192915050565b600084516126f2818460208901612e4a565b91909101928352506020820152604001919050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b828110156127cd578151805173ffffffffffffffffffffffffffffffffffffffff1685528681015160ff168786015285015167ffffffffffffffff16858501526060909301929085019060010161277b565b5091979650505050505050565b901515815260200190565b90815260200190565b93845273ffffffffffffffffffffffffffffffffffffffff9283166020850152604084019190915216606082015260800190565b93845273ffffffffffffffffffffffffffffffffffffffff9290921660208401526040830152606082015260800190565b6000838252604060208301528251806040840152612878816060850160208701612e4a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b93845260ff9290921660208401526040830152606082015260800190565b60208082526013908201527f494e56414c49445f56414c49445f554e54494c00000000000000000000000000604082015260600190565b6020808252600f908201527f494e56414c49445f414444524553530000000000000000000000000000000000604082015260600190565b60208082526011908201527f554e45585045435445445f524553554c54000000000000000000000000000000604082015260600190565b60208082526016908201527f455850495245445f5349474e45445f5245515545535400000000000000000000604082015260600190565b60208082526013908201527f5349474e45525f4e4f545f475541524449414e00000000000000000000000000604082015260600190565b60208082526012908201527f4241445f5349474e41545552455f444154410000000000000000000000000000604082015260600190565b6020808252601f908201527f57414c4c45545f4f574e45525f5349474e41545552455f524551554952454400604082015260600190565b60208082526011908201527f5045524d495353494f4e5f44454e494544000000000000000000000000000000604082015260600190565b6020808252600c908201527f4e4f5f475541524449414e530000000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f5a45524f5f414444524553530000000000000000000000000000000000000000604082015260600190565b60208082526015908201527f494e56414c49445f5349474e4552535f4f524445520000000000000000000000604082015260600190565b6020808252818101527f4e4f5f475541524449414e5f5349474e45445f424553494445535f4f574e4552604082015260600190565b6020808252600e908201527f494e56414c49445f57414c4c4554000000000000000000000000000000000000604082015260600190565b60208082526013908201527f494e56414c49445f56414c49445f53494e434500000000000000000000000000604082015260600190565b60208082526013908201527f475541524449414e5f4e4f545f45584953545300000000000000000000000000604082015260600190565b60208082526012908201527f544f4f5f4d414e595f475541524449414e530000000000000000000000000000604082015260600190565b60208082526022908201527f57414c4c45545f4f574e45525f5349474e41545552455f4e4f545f414c4c4f5760408201527f4544000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526010908201527f494e56414c49445f4f52444552494e4700000000000000000000000000000000604082015260600190565b60208082526012908201527f494e56414c49445f5349474e4154555245530000000000000000000000000000604082015260600190565b6020808252600a908201527f484153485f455849535400000000000000000000000000000000000000000000604082015260600190565b60208082526019908201527f475541524449414e5f43414e5f4e4f545f42455f4f574e455200000000000000604082015260600190565b60405181810167ffffffffffffffff81118282101715612d8c57fe5b604052919050565b600067ffffffffffffffff821115612da857fe5b5060209081020190565b600060808236031215612dc3578081fd5b6040516080810167ffffffffffffffff8282108183111715612de157fe5b816040528435915080821115612df5578384fd5b612e01368387016122ff565b83526020850135915080821115612e16578384fd5b50612e2336828601612372565b60208301525060408301356040820152612e3f60608401612292565b606082015292915050565b60005b83811015612e65578181015183820152602001612e4d565b83811115610783575050600091015256fe53616665436173743a2076616c756520646f65736e27742066697420696e2036342062697473a264697066735822122032de4f17b1ee9c352873347acdc3586968a6c4debfdd725595ed5b41a4bf9a1d64736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.