Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
15365242 | 698 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
Governance
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.7.0; // SPDX-License-Identifier: MIT OR Apache-2.0 import "./Config.sol"; import "./Utils.sol"; import "./NFTFactory.sol"; import "./TokenGovernance.sol"; /// @title Governance Contract /// @author Matter Labs contract Governance is Config { /// @notice Token added to Franklin net event NewToken(address indexed token, uint16 indexed tokenId); /// @notice Default nft factory has set event SetDefaultNFTFactory(address indexed factory); /// @notice NFT factory registered new creator account event NFTFactoryRegisteredCreator( uint32 indexed creatorAccountId, address indexed creatorAddress, address factoryAddress ); /// @notice Governor changed event NewGovernor(address newGovernor); /// @notice Token Governance changed event NewTokenGovernance(TokenGovernance newTokenGovernance); /// @notice Validator's status changed event ValidatorStatusUpdate(address indexed validatorAddress, bool isActive); event TokenPausedUpdate(address indexed token, bool paused); /// @notice Address which will exercise governance over the network i.e. add tokens, change validator set, conduct upgrades address public networkGovernor; /// @notice Total number of ERC20 tokens registered in the network (excluding ETH, which is hardcoded as tokenId = 0) uint16 public totalTokens; /// @notice List of registered tokens by tokenId mapping(uint16 => address) public tokenAddresses; /// @notice List of registered tokens by address mapping(address => uint16) public tokenIds; /// @notice List of permitted validators mapping(address => bool) public validators; /// @notice Paused tokens list, deposits are impossible to create for paused tokens mapping(uint16 => bool) public pausedTokens; /// @notice Address that is authorized to add tokens to the Governance. TokenGovernance public tokenGovernance; /// @notice NFT Creator address to factory address mapping mapping(uint32 => mapping(address => NFTFactory)) public nftFactories; /// @notice Address which will be used if NFT token has no factories NFTFactory public defaultFactory; /// @notice Governance contract initialization. Can be external because Proxy contract intercepts illegal calls of this function. /// @param initializationParameters Encoded representation of initialization parameters: /// _networkGovernor The address of network governor function initialize(bytes calldata initializationParameters) external { address _networkGovernor = abi.decode(initializationParameters, (address)); networkGovernor = _networkGovernor; } /// @notice Governance contract upgrade. Can be external because Proxy contract intercepts illegal calls of this function. /// @param upgradeParameters Encoded representation of upgrade parameters // solhint-disable-next-line no-empty-blocks function upgrade(bytes calldata upgradeParameters) external {} /// @notice Change current governor /// @param _newGovernor Address of the new governor function changeGovernor(address _newGovernor) external { require(_newGovernor != address(0), "1n"); requireGovernor(msg.sender); if (networkGovernor != _newGovernor) { networkGovernor = _newGovernor; emit NewGovernor(_newGovernor); } } /// @notice Change current token governance /// @param _newTokenGovernance Address of the new token governor function changeTokenGovernance(TokenGovernance _newTokenGovernance) external { requireGovernor(msg.sender); if (tokenGovernance != _newTokenGovernance) { tokenGovernance = _newTokenGovernance; emit NewTokenGovernance(_newTokenGovernance); } } /// @notice Add token to the list of networks tokens /// @param _token Token address function addToken(address _token) external { require(msg.sender == address(tokenGovernance), "1E"); require(tokenIds[_token] == 0, "1e"); // token exists require(totalTokens < MAX_AMOUNT_OF_REGISTERED_TOKENS, "1f"); // no free identifiers for tokens totalTokens++; uint16 newTokenId = totalTokens; // it is not `totalTokens - 1` because tokenId = 0 is reserved for eth tokenAddresses[newTokenId] = _token; tokenIds[_token] = newTokenId; emit NewToken(_token, newTokenId); } /// @notice Pause token deposits for the given token /// @param _tokenAddr Token address /// @param _tokenPaused Token paused status function setTokenPaused(address _tokenAddr, bool _tokenPaused) external { requireGovernor(msg.sender); uint16 tokenId = this.validateTokenAddress(_tokenAddr); if (pausedTokens[tokenId] != _tokenPaused) { pausedTokens[tokenId] = _tokenPaused; emit TokenPausedUpdate(_tokenAddr, _tokenPaused); } } /// @notice Change validator status (active or not active) /// @param _validator Validator address /// @param _active Active flag function setValidator(address _validator, bool _active) external { requireGovernor(msg.sender); if (validators[_validator] != _active) { validators[_validator] = _active; emit ValidatorStatusUpdate(_validator, _active); } } /// @notice Check if specified address is is governor /// @param _address Address to check function requireGovernor(address _address) public view { require(_address == networkGovernor, "1g"); // only by governor } /// @notice Checks if validator is active /// @param _address Validator address function requireActiveValidator(address _address) external view { require(validators[_address], "1h"); // validator is not active } /// @notice Validate token id (must be less than or equal to total tokens amount) /// @param _tokenId Token id /// @return bool flag that indicates if token id is less than or equal to total tokens amount function isValidTokenId(uint16 _tokenId) external view returns (bool) { return _tokenId <= totalTokens; } /// @notice Validate token address /// @param _tokenAddr Token address /// @return tokens id function validateTokenAddress(address _tokenAddr) external view returns (uint16) { uint16 tokenId = tokenIds[_tokenAddr]; require(tokenId != 0, "1i"); // 0 is not a valid token return tokenId; } function packRegisterNFTFactoryMsg( uint32 _creatorAccountId, address _creatorAddress, address _factoryAddress ) internal pure returns (bytes memory) { return abi.encodePacked( "\x19Ethereum Signed Message:\n141", "\nCreator's account ID in zkSync: ", Bytes.bytesToHexASCIIBytes(abi.encodePacked((_creatorAccountId))), "\nCreator: ", Bytes.bytesToHexASCIIBytes(abi.encodePacked((_creatorAddress))), "\nFactory: ", Bytes.bytesToHexASCIIBytes(abi.encodePacked((_factoryAddress))) ); } /// @notice Register creator corresponding to the factory /// @param _creatorAccountId Creator's zkSync account ID /// @param _creatorAddress NFT creator address /// @param _signature Creator's signature function registerNFTFactoryCreator( uint32 _creatorAccountId, address _creatorAddress, bytes memory _signature ) external { require(address(nftFactories[_creatorAccountId][_creatorAddress]) == address(0), "Q"); bytes32 messageHash = keccak256(packRegisterNFTFactoryMsg(_creatorAccountId, _creatorAddress, msg.sender)); address recoveredAddress = Utils.recoverAddressFromEthSignature(_signature, messageHash); require(recoveredAddress == _creatorAddress, "ws"); nftFactories[_creatorAccountId][_creatorAddress] = NFTFactory(msg.sender); emit NFTFactoryRegisteredCreator(_creatorAccountId, _creatorAddress, msg.sender); } /// @notice Set default factory for our contract. This factory will be used to mint an NFT token that has no factory /// @param _factory Address of NFT factory function setDefaultNFTFactory(address _factory) external { requireGovernor(msg.sender); require(address(_factory) != address(0), "mb1"); // Factory should be non zero require(address(defaultFactory) == address(0), "mb2"); // NFTFactory is already set defaultFactory = NFTFactory(_factory); emit SetDefaultNFTFactory(_factory); } function getNFTFactory(uint32 _creatorAccountId, address _creatorAddress) external view returns (NFTFactory) { NFTFactory _factory = nftFactories[_creatorAccountId][_creatorAddress]; // even if the factory is undefined or has been destroyed, the user can mint NFT if (address(_factory) == address(0) || !isContract(address(_factory))) { require(address(defaultFactory) != address(0), "fs"); // NFTFactory does not set return defaultFactory; } else { return _factory; } } /// @return whether the address is a contract or not /// NOTE: for smart contracts that called `selfdestruct` will return a negative result function isContract(address _address) internal view returns (bool) { uint256 contractSize; assembly { contractSize := extcodesize(_address) } return contractSize != 0; } }
pragma solidity ^0.7.0; // SPDX-License-Identifier: MIT OR Apache-2.0 /// @title zkSync configuration constants /// @author Matter Labs contract Config { /// @dev ERC20 tokens and ETH withdrawals gas limit, used only for complete withdrawals uint256 internal constant WITHDRAWAL_GAS_LIMIT = 100000; /// @dev NFT withdrawals gas limit, used only for complete withdrawals uint256 internal constant WITHDRAWAL_NFT_GAS_LIMIT = 300000; /// @dev Bytes in one chunk uint8 internal constant CHUNK_BYTES = 10; /// @dev zkSync address length uint8 internal constant ADDRESS_BYTES = 20; uint8 internal constant PUBKEY_HASH_BYTES = 20; /// @dev Public key bytes length uint8 internal constant PUBKEY_BYTES = 32; /// @dev Ethereum signature r/s bytes length uint8 internal constant ETH_SIGN_RS_BYTES = 32; /// @dev Success flag bytes length uint8 internal constant SUCCESS_FLAG_BYTES = 1; /// @dev Max amount of tokens registered in the network (excluding ETH, which is hardcoded as tokenId = 0) uint32 internal constant MAX_AMOUNT_OF_REGISTERED_TOKENS = 1023; /// @dev Max account id that could be registered in the network uint32 internal constant MAX_ACCOUNT_ID = 16777215; /// @dev Expected average period of block creation uint256 internal constant BLOCK_PERIOD = 15 seconds; /// @dev ETH blocks verification expectation /// @dev Blocks can be reverted if they are not verified for at least EXPECT_VERIFICATION_IN. /// @dev If set to 0 validator can revert blocks at any time. uint256 internal constant EXPECT_VERIFICATION_IN = 0 hours / BLOCK_PERIOD; uint256 internal constant NOOP_BYTES = 1 * CHUNK_BYTES; uint256 internal constant DEPOSIT_BYTES = 6 * CHUNK_BYTES; uint256 internal constant MINT_NFT_BYTES = 5 * CHUNK_BYTES; uint256 internal constant TRANSFER_TO_NEW_BYTES = 6 * CHUNK_BYTES; uint256 internal constant PARTIAL_EXIT_BYTES = 6 * CHUNK_BYTES; uint256 internal constant TRANSFER_BYTES = 2 * CHUNK_BYTES; uint256 internal constant FORCED_EXIT_BYTES = 6 * CHUNK_BYTES; uint256 internal constant WITHDRAW_NFT_BYTES = 10 * CHUNK_BYTES; /// @dev Full exit operation length uint256 internal constant FULL_EXIT_BYTES = 11 * CHUNK_BYTES; /// @dev ChangePubKey operation length uint256 internal constant CHANGE_PUBKEY_BYTES = 6 * CHUNK_BYTES; /// @dev Expiration delta for priority request to be satisfied (in seconds) /// @dev NOTE: Priority expiration should be > (EXPECT_VERIFICATION_IN * BLOCK_PERIOD) /// @dev otherwise incorrect block with priority op could not be reverted. uint256 internal constant PRIORITY_EXPIRATION_PERIOD = 14 days; /// @dev Expiration delta for priority request to be satisfied (in ETH blocks) uint256 internal constant PRIORITY_EXPIRATION = PRIORITY_EXPIRATION_PERIOD/BLOCK_PERIOD; /// @dev Maximum number of priority request to clear during verifying the block /// @dev Cause deleting storage slots cost 5k gas per each slot it's unprofitable to clear too many slots /// @dev Value based on the assumption of ~750k gas cost of verifying and 5 used storage slots per PriorityOperation structure uint64 internal constant MAX_PRIORITY_REQUESTS_TO_DELETE_IN_VERIFY = 6; /// @dev Reserved time for users to send full exit priority operation in case of an upgrade (in seconds) uint256 internal constant MASS_FULL_EXIT_PERIOD = 5 days; /// @dev Reserved time for users to withdraw funds from full exit priority operation in case of an upgrade (in seconds) uint256 internal constant TIME_TO_WITHDRAW_FUNDS_FROM_FULL_EXIT = 2 days; /// @dev Notice period before activation preparation status of upgrade mode (in seconds) /// @dev NOTE: we must reserve for users enough time to send full exit operation, wait maximum time for processing this operation and withdraw funds from it. uint256 internal constant UPGRADE_NOTICE_PERIOD = MASS_FULL_EXIT_PERIOD+PRIORITY_EXPIRATION_PERIOD+TIME_TO_WITHDRAW_FUNDS_FROM_FULL_EXIT; /// @dev Timestamp - seconds since unix epoch uint256 internal constant COMMIT_TIMESTAMP_NOT_OLDER = 24 hours; /// @dev Maximum available error between real commit block timestamp and analog used in the verifier (in seconds) /// @dev Must be used cause miner's `block.timestamp` value can differ on some small value (as we know - 15 seconds) uint256 internal constant COMMIT_TIMESTAMP_APPROXIMATION_DELTA = 15 minutes; /// @dev Bit mask to apply for verifier public input before verifying. uint256 internal constant INPUT_MASK = 14474011154664524427946373126085988481658748083205070504932198000989141204991; /// @dev Auth fact reset timelock. uint256 internal constant AUTH_FACT_RESET_TIMELOCK = 1 days; /// @dev Max deposit of ERC20 token that is possible to deposit uint128 internal constant MAX_DEPOSIT_AMOUNT = 20282409603651670423947251286015; uint32 internal constant SPECIAL_ACCOUNT_ID = 16777215; address internal constant SPECIAL_ACCOUNT_ADDRESS = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF); uint32 internal constant SPECIAL_NFT_TOKEN_ID = 2147483646; uint32 internal constant MAX_FUNGIBLE_TOKEN_ID = 65535; uint256 internal constant SECURITY_COUNCIL_MEMBERS_NUMBER = 15; string internal constant name = "ZkSync"; string internal constant version = "1.0"; bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId)"); bytes32 internal constant EIP712_CHANGEPUBKEY_TYPEHASH = keccak256("ChangePubKey(bytes20 pubKeyHash,uint32 nonce,uint32 accountId)"); }
pragma solidity ^0.7.0; // SPDX-License-Identifier: MIT OR Apache-2.0 import "./IERC20.sol"; import "./Bytes.sol"; library Utils { /// @notice Returns lesser of two values function minU32(uint32 a, uint32 b) internal pure returns (uint32) { return a < b ? a : b; } /// @notice Returns lesser of two values function minU64(uint64 a, uint64 b) internal pure returns (uint64) { return a < b ? a : b; } /// @notice Returns lesser of two values function minU128(uint128 a, uint128 b) internal pure returns (uint128) { return a < b ? a : b; } /// @notice Recovers signer's address from ethereum signature for given message /// @param _signature 65 bytes concatenated. R (32) + S (32) + V (1) /// @param _messageHash signed message hash. /// @return address of the signer /// NOTE: will revert if signature is invalid function recoverAddressFromEthSignature(bytes memory _signature, bytes32 _messageHash) internal pure returns (address) { require(_signature.length == 65, "P"); // incorrect signature length bytes32 signR; bytes32 signS; uint8 signV; assembly { signR := mload(add(_signature, 32)) signS := mload(add(_signature, 64)) signV := byte(0, mload(add(_signature, 96))) } address recoveredAddress = ecrecover(_messageHash, signV, signR, signS); require(recoveredAddress != address(0), "p4"); // invalid signature return recoveredAddress; } /// @notice Returns new_hash = hash(old_hash + bytes) function concatHash(bytes32 _hash, bytes memory _bytes) internal pure returns (bytes32) { bytes32 result; assembly { let bytesLen := add(mload(_bytes), 32) mstore(_bytes, _hash) result := keccak256(_bytes, bytesLen) } return result; } function hashBytesToBytes20(bytes memory _bytes) internal pure returns (bytes20) { return bytes20(uint160(uint256(keccak256(_bytes)))); } function getChainId() internal pure returns (uint256) { uint256 chainId; assembly { chainId := chainid() } return chainId; } }
pragma solidity ^0.7.0; // SPDX-License-Identifier: UNLICENSED interface NFTFactory { function mintNFTFromZkSync( address creator, address recipient, uint32 creatorAccountId, uint32 serialId, bytes32 contentHash, // Even though the token id can fit into the uint32, we still use // the uint256 to preserve consistency with the ERC721 parent contract uint256 tokenId ) external; event MintNFTFromZkSync( address indexed creator, address indexed recipient, uint32 creatorAccountId, uint32 serialId, bytes32 contentHash, uint256 tokenId ); }
pragma solidity ^0.7.0; // SPDX-License-Identifier: MIT OR Apache-2.0 import "./ReentrancyGuard.sol"; import "./Governance.sol"; import "./ITrustedTransfarableERC20.sol"; import "./Utils.sol"; /// @title Token Governance Contract /// @author Matter Labs /// @notice Contract is used to allow anyone to add new ERC20 tokens to zkSync given sufficient payment contract TokenGovernance is ReentrancyGuard { /// @notice Token lister added or removed (see `tokenLister`) event TokenListerUpdate(address indexed tokenLister, bool isActive); /// @notice Listing fee token set event ListingFeeTokenUpdate(ITrustedTransfarableERC20 indexed newListingFeeToken, uint256 newListingFee); /// @notice Listing fee set event ListingFeeUpdate(uint256 newListingFee); /// @notice Maximum number of listed tokens updated event ListingCapUpdate(uint16 newListingCap); /// @notice The treasury (the account which will receive the fee) was updated event TreasuryUpdate(address newTreasury); /// @notice zkSync governance contract Governance public governance; /// @notice Token used to collect listing fee for addition of new token to zkSync network ITrustedTransfarableERC20 public listingFeeToken; /// @notice Token listing fee uint256 public listingFee; /// @notice Max number of tokens that can be listed using this contract uint16 public listingCap; /// @notice Addresses that can list tokens without fee mapping(address => bool) public tokenLister; /// @notice Address that collects listing payments address public treasury; constructor( Governance _governance, ITrustedTransfarableERC20 _listingFeeToken, uint256 _listingFee, uint16 _listingCap, address _treasury ) { initializeReentrancyGuard(); governance = _governance; listingFeeToken = _listingFeeToken; listingFee = _listingFee; listingCap = _listingCap; treasury = _treasury; address governor = governance.networkGovernor(); // We add zkSync governor as a first token lister. tokenLister[governor] = true; emit TokenListerUpdate(governor, true); } /// @notice Adds new ERC20 token to zkSync network. /// @notice If caller is not present in the `tokenLister` map payment of `listingFee` in `listingFeeToken` should be made. /// @notice NOTE: before calling this function make sure to approve `listingFeeToken` transfer for this contract. function addToken(address _token) external nonReentrant { require(_token != address(0), "z1"); // Token should have a non-zero address require(_token != 0xaBEA9132b05A70803a4E85094fD0e1800777fBEF, "z2"); // Address of the token cannot be the same as the address of the main zksync contract require(governance.totalTokens() < listingCap, "can't add more tokens"); // Impossible to add more tokens using this contract if (!tokenLister[msg.sender] && listingFee > 0) { // Collect fees bool feeTransferOk = listingFeeToken.transferFrom(msg.sender, treasury, listingFee); require(feeTransferOk, "fee transfer failed"); // Failed to receive payment for token addition. } governance.addToken(_token); } /// Governance functions (this contract is governed by zkSync governor) /// @notice Set new listing token and fee /// @notice Can be called only by zkSync governor function setListingFeeToken(ITrustedTransfarableERC20 _newListingFeeToken, uint256 _newListingFee) external { governance.requireGovernor(msg.sender); listingFeeToken = _newListingFeeToken; listingFee = _newListingFee; emit ListingFeeTokenUpdate(_newListingFeeToken, _newListingFee); } /// @notice Set new listing fee /// @notice Can be called only by zkSync governor function setListingFee(uint256 _newListingFee) external { governance.requireGovernor(msg.sender); listingFee = _newListingFee; emit ListingFeeUpdate(_newListingFee); } /// @notice Enable or disable token lister. If enabled new tokens can be added by that address without payment /// @notice Can be called only by zkSync governor function setLister(address _listerAddress, bool _active) external { governance.requireGovernor(msg.sender); if (tokenLister[_listerAddress] != _active) { tokenLister[_listerAddress] = _active; emit TokenListerUpdate(_listerAddress, _active); } } /// @notice Change maximum amount of tokens that can be listed using this method /// @notice Can be called only by zkSync governor function setListingCap(uint16 _newListingCap) external { governance.requireGovernor(msg.sender); listingCap = _newListingCap; emit ListingCapUpdate(_newListingCap); } /// @notice Change address that collects payments for listing tokens. /// @notice Can be called only by zkSync governor function setTreasury(address _newTreasury) external { governance.requireGovernor(msg.sender); treasury = _newTreasury; emit TreasuryUpdate(_newTreasury); } }
pragma solidity ^0.7.0; // SPDX-License-Identifier: UNLICENSED /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external; /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external; /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
pragma solidity ^0.7.0; // SPDX-License-Identifier: MIT OR Apache-2.0 // Functions named bytesToX, except bytesToBytes20, where X is some type of size N < 32 (size of one word) // implements the following algorithm: // f(bytes memory input, uint offset) -> X out // where byte representation of out is N bytes from input at the given offset // 1) We compute memory location of the word W such that last N bytes of W is input[offset..offset+N] // W_address = input + 32 (skip stored length of bytes) + offset - (32 - N) == input + offset + N // 2) We load W from memory into out, last N bytes of W are placed into out library Bytes { function toBytesFromUInt16(uint16 self) internal pure returns (bytes memory _bts) { return toBytesFromUIntTruncated(uint256(self), 2); } function toBytesFromUInt24(uint24 self) internal pure returns (bytes memory _bts) { return toBytesFromUIntTruncated(uint256(self), 3); } function toBytesFromUInt32(uint32 self) internal pure returns (bytes memory _bts) { return toBytesFromUIntTruncated(uint256(self), 4); } function toBytesFromUInt128(uint128 self) internal pure returns (bytes memory _bts) { return toBytesFromUIntTruncated(uint256(self), 16); } // Copies 'len' lower bytes from 'self' into a new 'bytes memory'. // Returns the newly created 'bytes memory'. The returned bytes will be of length 'len'. function toBytesFromUIntTruncated(uint256 self, uint8 byteLength) private pure returns (bytes memory bts) { require(byteLength <= 32, "Q"); bts = new bytes(byteLength); // Even though the bytes will allocate a full word, we don't want // any potential garbage bytes in there. uint256 data = self << ((32 - byteLength) * 8); assembly { mstore( add(bts, 32), // BYTES_HEADER_SIZE data ) } } // Copies 'self' into a new 'bytes memory'. // Returns the newly created 'bytes memory'. The returned bytes will be of length '20'. function toBytesFromAddress(address self) internal pure returns (bytes memory bts) { bts = toBytesFromUIntTruncated(uint256(self), 20); } // See comment at the top of this file for explanation of how this function works. // NOTE: theoretically possible overflow of (_start + 20) function bytesToAddress(bytes memory self, uint256 _start) internal pure returns (address addr) { uint256 offset = _start + 20; require(self.length >= offset, "R"); assembly { addr := mload(add(self, offset)) } } // Reasoning about why this function works is similar to that of other similar functions, except NOTE below. // NOTE: that bytes1..32 is stored in the beginning of the word unlike other primitive types // NOTE: theoretically possible overflow of (_start + 20) function bytesToBytes20(bytes memory self, uint256 _start) internal pure returns (bytes20 r) { require(self.length >= (_start + 20), "S"); assembly { r := mload(add(add(self, 0x20), _start)) } } // See comment at the top of this file for explanation of how this function works. // NOTE: theoretically possible overflow of (_start + 0x2) function bytesToUInt16(bytes memory _bytes, uint256 _start) internal pure returns (uint16 r) { uint256 offset = _start + 0x2; require(_bytes.length >= offset, "T"); assembly { r := mload(add(_bytes, offset)) } } // See comment at the top of this file for explanation of how this function works. // NOTE: theoretically possible overflow of (_start + 0x3) function bytesToUInt24(bytes memory _bytes, uint256 _start) internal pure returns (uint24 r) { uint256 offset = _start + 0x3; require(_bytes.length >= offset, "U"); assembly { r := mload(add(_bytes, offset)) } } // NOTE: theoretically possible overflow of (_start + 0x4) function bytesToUInt32(bytes memory _bytes, uint256 _start) internal pure returns (uint32 r) { uint256 offset = _start + 0x4; require(_bytes.length >= offset, "V"); assembly { r := mload(add(_bytes, offset)) } } // NOTE: theoretically possible overflow of (_start + 0x10) function bytesToUInt128(bytes memory _bytes, uint256 _start) internal pure returns (uint128 r) { uint256 offset = _start + 0x10; require(_bytes.length >= offset, "W"); assembly { r := mload(add(_bytes, offset)) } } // See comment at the top of this file for explanation of how this function works. // NOTE: theoretically possible overflow of (_start + 0x14) function bytesToUInt160(bytes memory _bytes, uint256 _start) internal pure returns (uint160 r) { uint256 offset = _start + 0x14; require(_bytes.length >= offset, "X"); assembly { r := mload(add(_bytes, offset)) } } // NOTE: theoretically possible overflow of (_start + 0x20) function bytesToBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32 r) { uint256 offset = _start + 0x20; require(_bytes.length >= offset, "Y"); assembly { r := mload(add(_bytes, offset)) } } // Original source code: https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol#L228 // Get slice from bytes arrays // Returns the newly created 'bytes memory' // NOTE: theoretically possible overflow of (_start + _length) function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_bytes.length >= (_start + _length), "Z"); // bytes length is less then start byte + length bytes bytes memory tempBytes = new bytes(_length); if (_length != 0) { assembly { let slice_curr := add(tempBytes, 0x20) let slice_end := add(slice_curr, _length) for { let array_current := add(_bytes, add(_start, 0x20)) } lt(slice_curr, slice_end) { slice_curr := add(slice_curr, 0x20) array_current := add(array_current, 0x20) } { mstore(slice_curr, mload(array_current)) } } } return tempBytes; } /// Reads byte stream /// @return newOffset - offset + amount of bytes read /// @return data - actually read data // NOTE: theoretically possible overflow of (_offset + _length) function read( bytes memory _data, uint256 _offset, uint256 _length ) internal pure returns (uint256 newOffset, bytes memory data) { data = slice(_data, _offset, _length); newOffset = _offset + _length; } // NOTE: theoretically possible overflow of (_offset + 1) function readBool(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, bool r) { newOffset = _offset + 1; r = uint8(_data[_offset]) != 0; } // NOTE: theoretically possible overflow of (_offset + 1) function readUint8(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, uint8 r) { newOffset = _offset + 1; r = uint8(_data[_offset]); } // NOTE: theoretically possible overflow of (_offset + 2) function readUInt16(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, uint16 r) { newOffset = _offset + 2; r = bytesToUInt16(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 3) function readUInt24(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, uint24 r) { newOffset = _offset + 3; r = bytesToUInt24(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 4) function readUInt32(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, uint32 r) { newOffset = _offset + 4; r = bytesToUInt32(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 16) function readUInt128(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, uint128 r) { newOffset = _offset + 16; r = bytesToUInt128(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 20) function readUInt160(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, uint160 r) { newOffset = _offset + 20; r = bytesToUInt160(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 20) function readAddress(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, address r) { newOffset = _offset + 20; r = bytesToAddress(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 20) function readBytes20(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, bytes20 r) { newOffset = _offset + 20; r = bytesToBytes20(_data, _offset); } // NOTE: theoretically possible overflow of (_offset + 32) function readBytes32(bytes memory _data, uint256 _offset) internal pure returns (uint256 newOffset, bytes32 r) { newOffset = _offset + 32; r = bytesToBytes32(_data, _offset); } /// Trim bytes into single word function trim(bytes memory _data, uint256 _newLength) internal pure returns (uint256 r) { require(_newLength <= 0x20, "10"); // new_length is longer than word require(_data.length >= _newLength, "11"); // data is to short uint256 a; assembly { a := mload(add(_data, 0x20)) // load bytes into uint256 } return a >> ((0x20 - _newLength) * 8); } // Helper function for hex conversion. function halfByteToHex(bytes1 _byte) internal pure returns (bytes1 _hexByte) { require(uint8(_byte) < 0x10, "hbh11"); // half byte's value is out of 0..15 range. // "FEDCBA9876543210" ASCII-encoded, shifted and automatically truncated. return bytes1(uint8(0x66656463626139383736353433323130 >> (uint8(_byte) * 8))); } // Convert bytes to ASCII hex representation function bytesToHexASCIIBytes(bytes memory _input) internal pure returns (bytes memory _output) { bytes memory outStringBytes = new bytes(_input.length * 2); // code in `assembly` construction is equivalent of the next code: // for (uint i = 0; i < _input.length; ++i) { // outStringBytes[i*2] = halfByteToHex(_input[i] >> 4); // outStringBytes[i*2+1] = halfByteToHex(_input[i] & 0x0f); // } assembly { let input_curr := add(_input, 0x20) let input_end := add(input_curr, mload(_input)) for { let out_curr := add(outStringBytes, 0x20) } lt(input_curr, input_end) { input_curr := add(input_curr, 0x01) out_curr := add(out_curr, 0x02) } { let curr_input_byte := shr(0xf8, mload(input_curr)) // here outStringByte from each half of input byte calculates by the next: // // "FEDCBA9876543210" ASCII-encoded, shifted and automatically truncated. // outStringByte = byte (uint8 (0x66656463626139383736353433323130 >> (uint8 (_byteHalf) * 8))) mstore( out_curr, shl(0xf8, shr(mul(shr(0x04, curr_input_byte), 0x08), 0x66656463626139383736353433323130)) ) mstore( add(out_curr, 0x01), shl(0xf8, shr(mul(and(0x0f, curr_input_byte), 0x08), 0x66656463626139383736353433323130)) ) } } return outStringBytes; } }
pragma solidity ^0.7.0; // SPDX-License-Identifier: MIT OR Apache-2.0 /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. * * _Since v2.5.0:_ this module is now much more gas efficient, given net gas * metering changes introduced in the Istanbul hardfork. */ contract ReentrancyGuard { /// @dev Address of lock flag variable. /// @dev Flag is placed at random memory location to not interfere with Storage contract. uint256 private constant LOCK_FLAG_ADDRESS = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4; // keccak256("ReentrancyGuard") - 1; // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/566a774222707e424896c0c390a84dc3c13bdcb2/contracts/security/ReentrancyGuard.sol // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; function initializeReentrancyGuard() internal { uint256 lockSlotOldValue; // Storing an initial non-zero value makes deployment a bit more // expensive, but in exchange every call to nonReentrant // will be cheaper. assembly { lockSlotOldValue := sload(LOCK_FLAG_ADDRESS) sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED) } // Check that storage slot for reentrancy guard is empty to rule out possibility of double initialization require(lockSlotOldValue == 0, "1B"); } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { uint256 _status; assembly { _status := sload(LOCK_FLAG_ADDRESS) } // On the first call to nonReentrant, _notEntered will be true require(_status == _NOT_ENTERED); // Any calls to nonReentrant after this point will fail assembly { sstore(LOCK_FLAG_ADDRESS, _ENTERED) } _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) assembly { sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED) } } }
/// @dev Interface of the ERC20 standard as defined in the EIP. /// 1. Implements only `transfer` and `transferFrom` methods /// 2. These methods return a boolean value in case of a non-revert call /// NOTE: It is expected that if the function returns true, then the user's balance has /// changed exactly by `amount` according to the ERC20 standard. /// Note: Used to perform transfers for tokens that explicitly return a boolean value /// (if the token returns any other data or does not return at all, then the function call will be reverted) interface ITrustedTransfarableERC20 { /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"creatorAccountId","type":"uint32"},{"indexed":true,"internalType":"address","name":"creatorAddress","type":"address"},{"indexed":false,"internalType":"address","name":"factoryAddress","type":"address"}],"name":"NFTFactoryRegisteredCreator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newGovernor","type":"address"}],"name":"NewGovernor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint16","name":"tokenId","type":"uint16"}],"name":"NewToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract TokenGovernance","name":"newTokenGovernance","type":"address"}],"name":"NewTokenGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"SetDefaultNFTFactory","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"TokenPausedUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validatorAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"ValidatorStatusUpdate","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"addToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"changeGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract TokenGovernance","name":"_newTokenGovernance","type":"address"}],"name":"changeTokenGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultFactory","outputs":[{"internalType":"contract NFTFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_creatorAccountId","type":"uint32"},{"internalType":"address","name":"_creatorAddress","type":"address"}],"name":"getNFTFactory","outputs":[{"internalType":"contract NFTFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initializationParameters","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"isValidTokenId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"networkGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"nftFactories","outputs":[{"internalType":"contract NFTFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"pausedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_creatorAccountId","type":"uint32"},{"internalType":"address","name":"_creatorAddress","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"registerNFTFactoryCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"requireActiveValidator","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"requireGovernor","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"setDefaultNFTFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddr","type":"address"},{"internalType":"bool","name":"_tokenPaused","type":"bool"}],"name":"setTokenPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_validator","type":"address"},{"internalType":"bool","name":"_active","type":"bool"}],"name":"setValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"tokenAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenGovernance","outputs":[{"internalType":"contract TokenGovernance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenIds","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokens","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"upgradeParameters","type":"bytes"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddr","type":"address"}],"name":"validateTokenAddress","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611302806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c8063ce09e20d116100c3578063ead317621161007c578063ead3176214610514578063f39349ef1461053a578063f3a65bf914610542578063f5f84ed414610563578063fa52c7d814610589578063fc97a303146105af5761014d565b8063ce09e20d14610433578063d48bfca714610459578063d4b6846d1461047f578063e122b7d114610487578063e2c79268146104b9578063e4c0aaf4146104ee5761014d565b8063622574701161011557806362257470146102c557806378393d22146102f35780637e1c0c09146103195780638d1db94014610338578063b79eb8c714610340578063c4dcb92c146103725761014d565b806310603dad14610152578063253946451461018f578063439fab91146102015780634623c91d146102715780634b18bd0f1461029f575b600080fd5b6101736004803603602081101561016857600080fd5b503561ffff166105d5565b604080516001600160a01b039092168252519081900360200190f35b6101ff600480360360208110156101a557600080fd5b8101906020810181356401000000008111156101c057600080fd5b8201836020820111156101d257600080fd5b803590602001918460018302840111640100000000831117156101f457600080fd5b5090925090506105f0565b005b6101ff6004803603602081101561021757600080fd5b81019060208101813564010000000081111561023257600080fd5b82018360208201111561024457600080fd5b8035906020019184600183028401116401000000008311171561026657600080fd5b5090925090506105f4565b6101ff6004803603604081101561028757600080fd5b506001600160a01b038135169060200135151561062d565b6101ff600480360360208110156102b557600080fd5b50356001600160a01b03166106bc565b6101ff600480360360408110156102db57600080fd5b506001600160a01b0381351690602001351515610711565b6101ff6004803603602081101561030957600080fd5b50356001600160a01b0316610820565b610321610892565b6040805161ffff9092168252519081900360200190f35b6101736108a3565b6101736004803603604081101561035657600080fd5b50803563ffffffff1690602001356001600160a01b03166108b2565b6101ff6004803603606081101561038857600080fd5b63ffffffff823516916001600160a01b03602082013516918101906060810160408201356401000000008111156103be57600080fd5b8201836020820111156103d057600080fd5b803590602001918460018302840111640100000000831117156103f257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610953945050505050565b6101ff6004803603602081101561044957600080fd5b50356001600160a01b0316610a9f565b6101ff6004803603602081101561046f57600080fd5b50356001600160a01b0316610b77565b610173610cf7565b6101736004803603604081101561049d57600080fd5b50803563ffffffff1690602001356001600160a01b0316610d06565b6104da600480360360208110156104cf57600080fd5b503561ffff16610d2c565b604080519115158252519081900360200190f35b6101ff6004803603602081101561050457600080fd5b50356001600160a01b0316610d43565b6103216004803603602081101561052a57600080fd5b50356001600160a01b0316610df5565b610173610e49565b6104da6004803603602081101561055857600080fd5b503561ffff16610e58565b6101ff6004803603602081101561057957600080fd5b50356001600160a01b0316610e6d565b6104da6004803603602081101561059f57600080fd5b50356001600160a01b0316610eb4565b610321600480360360208110156105c557600080fd5b50356001600160a01b0316610ec9565b6001602052600090815260409020546001600160a01b031681565b5050565b60008282602081101561060657600080fd5b506000805491356001600160a01b03166001600160a01b0319909216919091179055505050565b61063633610e6d565b6001600160a01b03821660009081526003602052604090205460ff161515811515146105f0576001600160a01b038216600081815260036020908152604091829020805460ff1916851515908117909155825190815291517f065b77b53864e46fda3d8986acb51696223d6dde7ced42441eb150bae6d481369281900390910190a25050565b6001600160a01b03811660009081526003602052604090205460ff1661070e576040805162461bcd60e51b8152602060048201526002602482015261062d60f31b604482015290519081900360640190fd5b50565b61071a33610e6d565b6000306001600160a01b031663ead31762846040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561076957600080fd5b505afa15801561077d573d6000803e3d6000fd5b505050506040513d602081101561079357600080fd5b505161ffff811660009081526004602052604090205490915060ff1615158215151461081b5761ffff8116600090815260046020908152604091829020805460ff1916851515908117909155825190815291516001600160a01b038616927ff72cbadf0693609a042637541df35c63e7e074363dea6efb5c19d6c7814ceee992908290030190a25b505050565b61082933610e6d565b6005546001600160a01b0382811691161461070e57600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517fb24c0fc80a0c2a8c6a406f1f63ac240a949e45444715e77bcb06073a1a1d401c9181900360200190a150565b600054600160a01b900461ffff1681565b6005546001600160a01b031681565b63ffffffff821660009081526006602090815260408083206001600160a01b0380861685529252822054168015806108f057506108ee81610edf565b155b1561094a576007546001600160a01b0316610937576040805162461bcd60e51b8152602060048201526002602482015261667360f01b604482015290519081900360640190fd5b50506007546001600160a01b031661094d565b90505b92915050565b63ffffffff831660009081526006602090815260408083206001600160a01b03868116855292529091205416156109b5576040805162461bcd60e51b81526020600482015260016024820152605160f81b604482015290519081900360640190fd5b60006109c2848433610ee5565b80519060200120905060006109d783836110dd565b9050836001600160a01b0316816001600160a01b031614610a24576040805162461bcd60e51b8152602060048201526002602482015261777360f01b604482015290519081900360640190fd5b63ffffffff851660008181526006602090815260408083206001600160a01b0389168085529083529281902080546001600160a01b03191633908117909155815190815290519293927fa31b86f0827cd4eabf087b77e866f658278cb60e2d7c291d407edaada53408e0929181900390910190a35050505050565b610aa833610e6d565b6001600160a01b038116610ae9576040805162461bcd60e51b81526020600482015260036024820152626d623160e81b604482015290519081900360640190fd5b6007546001600160a01b031615610b2d576040805162461bcd60e51b815260206004820152600360248201526236b11960e91b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f9678384f56a2d29e9db5747e5910c194dde921293922f2463582d8c25b96533090600090a250565b6005546001600160a01b03163314610bbb576040805162461bcd60e51b8152602060048201526002602482015261314560f01b604482015290519081900360640190fd5b6001600160a01b03811660009081526002602052604090205461ffff1615610c0f576040805162461bcd60e51b8152602060048201526002602482015261316560f01b604482015290519081900360640190fd5b6000546103ff600160a01b90910461ffff1610610c58576040805162461bcd60e51b815260206004820152600260248201526118b360f11b604482015290519081900360640190fd5b60008054600161ffff600160a01b808404821683018216810261ffff60a01b1990941693909317808555929092049091168083526020918252604080842080546001600160a01b0387166001600160a01b031990911681179091558085526002909352808420805461ffff1916831790555190928392917ffe74dea79bde70d1990ddb655bac45735b14f495ddc508cfab80b7729aa9d6689190a35050565b6007546001600160a01b031681565b60066020908152600092835260408084209091529082529020546001600160a01b031681565b600054600160a01b900461ffff9081169116111590565b6001600160a01b038116610d83576040805162461bcd60e51b815260206004820152600260248201526118b760f11b604482015290519081900360640190fd5b610d8c33610e6d565b6000546001600160a01b0382811691161461070e57600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f5425363a03f182281120f5919107c49c7a1a623acc1cbc6df468b6f0c11fcf8c9181900360200190a150565b6001600160a01b03811660009081526002602052604081205461ffff168061094d576040805162461bcd60e51b8152602060048201526002602482015261316960f01b604482015290519081900360640190fd5b6000546001600160a01b031681565b60046020526000908152604090205460ff1681565b6000546001600160a01b0382811691161461070e576040805162461bcd60e51b8152602060048201526002602482015261316760f01b604482015290519081900360640190fd5b60036020526000908152604090205460ff1681565b60026020526000908152604090205461ffff1681565b3b151590565b6060610f1884604051602001808263ffffffff1660e01b81526004019150506040516020818303038152906040526111e9565b610f4c8460405160200180826001600160a01b031660601b81526014019150506040516020818303038152906040526111e9565b610f808460405160200180826001600160a01b031660601b81526014019150506040516020818303038152906040526111e9565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3134310000006020820190815290603d0160216112ac823960210184805190602001908083835b60208310610fe45780518252601f199092019160209182019101610fc5565b51815160209384036101000a600019018019909216911617905268521b932b0ba37b91d160b51b919093019081528551600a90910192860191508083835b602083106110415780518252601f199092019160209182019101611022565b51815160209384036101000a60001901801990921691161790526852330b1ba37b93c9d160b51b919093019081528451600a90910192850191508083835b6020831061109e5780518252601f19909201916020918201910161107f565b6001836020036101000a038019825116818451168082178552505050505050905001935050505060405160208183030381529060405290509392505050565b60008251604114611119576040805162461bcd60e51b81526020600482015260016024820152600560fc1b604482015290519081900360640190fd5b60008060006020860151925060408601519150606086015160001a9050600060018683868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611192573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166111df576040805162461bcd60e51b81526020600482015260026024820152611c0d60f21b604482015290519081900360640190fd5b9695505050505050565b60606000825160020267ffffffffffffffff8111801561120857600080fd5b506040519080825280601f01601f191660200182016040528015611233576020820181803683370190505b5090506020830183518101602083015b818310156112a157825160f81c6f6665646362613938373635343332313060088260041c021c60f81b82526f66656463626139383736353433323130600882600f16021c60f81b600183015250600183019250600281019050611243565b509194935050505056fe0a43726561746f722773206163636f756e7420494420696e207a6b53796e633a20a2646970667358221220c6a0c5ae82a2b4caaf3089a086a98d6633657bec5a18916b0fbdfbe041616c7b64736f6c63430007060033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061014d5760003560e01c8063ce09e20d116100c3578063ead317621161007c578063ead3176214610514578063f39349ef1461053a578063f3a65bf914610542578063f5f84ed414610563578063fa52c7d814610589578063fc97a303146105af5761014d565b8063ce09e20d14610433578063d48bfca714610459578063d4b6846d1461047f578063e122b7d114610487578063e2c79268146104b9578063e4c0aaf4146104ee5761014d565b8063622574701161011557806362257470146102c557806378393d22146102f35780637e1c0c09146103195780638d1db94014610338578063b79eb8c714610340578063c4dcb92c146103725761014d565b806310603dad14610152578063253946451461018f578063439fab91146102015780634623c91d146102715780634b18bd0f1461029f575b600080fd5b6101736004803603602081101561016857600080fd5b503561ffff166105d5565b604080516001600160a01b039092168252519081900360200190f35b6101ff600480360360208110156101a557600080fd5b8101906020810181356401000000008111156101c057600080fd5b8201836020820111156101d257600080fd5b803590602001918460018302840111640100000000831117156101f457600080fd5b5090925090506105f0565b005b6101ff6004803603602081101561021757600080fd5b81019060208101813564010000000081111561023257600080fd5b82018360208201111561024457600080fd5b8035906020019184600183028401116401000000008311171561026657600080fd5b5090925090506105f4565b6101ff6004803603604081101561028757600080fd5b506001600160a01b038135169060200135151561062d565b6101ff600480360360208110156102b557600080fd5b50356001600160a01b03166106bc565b6101ff600480360360408110156102db57600080fd5b506001600160a01b0381351690602001351515610711565b6101ff6004803603602081101561030957600080fd5b50356001600160a01b0316610820565b610321610892565b6040805161ffff9092168252519081900360200190f35b6101736108a3565b6101736004803603604081101561035657600080fd5b50803563ffffffff1690602001356001600160a01b03166108b2565b6101ff6004803603606081101561038857600080fd5b63ffffffff823516916001600160a01b03602082013516918101906060810160408201356401000000008111156103be57600080fd5b8201836020820111156103d057600080fd5b803590602001918460018302840111640100000000831117156103f257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610953945050505050565b6101ff6004803603602081101561044957600080fd5b50356001600160a01b0316610a9f565b6101ff6004803603602081101561046f57600080fd5b50356001600160a01b0316610b77565b610173610cf7565b6101736004803603604081101561049d57600080fd5b50803563ffffffff1690602001356001600160a01b0316610d06565b6104da600480360360208110156104cf57600080fd5b503561ffff16610d2c565b604080519115158252519081900360200190f35b6101ff6004803603602081101561050457600080fd5b50356001600160a01b0316610d43565b6103216004803603602081101561052a57600080fd5b50356001600160a01b0316610df5565b610173610e49565b6104da6004803603602081101561055857600080fd5b503561ffff16610e58565b6101ff6004803603602081101561057957600080fd5b50356001600160a01b0316610e6d565b6104da6004803603602081101561059f57600080fd5b50356001600160a01b0316610eb4565b610321600480360360208110156105c557600080fd5b50356001600160a01b0316610ec9565b6001602052600090815260409020546001600160a01b031681565b5050565b60008282602081101561060657600080fd5b506000805491356001600160a01b03166001600160a01b0319909216919091179055505050565b61063633610e6d565b6001600160a01b03821660009081526003602052604090205460ff161515811515146105f0576001600160a01b038216600081815260036020908152604091829020805460ff1916851515908117909155825190815291517f065b77b53864e46fda3d8986acb51696223d6dde7ced42441eb150bae6d481369281900390910190a25050565b6001600160a01b03811660009081526003602052604090205460ff1661070e576040805162461bcd60e51b8152602060048201526002602482015261062d60f31b604482015290519081900360640190fd5b50565b61071a33610e6d565b6000306001600160a01b031663ead31762846040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561076957600080fd5b505afa15801561077d573d6000803e3d6000fd5b505050506040513d602081101561079357600080fd5b505161ffff811660009081526004602052604090205490915060ff1615158215151461081b5761ffff8116600090815260046020908152604091829020805460ff1916851515908117909155825190815291516001600160a01b038616927ff72cbadf0693609a042637541df35c63e7e074363dea6efb5c19d6c7814ceee992908290030190a25b505050565b61082933610e6d565b6005546001600160a01b0382811691161461070e57600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517fb24c0fc80a0c2a8c6a406f1f63ac240a949e45444715e77bcb06073a1a1d401c9181900360200190a150565b600054600160a01b900461ffff1681565b6005546001600160a01b031681565b63ffffffff821660009081526006602090815260408083206001600160a01b0380861685529252822054168015806108f057506108ee81610edf565b155b1561094a576007546001600160a01b0316610937576040805162461bcd60e51b8152602060048201526002602482015261667360f01b604482015290519081900360640190fd5b50506007546001600160a01b031661094d565b90505b92915050565b63ffffffff831660009081526006602090815260408083206001600160a01b03868116855292529091205416156109b5576040805162461bcd60e51b81526020600482015260016024820152605160f81b604482015290519081900360640190fd5b60006109c2848433610ee5565b80519060200120905060006109d783836110dd565b9050836001600160a01b0316816001600160a01b031614610a24576040805162461bcd60e51b8152602060048201526002602482015261777360f01b604482015290519081900360640190fd5b63ffffffff851660008181526006602090815260408083206001600160a01b0389168085529083529281902080546001600160a01b03191633908117909155815190815290519293927fa31b86f0827cd4eabf087b77e866f658278cb60e2d7c291d407edaada53408e0929181900390910190a35050505050565b610aa833610e6d565b6001600160a01b038116610ae9576040805162461bcd60e51b81526020600482015260036024820152626d623160e81b604482015290519081900360640190fd5b6007546001600160a01b031615610b2d576040805162461bcd60e51b815260206004820152600360248201526236b11960e91b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f9678384f56a2d29e9db5747e5910c194dde921293922f2463582d8c25b96533090600090a250565b6005546001600160a01b03163314610bbb576040805162461bcd60e51b8152602060048201526002602482015261314560f01b604482015290519081900360640190fd5b6001600160a01b03811660009081526002602052604090205461ffff1615610c0f576040805162461bcd60e51b8152602060048201526002602482015261316560f01b604482015290519081900360640190fd5b6000546103ff600160a01b90910461ffff1610610c58576040805162461bcd60e51b815260206004820152600260248201526118b360f11b604482015290519081900360640190fd5b60008054600161ffff600160a01b808404821683018216810261ffff60a01b1990941693909317808555929092049091168083526020918252604080842080546001600160a01b0387166001600160a01b031990911681179091558085526002909352808420805461ffff1916831790555190928392917ffe74dea79bde70d1990ddb655bac45735b14f495ddc508cfab80b7729aa9d6689190a35050565b6007546001600160a01b031681565b60066020908152600092835260408084209091529082529020546001600160a01b031681565b600054600160a01b900461ffff9081169116111590565b6001600160a01b038116610d83576040805162461bcd60e51b815260206004820152600260248201526118b760f11b604482015290519081900360640190fd5b610d8c33610e6d565b6000546001600160a01b0382811691161461070e57600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f5425363a03f182281120f5919107c49c7a1a623acc1cbc6df468b6f0c11fcf8c9181900360200190a150565b6001600160a01b03811660009081526002602052604081205461ffff168061094d576040805162461bcd60e51b8152602060048201526002602482015261316960f01b604482015290519081900360640190fd5b6000546001600160a01b031681565b60046020526000908152604090205460ff1681565b6000546001600160a01b0382811691161461070e576040805162461bcd60e51b8152602060048201526002602482015261316760f01b604482015290519081900360640190fd5b60036020526000908152604090205460ff1681565b60026020526000908152604090205461ffff1681565b3b151590565b6060610f1884604051602001808263ffffffff1660e01b81526004019150506040516020818303038152906040526111e9565b610f4c8460405160200180826001600160a01b031660601b81526014019150506040516020818303038152906040526111e9565b610f808460405160200180826001600160a01b031660601b81526014019150506040516020818303038152906040526111e9565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3134310000006020820190815290603d0160216112ac823960210184805190602001908083835b60208310610fe45780518252601f199092019160209182019101610fc5565b51815160209384036101000a600019018019909216911617905268521b932b0ba37b91d160b51b919093019081528551600a90910192860191508083835b602083106110415780518252601f199092019160209182019101611022565b51815160209384036101000a60001901801990921691161790526852330b1ba37b93c9d160b51b919093019081528451600a90910192850191508083835b6020831061109e5780518252601f19909201916020918201910161107f565b6001836020036101000a038019825116818451168082178552505050505050905001935050505060405160208183030381529060405290509392505050565b60008251604114611119576040805162461bcd60e51b81526020600482015260016024820152600560fc1b604482015290519081900360640190fd5b60008060006020860151925060408601519150606086015160001a9050600060018683868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611192573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166111df576040805162461bcd60e51b81526020600482015260026024820152611c0d60f21b604482015290519081900360640190fd5b9695505050505050565b60606000825160020267ffffffffffffffff8111801561120857600080fd5b506040519080825280601f01601f191660200182016040528015611233576020820181803683370190505b5090506020830183518101602083015b818310156112a157825160f81c6f6665646362613938373635343332313060088260041c021c60f81b82526f66656463626139383736353433323130600882600f16021c60f81b600183015250600183019250600281019050611243565b509194935050505056fe0a43726561746f722773206163636f756e7420494420696e207a6b53796e633a20a2646970667358221220c6a0c5ae82a2b4caaf3089a086a98d6633657bec5a18916b0fbdfbe041616c7b64736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.