From 5600364df7ae65d4922220be8637caeb47b826d1 Mon Sep 17 00:00:00 2001 From: Team1 Date: Wed, 5 Apr 2023 20:34:27 +0000 Subject: [PATCH] se eliminaron documentos --- EIPS/eip-998.md | 1378 ----------------------------------------------- EIPS/eip-999.md | 157 ------ 2 files changed, 1535 deletions(-) delete mode 100644 EIPS/eip-998.md delete mode 100644 EIPS/eip-999.md diff --git a/EIPS/eip-998.md b/EIPS/eip-998.md deleted file mode 100644 index b50c261..0000000 --- a/EIPS/eip-998.md +++ /dev/null @@ -1,1378 +0,0 @@ ---- -eip: 998 -title: Composable Non-Fungible Token -description: Extends a ERC-721 to own other ERC-721 and ERC-20 tokens. -author: Matt Lockyer , Nick Mudge , Jordan Schalm , sebastian echeverry , Zainan Victor Zhou (@xinbenlv) -discussions-to: https://ethereum-magicians.org/t/erc-998-composable-non-fungible-tokens-cnfts/387 -status: Draft -type: Standards Track -category: ERC -created: 2018-07-07 -requires: 20, 165, 721 ---- - -## Abstract - -An extension of the [ERC-721 standard](./eip-721.md) to enable ERC-721 tokens to own other ERC-721 tokens and [ERC-20](./eip-20.md) tokens. - -An extension of the [ERC-20](./eip-20.md) and `ERC-223 https://github.com/ethereum/EIPs/issues/223` standards to enable ERC-20 and `ERC-223` tokens to be owned by ERC-721 tokens. - -This specification covers four different kinds of composable tokens: - -1. [`ERC998ERC721` top-down composable tokens that receive, hold and transfer ERC-721 tokens](#erc-721-top-down-composable) -2. [`ERC998ERC20` top-down composable tokens that receive, hold and transfer ERC-20 tokens](#erc-20-top-down-composable) -3. [`ERC998ERC721` bottom-up composable tokens that attach themselves to other ERC-721 tokens.](#erc-721-bottom-up-composable) -4. [`ERC998ERC20` bottom-up composable tokens that attach themselves to ERC-721 tokens.](#erc-20-bottom-up-composable) - -which map to - -1. An `ERC998ERC721` top-down composable is an ERC-721 token with additional functionality for owning other ERC-721 tokens. -2. An `ERC998ERC20` top-down composable is an ERC-721 token with additional functionality for owning ERC-20 tokens. -3. An `ERC998ERC721` bottom-up composable is an ERC-721 token with additional functionality for being owned by an ERC-721 token. -4. An `ERC998ERC20` bottom-up composable is an ERC-20 token with additional functionality for being owned by an ERC-721 token. - -A top-down composable contract stores and keeps track of child tokens for each of its tokens. - -A bottom-up composable contract stores and keeps track of a parent token for each its tokens. - -With composable tokens it is possible to compose lists or trees of ERC-721 and ERC-20 tokens connected by ownership. Any such structure will have a single owner address at the root of the structure that is the owner of the entire composition. The entire composition can be transferred with one transaction by changing the root owner. - -Different composables, top-down and bottom-up, have their advantages and disadvantages which are explained in the [Rational section](#rationale). It is possible for a token to be one or more kinds of composable token. - -A non-fungible token is compliant and Composable of this EIP if it implements one or more of the following interfaces: - -* `ERC998ERC721TopDown` -* `ERC998ERC20TopDown` -* `ERC998ERC721BottomUp` -* `ERC998ERC20BottomUp` - -## Specification - -### ERC-721 - -`ERC998ERC721` top-down, `ERC998ERC20` top-down, and `ERC998ERC721` bottom-up composable contracts must implement the [ERC-721 interface](./eip-721.md). - -### ERC-20 - -`ERC998ERC20` bottom-up composable contracts must implement the [ERC-20 interface](./eip-20.md). - -### [ERC-165](./eip-165.md) - -The [ERC-165 standard](./eip-165.md) must be applied to each [ERC-998](./eip-998.md) interface that is used. - -### Authentication - -Authenticating whether a user or contract can execute some action works the same for both `ERC998ERC721` top-down and `ERC998ERC721` bottom-up composables. - -A `rootOwner` refers to the owner address at the top of a tree of composables and ERC-721 tokens. - -Authentication within any composable is done by finding the rootOwner and comparing it to `msg.sender`, the return result of `getApproved(tokenId)` and the return result of `isApprovedForAll(rootOwner, msg.sender)`. If a match is found then authentication passes, otherwise authentication fails and the contract throws. - -Here is an example of authentication code: - -```solidity -address rootOwner = address(rootOwnerOf(_tokenId)); -require(rootOwner == msg.sender || - isApprovedForAll(rootOwner,msg.sender) || - getApproved(tokenId) == msg.sender; -``` - -The `approve(address _approved, uint256 _tokenId)` and `getApproved(uint256 _tokenId)` ERC-721 functions are implemented specifically for the rootOwner. This enables a tree of composables to be transferred to a new rootOwner without worrying about which addresses have been approved in child composables, because any prior approves can only be used by the prior rootOwner. - -Here are example implementations: - -```solidity -function approve(address _approved, uint256 _tokenId) external { - address rootOwner = address(rootOwnerOf(_tokenId)); - require(rootOwner == msg.sender || isApprovedForAll(rootOwner,msg.sender)); - - rootOwnerAndTokenIdToApprovedAddress[rootOwner][_tokenId] = _approved; - emit Approval(rootOwner, _approved, _tokenId); -} - -function getApproved(uint256 _tokenId) public view returns (address) { - address rootOwner = address(rootOwnerOf(_tokenId)); - return rootOwnerAndTokenIdToApprovedAddress[rootOwner][_tokenId]; -} -``` - -### Traversal - -The rootOwner of a composable is gotten by calling `rootOwnerOf(uint256 _tokenId)` or `rootOwnerOfChild(address _childContract, uint256 _childTokenId)`. These functions are used by top-down and bottom-up composables to traverse up the tree of composables and ERC-721 tokens to find the rootOwner. - -`ERC998ERC721` top-down and bottom-up composables are interoperable with each other. It is possible for a top-down composable to own a bottom-up composable or for a top-down composable to own an ERC-721 token that owns a bottom-up token. In any configuration calling `rootOwnerOf(uint256 _tokenID)` on a composable will return the root owner address at the top of the ownership tree. - -It is important to get the traversal logic of `rootOwnerOf` right. The logic for `rootOwnerOf` is the same whether or not a composable is bottom-up or top-down or both. -Here is the logic: - -``` -Logic for rootOwnerOf(uint256 _tokenId) - -If the token is a bottom-up composable and has a parent token then call rootOwnerOf for the parent token. - If the call was successful then the returned address is the rootOwner. - Otherwise call rootOwnerOfChild for the parent token. - If the call was successful then the returned address is the rootOwner. - Otherwise get the owner address of the token and that is the rootOwner. -Otherwise call rootOwnerOfChild for the token - If the call was successful then the returned address is the rootOwner. - Otherwise get the owner address of the token and that is the rootOwner. -``` - -Calling `rootOwnerOfChild` for a token means the following logic: - -```solidity -// Logic for calling rootOwnerOfChild for a tokenId -address tokenOwner = ownerOf(tokenId); -address childContract = address(this); -bytes32 rootOwner = ERC998ERC721(tokenOwner).rootOwnerOfChild(childContract, tokenId); -``` - -But understand that the real call to `rootOwnerOfChild` should be made with assembly so that the code can check if the call failed and so that the `staticcall` opcode is used to ensure that no state is modified. - -Tokens/contracts that implement the above authentication and traversal functionality are "composable aware". - -### Composable Transfer Function Parameter Format - -Composable functions that make transfers follow the same parameter format: **from:to:what**. - -For example the `getChild(address _from, uint256 _tokenId, address _childContract, uint256 _childTokenId)` composable function transfers an ERC-721 token from an address to a top-down composable. The `_from` parameter is the **from**, the `_tokenId` parameter is the **to** and the `address _childContract, uint256 _childTokenId` parameters are the **what**. - -Another example is the `safeTransferChild(uint256 _fromTokenId, address _to, address _childContract, uint256 _childTokenId)` function. The `_fromTokenId` is the **from**, the `_to` is the **to** and the `address _childContract, address _childTokenId` parameters are the **what**. - -### transferFrom/safeTransferFrom Functions Do Not Transfer Tokens Owned By Tokens - -In bottom-up and top-down composable contracts the `transferFrom` and `safeTransferFrom` functions must throw if they are called directly to transfer a token that is owned by another token. - -The reason for this is that these functions do not explicitly specify which token owns a token to be transferred. [See the rational section for more information about this.](#explicit-transfer-parameters) - -`transferFrom/safeTransferFrom` functions must be used to transfer tokens that are owned by an address. - - -### ERC-721 Top-Down Composable - -ERC-721 top-down composables act as containers for ERC-721 tokens. - -ERC-721 top-down composables are ERC-721 tokens that can receive, hold and transfer ERC-721 tokens. - -There are two ways to transfer a ERC-721 token to a top-down composable: - -1. Use the `function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data)` function. The `_to` argument is the top-down composable contract address. The `bytes data` argument holds the integer value of the top-down composable tokenId that the ERC-721 token is transferred to. -2. Call `approve` in the ERC-721 token contract for the top-down composable contract. Then call `getChild` in the composable contract. - -The first ways is for ERC-721 contracts that have a `safeTransferFrom` function. The second way is for contracts that do not have this function such as cryptokitties. - -Here is an example of transferring ERC-721 token 3 from an address to top-down composable token 6: - -```solidity -uint256 tokenId = 6; -bytes memory tokenIdBytes = new bytes(32); -assembly { mstore(add(tokenIdBytes, 32), tokenId) } -ERC721(contractAddress).safeTransferFrom(userAddress, composableAddress, 3, tokenIdBytes); -``` - -Every ERC-721 top-down composable compliant contract must implement the `ERC998ERC721TopDown` interface. - -The `ERC998ERC721TopDownEnumerable` and `ERC998ERC20TopDownEnumerable` interfaces are optional. - -```solidity -pragma solidity ^0.4.24; - -/// @title `ERC998ERC721` Top-Down Composable Non-Fungible Token -/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md -/// Note: the ERC-165 identifier for this interface is 0xcde244d9 -interface ERC998ERC721TopDown { - - /// @dev This emits when a token receives a child token. - /// @param _from The prior owner of the token. - /// @param _toTokenId The token that receives the child token. - event ReceivedChild( - address indexed _from, - uint256 indexed _toTokenId, - address indexed _childContract, - uint256 _childTokenId - ); - - /// @dev This emits when a child token is transferred from a token to an address. - /// @param _fromTokenId The parent token that the child token is being transferred from. - /// @param _to The new owner address of the child token. - event TransferChild( - uint256 indexed _fromTokenId, - address indexed _to, - address indexed _childContract, - uint256 _childTokenId - ); - - /// @notice Get the root owner of tokenId. - /// @param _tokenId The token to query for a root owner address - /// @return rootOwner The root owner at the top of tree of tokens and ERC-998 magic value. - function rootOwnerOf(uint256 _tokenId) public view returns (bytes32 rootOwner); - - /// @notice Get the root owner of a child token. - /// @param _childContract The contract address of the child token. - /// @param _childTokenId The tokenId of the child. - /// @return rootOwner The root owner at the top of tree of tokens and ERC-998 magic value. - function rootOwnerOfChild( - address _childContract, - uint256 _childTokenId - ) - public - view - returns (bytes32 rootOwner); - - /// @notice Get the parent tokenId of a child token. - /// @param _childContract The contract address of the child token. - /// @param _childTokenId The tokenId of the child. - /// @return parentTokenOwner The parent address of the parent token and ERC-998 magic value - /// @return parentTokenId The parent tokenId of _tokenId - function ownerOfChild( - address _childContract, - uint256 _childTokenId - ) - external - view - returns ( - bytes32 parentTokenOwner, - uint256 parentTokenId - ); - - /// @notice A token receives a child token - /// @param _operator The address that caused the transfer. - /// @param _from The owner of the child token. - /// @param _childTokenId The token that is being transferred to the parent. - /// @param _data Up to the first 32 bytes contains an integer which is the receiving parent tokenId. - function onERC721Received( - address _operator, - address _from, - uint256 _childTokenId, - bytes _data - ) - external - returns(bytes4); - - /// @notice Transfer child token from top-down composable to address. - /// @param _fromTokenId The owning token to transfer from. - /// @param _to The address that receives the child token - /// @param _childContract The ERC-721 contract of the child token. - /// @param _childTokenId The tokenId of the token that is being transferred. - function transferChild( - uint256 _fromTokenId, - address _to, - address _childContract, - uint256 _childTokenId - ) - external; - - /// @notice Transfer child token from top-down composable to address. - /// @param _fromTokenId The owning token to transfer from. - /// @param _to The address that receives the child token - /// @param _childContract The ERC-721 contract of the child token. - /// @param _childTokenId The tokenId of the token that is being transferred. - function safeTransferChild( - uint256 _fromTokenId, - address _to, - address _childContract, - uint256 _childTokenId - ) - external; - - /// @notice Transfer child token from top-down composable to address. - /// @param _fromTokenId The owning token to transfer from. - /// @param _to The address that receives the child token - /// @param _childContract The ERC-721 contract of the child token. - /// @param _childTokenId The tokenId of the token that is being transferred. - /// @param _data Additional data with no specified format - function safeTransferChild( - uint256 _fromTokenId, - address _to, - address _childContract, - uint256 _childTokenId, - bytes _data - ) - external; - - /// @notice Transfer bottom-up composable child token from top-down composable to other ERC-721 token. - /// @param _fromTokenId The owning token to transfer from. - /// @param _toContract The ERC-721 contract of the receiving token - /// @param _toTokenId The receiving token - /// @param _childContract The bottom-up composable contract of the child token. - /// @param _childTokenId The token that is being transferred. - /// @param _data Additional data with no specified format - function transferChildToParent( - uint256 _fromTokenId, - address _toContract, - uint256 _toTokenId, - address _childContract, - uint256 _childTokenId, - bytes _data - ) - external; - - /// @notice Get a child token from an ERC-721 contract. - /// @param _from The address that owns the child token. - /// @param _tokenId The token that becomes the parent owner - /// @param _childContract The ERC-721 contract of the child token - /// @param _childTokenId The tokenId of the child token - function getChild( - address _from, - uint256 _tokenId, - address _childContract, - uint256 _childTokenId - ) - external; -} -``` - -#### `rootOwnerOf` 1 - -```solidity -/// @notice Get the root owner of tokenId. -/// @param _tokenId The token to query for a root owner address -/// @return rootOwner The root owner at the top of tree of tokens and ERC-998 magic value. -function rootOwnerOf(uint256 _tokenId) public view returns (bytes32 rootOwner); -``` - -This function traverses token owners until the the root owner address of `_tokenId` is found. - -The first 4 bytes of rootOwner contain the ERC-998 magic value `0xcd740db5`. The last 20 bytes contain the root owner address. - -The magic value is returned because this function may be called on contracts when it is unknown if the contracts have a `rootOwnerOf` function. The magic value is used in such calls to ensure a valid return value is received. - -If it is unknown whether a contract has the `rootOwnerOf` function then the first four bytes of the `rootOwner` return value must be compared to `0xcd740db5`. - -`0xcd740db5` is equal to: - -```solidity -this.rootOwnerOf.selector ^ this.rootOwnerOfChild.selector ^ -this.tokenOwnerOf.selector ^ this.ownerOfChild.selector; -``` - -Here is an example of a value returned by `rootOwnerOf`. -`0xcd740db50000000000000000e5240103e1ff986a2c8ae6b6728ffe0d9a395c59` - -#### rootOwnerOfChild - -```solidity -/// @notice Get the root owner of a child token. -/// @param _childContract The contract address of the child token. -/// @param _childTokenId The tokenId of the child. -/// @return rootOwner The root owner at the top of tree of tokens and ERC-998 magic value. -function rootOwnerOfChild( - address _childContract, - uint256 _childTokenId -) - public - view - returns (bytes32 rootOwner); -``` - -This function traverses token owners until the the root owner address of the supplied child token is found. - -The first 4 bytes of rootOwner contain the ERC-998 magic value `0xcd740db5`. The last 20 bytes contain the root owner address. - -The magic value is returned because this function may be called on contracts when it is unknown if the contracts have a `rootOwnerOf` function. The magic value is used in such calls to ensure a valid return value is received. - -If it is unknown whether a contract has the `rootOwnerOfChild` function then the first four bytes of the `rootOwner` return value must be compared to `0xcd740db5`. - -#### ownerOfChild - -```solidity -/// @notice Get the parent tokenId of a child token. -/// @param _childContract The contract address of the child token. -/// @param _childTokenId The tokenId of the child. -/// @return parentTokenOwner The parent address of the parent token and ERC-998 magic value -/// @return parentTokenId The parent tokenId of _tokenId -function ownerOfChild( - address _childContract, - uint256 _childTokenId -) - external - view - returns ( - address parentTokenOwner, - uint256 parentTokenId - ); -``` - -This function is used to get the parent tokenId of a child token and get the owner address of the parent token. - -The first 4 bytes of parentTokenOwner contain the ERC-998 magic value `0xcd740db5`. The last 20 bytes contain the parent token owner address. - -The magic value is returned because this function may be called on contracts when it is unknown if the contracts have a `ownerOfChild` function. The magic value is used in such calls to ensure a valid return value is received. - -If it is unknown whether a contract has the `ownerOfChild` function then the first four bytes of the `parentTokenOwner` return value must be compared to `0xcd740db5`. - -#### `onERC721Received` - -```solidity -/// @notice A token receives a child token -/// @param _operator The address that caused the transfer. -/// @param _from The prior owner of the child token. -/// @param _childTokenId The token that is being transferred to the parent. -/// @param _data Up to the first 32 bytes contains an integer which is the receiving parent tokenId. -function onERC721Received( - address _operator, - address _from, - uint256 _childTokenId, - bytes _data -) - external - returns(bytes4); -``` - -This is a function defined in the ERC-721 standard. This function is called in an ERC-721 contract when `safeTransferFrom` is called. The `bytes _data` argument contains an integer value from 1 to 32 bytes long that is the parent tokenId that an ERC-721 token is transferred to. - -The `onERC721Received` function is how a top-down composable contract is notified that an ERC-721 token has been transferred to it and what tokenId in the top-down composable is the parent tokenId. - -The return value for `onERC721Received` is the magic value `0x150b7a02` which is equal to `bytes4(keccak256(abi.encodePacked("onERC721Received(address,address,uint256,bytes)")))`. - -#### transferChild - -```solidity -/// @notice Transfer child token from top-down composable to address. -/// @param _fromTokenId The owning token to transfer from. -/// @param _to The address that receives the child token -/// @param _childContract The ERC-721 contract of the child token. -/// @param _childTokenId The tokenId of the token that is being transferred. -function transferChild( - uint256 _fromTokenId, - address _to, - address _childContract, - uint256 _childTokenId -) - external; -``` - -This function authenticates `msg.sender` and transfers a child token from a top-down composable to a different address. - -This function makes this call within it: - -```solidity -ERC721(_childContract).transferFrom(this, _to, _childTokenId); -``` - -#### safeTransferChild 1 - -```solidity -/// @notice Transfer child token from top-down composable to address. -/// @param _fromTokenId The owning token to transfer from. -/// @param _to The address that receives the child token -/// @param _childContract The ERC-721 contract of the child token. -/// @param _childTokenId The tokenId of the token that is being transferred. -function safeTransferChild( - uint256 _fromTokenId, - address _to, - address _childContract, - uint256 _childTokenId -) - external; -``` - -This function authenticates `msg.sender` and transfers a child token from a top-down composable to a different address. - -This function makes this call within it: - -```solidity -ERC721(_childContract).safeTransferFrom(this, _to, _childTokenId); -``` - -#### safeTransferChild 2 - -```solidity -/// @notice Transfer child token from top-down composable to address or other top-down composable. -/// @param _fromTokenId The owning token to transfer from. -/// @param _to The address that receives the child token -/// @param _childContract The ERC721 contract of the child token. -/// @param _childTokenId The tokenId of the token that is being transferred. -/// @param _data Additional data with no specified format, can be used to specify tokenId to transfer to -function safeTransferChild( - uint256 _fromTokenId, - address _to, - address _childContract, - uint256 _childTokenId, - bytes _data -) - external; -``` - -This function authenticates `msg.sender` and transfers a child token from a top-down composable to a different address or to a different top-down composable. - -A child token is transferred to a different top-down composable if the `_to` address is a top-down composable contract and `bytes _data` is supplied an integer representing the parent tokenId. - -This function makes this call within it: - -```solidity -ERC721(_childContract).safeTransferFrom(this, _to, _childTokenId, _data); -``` - -#### transferChildToParent - -```solidity -/// @notice Transfer bottom-up composable child token from top-down composable to other ERC-721 token. -/// @param _fromTokenId The owning token to transfer from. -/// @param _toContract The ERC-721 contract of the receiving token -/// @param _toToken The receiving token -/// @param _childContract The bottom-up composable contract of the child token. -/// @param _childTokenId The token that is being transferred. -/// @param _data Additional data with no specified format -function transferChildToParent( - uint256 _fromTokenId, - address _toContract, - uint256 _toTokenId, - address _childContract, - uint256 _childTokenId, - bytes _data -) - external -``` - -This function authenticates `msg.sender` and transfers a child bottom-up composable token from a top-down composable to a different ERC-721 token. This function can only be used when the child token is a bottom-up composable token. It is designed to transfer a bottom-up composable token from a top-down composable to an ERC-721 token (bottom-up style) in one transaction. - -This function makes this call within it: - -```solidity -ERC998ERC721BottomUp(_childContract).transferToParent( - address(this), - _toContract, - _toTokenId, - _childTokenId, - _data -); -``` - -#### getChild - -```solidity -/// @notice Get a child token from an ERC-721 contract. -/// @param _from The address that owns the child token. -/// @param _tokenId The token that becomes the parent owner -/// @param _childContract The ERC-721 contract of the child token -/// @param _childTokenId The tokenId of the child token -function getChild( - address _from, - uint256 _tokenId, - address _childContract, - uint256 _childTokenId -) - external; -``` - -This function is used to transfer an ERC-721 token when its contract does not have a `safeTransferChild(uint256 _fromTokenId, address _to, address _childContract, uint256 _childTokenId, bytes _data)` function. - -A transfer with this function is done in two steps: - -1. The owner of the ERC-721 token calls `approve` or `setApprovalForAll` in the ERC-721 contract for the top-down composable contract. -2. The owner of the ERC-721 token calls `getChild` in the top-down composable contract for the ERC-721 token. - -The `getChild` function must authenticate that `msg.sender` is the owner of the ERC-721 token in the ERC-721 contract or is approved or an operator of the ERC-721 token in the ERC-721 contract. - -#### ERC-721 Top-Down Composable Enumeration - -Optional interface for top-down composable enumeration: - -```solidity -/// @dev The ERC-165 identifier for this interface is 0xa344afe4 -interface ERC998ERC721TopDownEnumerable { - - /// @notice Get the total number of child contracts with tokens that are owned by tokenId. - /// @param _tokenId The parent token of child tokens in child contracts - /// @return uint256 The total number of child contracts with tokens owned by tokenId. - function totalChildContracts(uint256 _tokenId) external view returns(uint256); - - /// @notice Get child contract by tokenId and index - /// @param _tokenId The parent token of child tokens in child contract - /// @param _index The index position of the child contract - /// @return childContract The contract found at the tokenId and index. - function childContractByIndex( - uint256 _tokenId, - uint256 _index - ) - external - view - returns (address childContract); - - /// @notice Get the total number of child tokens owned by tokenId that exist in a child contract. - /// @param _tokenId The parent token of child tokens - /// @param _childContract The child contract containing the child tokens - /// @return uint256 The total number of child tokens found in child contract that are owned by tokenId. - function totalChildTokens( - uint256 _tokenId, - address _childContract - ) - external - view - returns(uint256); - - /// @notice Get child token owned by tokenId, in child contract, at index position - /// @param _tokenId The parent token of the child token - /// @param _childContract The child contract of the child token - /// @param _index The index position of the child token. - /// @return childTokenId The child tokenId for the parent token, child token and index - function childTokenByIndex( - uint256 _tokenId, - address _childContract, - uint256 _index - ) - external - view - returns (uint256 childTokenId); -} -``` - -### ERC-20 Top-Down Composable - -ERC-20 top-down composables act as containers for ERC-20 tokens. - -ERC-20 top-down composables are ERC-721 tokens that can receive, hold and transfer ERC-20 tokens. - -There are two ways to transfer ERC-20 tokens to an ERC-20 Top-Down Composable: - -1. Use the `transfer(address _to, uint256 _value, bytes _data);` function from the `ERC-223` contract. The `_to` argument is the ERC-20 top-down composable contract address. The `_value` argument is how many ERC-20 tokens to transfer. The `bytes` argument holds the integer value of the top-down composable tokenId that receives the ERC-20 tokens. -2. Call `approve` in the ERC-20 contract for the ERC-20 top-down composable contract. Then call `getERC20(address _from, uint256 _tokenId, address _erc20Contract, uint256 _value)` from the ERC-20 top-down composable contract. - -The first way is for ERC-20 contracts that support the `ERC-223` standard. The second way is for contracts that do not. - -ERC-20 top-down composables implement the following interface: - -```solidity -/// @title `ERC998ERC20` Top-Down Composable Non-Fungible Token -/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md -/// Note: the ERC-165 identifier for this interface is 0x7294ffed -interface ERC998ERC20TopDown { - - /// @dev This emits when a token receives ERC-20 tokens. - /// @param _from The prior owner of the token. - /// @param _toTokenId The token that receives the ERC-20 tokens. - /// @param _erc20Contract The ERC-20 contract. - /// @param _value The number of ERC-20 tokens received. - event ReceivedERC20( - address indexed _from, - uint256 indexed _toTokenId, - address indexed _erc20Contract, - uint256 _value - ); - - /// @dev This emits when a token transfers ERC-20 tokens. - /// @param _tokenId The token that owned the ERC-20 tokens. - /// @param _to The address that receives the ERC-20 tokens. - /// @param _erc20Contract The ERC-20 contract. - /// @param _value The number of ERC-20 tokens transferred. - event TransferERC20( - uint256 indexed _fromTokenId, - address indexed _to, - address indexed _erc20Contract, - uint256 _value - ); - - /// @notice A token receives ERC-20 tokens - /// @param _from The prior owner of the ERC-20 tokens - /// @param _value The number of ERC-20 tokens received - /// @param _data Up to the first 32 bytes contains an integer which is the receiving tokenId. - function tokenFallback(address _from, uint256 _value, bytes _data) external; - - /// @notice Look up the balance of ERC-20 tokens for a specific token and ERC-20 contract - /// @param _tokenId The token that owns the ERC-20 tokens - /// @param _erc20Contract The ERC-20 contract - /// @return The number of ERC-20 tokens owned by a token from an ERC-20 contract - function balanceOfERC20( - uint256 _tokenId, - address _erc20Contract - ) - external - view - returns(uint256); - - /// @notice Transfer ERC-20 tokens to address - /// @param _tokenId The token to transfer from - /// @param _value The address to send the ERC-20 tokens to - /// @param _erc20Contract The ERC-20 contract - /// @param _value The number of ERC-20 tokens to transfer - function transferERC20( - uint256 _tokenId, - address _to, - address _erc20Contract, - uint256 _value - ) - external; - - /// @notice Transfer ERC-20 tokens to address or ERC-20 top-down composable - /// @param _tokenId The token to transfer from - /// @param _value The address to send the ERC-20 tokens to - /// @param _erc223Contract The `ERC-223` token contract - /// @param _value The number of ERC-20 tokens to transfer - /// @param _data Additional data with no specified format, can be used to specify tokenId to transfer to - function transferERC223( - uint256 _tokenId, - address _to, - address _erc223Contract, - uint256 _value, - bytes _data - ) - external; - - /// @notice Get ERC-20 tokens from ERC-20 contract. - /// @param _from The current owner address of the ERC-20 tokens that are being transferred. - /// @param _tokenId The token to transfer the ERC-20 tokens to. - /// @param _erc20Contract The ERC-20 token contract - /// @param _value The number of ERC-20 tokens to transfer - function getERC20( - address _from, - uint256 _tokenId, - address _erc20Contract, - uint256 _value - ) - external; -} -``` - -#### tokenFallback - -```solidity -/// @notice A token receives ERC-20 tokens -/// @param _from The prior owner of the ERC-20 tokens -/// @param _value The number of ERC-20 tokens received -/// @param _data Up to the first 32 bytes contains an integer which is the receiving tokenId. -function tokenFallback(address _from, uint256 _value, bytes _data) external; -``` - -This function comes from the `ERC-223` which is an extension of the ERC-20 standard. This function is called on the receiving contract from the sending contract when ERC-20 tokens are transferred. This function is how the ERC-20 top-down composable contract gets notified that one of its tokens received ERC-20 tokens. Which token received ERC-20 tokens is specified in the `_data` parameter. - -#### `balanceOfERC20` - -```solidity -/// @notice Look up the balance of ERC-20 tokens for a specific token and ERC-20 contract -/// @param _tokenId The token that owns the ERC-20 tokens -/// @param _erc20Contract The ERC-20 contract -/// @return The number of ERC-20 tokens owned by a token from an ERC-20 contract -function balanceOfERC20( - uint256 _tokenId, - address _erc20Contract -) - external - view - returns(uint256); -``` - -Gets the balance of ERC-20 tokens owned by a token from a specific ERC-20 contract. - -#### `transferERC20` - -```solidity -/// @notice Transfer ERC-20 tokens to address -/// @param _tokenId The token to transfer from -/// @param _value The address to send the ERC-20 tokens to -/// @param _erc20Contract The ERC-20 contract -/// @param _value The number of ERC-20 tokens to transfer -function transferERC20( - uint256 _tokenId, - address _to, - address _erc20Contract, - uint256 _value -) - external; -``` - -This is used to transfer ERC-20 tokens from a token to an address. This function calls `ERC20(_erc20Contract).transfer(_to, _value)`; - -This function must authenticate `msg.sender`. - -#### `transferERC223` - -```solidity - /// @notice Transfer ERC-20 tokens to address or ERC-20 top-down composable - /// @param _tokenId The token to transfer from - /// @param _value The address to send the ERC-20 tokens to - /// @param _erc223Contract The `ERC-223` token contract - /// @param _value The number of ERC-20 tokens to transfer - /// @param _data Additional data with no specified format, can be used to specify tokenId to transfer to - function transferERC223( - uint256 _tokenId, - address _to, - address _erc223Contract, - uint256 _value, - bytes _data - ) - external; -``` - -This function is from the `ERC-223`. It is used to transfer ERC-20 tokens from a token to an address or to another token by putting an integer token value in the `_data` argument. - -This function must authenticate `msg.sender`. - -#### `getERC20` - -```solidity -/// @notice Get ERC-20 tokens from ERC-20 contract. -/// @param _from The current owner address of the ERC-20 tokens that are being transferred. -/// @param _tokenId The token to transfer the ERC-20 tokens to. -/// @param _erc20Contract The ERC-20 token contract -/// @param _value The number of ERC-20 tokens to transfer -function getERC20( - address _from, - uint256 _tokenId, - address _erc20Contract, - uint256 _value -) - external; -``` - -This function is used to transfer ERC-20 tokens to an ERC-20 top-down composable when an ERC-20 contract does not have a `transferERC223(uint256 _tokenId, address _to, address _erc223Contract, uint256 _value, bytes _data)` function. - -Before this function can be used the ERC-20 top-down composable contract address must be approved in the ERC-20 contract to transfer the ERC-20 tokens. - -This function must authenticate that `msg.sender` equals `_from` or has been approved in the ERC-20 contract. - -#### ERC-20 Top-Down Composable Enumeration - -Optional interface for top-down composable enumeration: - -```solidity -/// @dev The ERC-165 identifier for this interface is 0xc5fd96cd -interface ERC998ERC20TopDownEnumerable { - - /// @notice Get the number of ERC-20 contracts that token owns ERC-20 tokens from - /// @param _tokenId The token that owns ERC-20 tokens. - /// @return uint256 The number of ERC-20 contracts - function totalERC20Contracts(uint256 _tokenId) external view returns(uint256); - - /// @notice Get an ERC-20 contract that token owns ERC-20 tokens from by index - /// @param _tokenId The token that owns ERC-20 tokens. - /// @param _index The index position of the ERC-20 contract. - /// @return address The ERC-20 contract - function erc20ContractByIndex( - uint256 _tokenId, - uint256 _index - ) - external - view - returns(address); -} -``` - -### ERC-721 Bottom-Up Composable - -ERC-721 bottom-up composables are ERC-721 tokens that attach themselves to other ERC-721 tokens. - -ERC-721 bottom-up composable contracts store the owning address of a token and the parent tokenId if any. - -```solidity -/// @title `ERC998ERC721` Bottom-Up Composable Non-Fungible Token -/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md -/// Note: the ERC-165 identifier for this interface is 0xa1b23002 -interface ERC998ERC721BottomUp { - - /// @dev This emits when a token is transferred to an ERC-721 token - /// @param _toContract The contract the token is transferred to - /// @param _toTokenId The token the token is transferred to - /// @param _tokenId The token that is transferred - event TransferToParent( - address indexed _toContract, - uint256 indexed _toTokenId, - uint256 _tokenId - ); - - /// @dev This emits when a token is transferred from an ERC-721 token - /// @param _fromContract The contract the token is transferred from - /// @param _fromTokenId The token the token is transferred from - /// @param _tokenId The token that is transferred - event TransferFromParent( - address indexed _fromContract, - uint256 indexed _fromTokenId, - uint256 _tokenId - ); - - /// @notice Get the root owner of tokenId. - /// @param _tokenId The token to query for a root owner address - /// @return rootOwner The root owner at the top of tree of tokens and ERC-998 magic value. - function rootOwnerOf(uint256 _tokenId) external view returns (bytes32 rootOwner); - - /// @notice Get the owner address and parent token (if there is one) of a token - /// @param _tokenId The tokenId to query. - /// @return tokenOwner The owner address of the token - /// @return parentTokenId The parent owner of the token and ERC-998 magic value - /// @return isParent True if parentTokenId is a valid parent tokenId and false if there is no parent tokenId - function tokenOwnerOf( - uint256 _tokenId - ) - external - view - returns ( - bytes32 tokenOwner, - uint256 parentTokenId, - bool isParent - ); - - /// @notice Transfer token from owner address to a token - /// @param _from The owner address - /// @param _toContract The ERC-721 contract of the receiving token - /// @param _toToken The receiving token - /// @param _data Additional data with no specified format - function transferToParent( - address _from, - address _toContract, - uint256 _toTokenId, - uint256 _tokenId, - bytes _data - ) - external; - - /// @notice Transfer token from a token to an address - /// @param _fromContract The address of the owning contract - /// @param _fromTokenId The owning token - /// @param _to The address the token is transferred to. - /// @param _tokenId The token that is transferred - /// @param _data Additional data with no specified format - function transferFromParent( - address _fromContract, - uint256 _fromTokenId, - address _to, - uint256 _tokenId, - bytes _data - ) - external; - - /// @notice Transfer a token from a token to another token - /// @param _fromContract The address of the owning contract - /// @param _fromTokenId The owning token - /// @param _toContract The ERC-721 contract of the receiving token - /// @param _toToken The receiving token - /// @param _tokenId The token that is transferred - /// @param _data Additional data with no specified format - function transferAsChild( - address _fromContract, - uint256 _fromTokenId, - address _toContract, - uint256 _toTokenId, - uint256 _tokenId, - bytes _data - ) - external; -} -``` - -#### `rootOwnerOf` - -```solidity -/// @notice Get the root owner of tokenId. -/// @param _tokenId The token to query for a root owner address -/// @return rootOwner The root owner at the top of tree of tokens and ERC-998 magic value. -function rootOwnerOf(uint256 _tokenId) public view returns (bytes32 rootOwner); -``` - -This function traverses token owners until the the root owner address of `_tokenId` is found. - -The first 4 bytes of rootOwner contain the ERC-998 magic value `0xcd740db5`. The last 20 bytes contain the root owner address. - -The magic value is returned because this function may be called on contracts when it is unknown if the contracts have a `rootOwnerOf` function. The magic value is used in such calls to ensure a valid return value is received. - -If it is unknown whether a contract has the `rootOwnerOf` function then the first four bytes of the `rootOwner` return value must be compared to `0xcd740db5`. - -`0xcd740db5` is equal to: - -```solidity -this.rootOwnerOf.selector ^ this.rootOwnerOfChild.selector ^ -this.tokenOwnerOf.selector ^ this.ownerOfChild.selector; -``` - -Here is an example of a value returned by `rootOwnerOf`. -`0xcd740db50000000000000000e5240103e1ff986a2c8ae6b6728ffe0d9a395c59` - -#### tokenOwnerOf - -```solidity -/// @notice Get the owner address and parent token (if there is one) of a token -/// @param _tokenId The tokenId to query. -/// @return tokenOwner The owner address of the token and ERC-998 magic value. -/// @return parentTokenId The parent owner of the token -/// @return isParent True if parentTokenId is a valid parent tokenId and false if there is no parent tokenId -function tokenOwnerOf( - uint256 _tokenId -) - external - view - returns ( - bytes32 tokenOwner, - uint256 parentTokenId, - bool isParent - ); -``` - -This function is used to get the owning address and parent tokenId of a token if there is one stored in the contract. - -If `isParent` is true then `tokenOwner` is the owning ERC-721 contract address and `parentTokenId` is a valid parent tokenId. If `isParent` is false then `tokenOwner` is a user address and `parentTokenId` does not contain a valid parent tokenId and must be ignored. - -The first 4 bytes of `tokenOwner` contain the ERC-998 magic value `0xcd740db5`. The last 20 bytes contain the token owner address. - -The magic value is returned because this function may be called on contracts when it is unknown if the contracts have a `tokenOwnerOf` function. The magic value is used in such calls to ensure a valid return value is received. - -If it is unknown whether a contract has the `rootOwnerOf` function then the first four bytes of the `tokenOwner` return value must be compared to `0xcd740db5`. - -#### transferToParent - -```solidity -/// @notice Transfer token from owner address to a token -/// @param _from The owner address -/// @param _toContract The ERC-721 contract of the receiving token -/// @param _toToken The receiving token -/// @param _data Additional data with no specified format -function transferToParent( - address _from, - address _toContract, - uint256 _toTokenId, - uint256 _tokenId, - bytes _data -) - external; -``` - -This function is used to transfer a token from an address to a token. `msg.sender` must be authenticated. - -This function must check that `_toToken` exists in `_toContract` and throw if not. - -#### transferFromParent - -```solidity -/// @notice Transfer token from a token to an address -/// @param _fromContract The address of the owning contract -/// @param _fromTokenId The owning token -/// @param _to The address the token is transferred to. -/// @param _tokenId The token that is transferred -/// @param _data Additional data with no specified format -function transferFromParent( - address _fromContract, - uint256 _fromTokenId, - address _to, - uint256 _tokenId, - bytes _data -) - external; -``` - -This function is used to transfer a token from a token to an address. `msg.sender` must be authenticated. - -This function must check that `_fromContract` and `_fromTokenId` own `_tokenId` and throw not. - -#### transferAsChild - -```solidity -/// @notice Transfer a token from a token to another token -/// @param _fromContract The address of the owning contract -/// @param _fromTokenId The owning token -/// @param _toContract The ERC-721 contract of the receiving token -/// @param _toToken The receiving token -/// @param _tokenId The token that is transferred -/// @param _data Additional data with no specified format -function transferAsChild( - address _fromContract, - uint256 _fromTokenId, - address _toContract, - uint256 _toTokenId, - uint256 _tokenId, - bytes _data -) - external; -``` - -This function is used to transfer a token from a token to another token. `msg.sender` must be authenticated. - -This function must check that `_toToken` exists in `_toContract` and throw if not. - -This function must check that `_fromContract` and `_fromTokenId` own `_tokenId` and throw if not. - -#### ERC-721 Bottom-Up Composable Enumeration - -Optional interface for bottom-up composable enumeration: - -```solidity -/// @dev The ERC-165 identifier for this interface is 0x8318b539 -interface ERC998ERC721BottomUpEnumerable { - - /// @notice Get the number of ERC-721 tokens owned by parent token. - /// @param _parentContract The contract the parent ERC-721 token is from. - /// @param _parentTokenId The parent tokenId that owns tokens - // @return uint256 The number of ERC-721 tokens owned by parent token. - function totalChildTokens( - address _parentContract, - uint256 _parentTokenId - ) - external - view - returns (uint256); - - /// @notice Get a child token by index - /// @param _parentContract The contract the parent ERC-721 token is from. - /// @param _parentTokenId The parent tokenId that owns the token - /// @param _index The index position of the child token - /// @return uint256 The child tokenId owned by the parent token - function childTokenByIndex( - address _parentContract, - uint256 _parentTokenId, - uint256 _index - ) - external - view - returns (uint256); -} -``` - -### ERC-20 Bottom-Up Composable - -ERC-20 bottom-up composables are ERC-20 tokens that attach themselves to ERC-721 tokens, or are owned by a user address like standard ERC-20 tokens. - -When owned by an ERC-721 token, ERC-20 bottom-up composable contracts store the owning address of a token and the parent tokenId. ERC-20 bottom-up composables add several methods to the ERC-20 and `ERC-223` interfaces allowing for querying the balance of parent tokens, and transferring tokens to, from, and between parent tokens. - -This functionality can be implemented by adding one additional mapping to track balances of tokens, in addition to the standard mapping for tracking user address balances. - -```solidity -/// @dev This mapping tracks standard ERC20/`ERC-223` ownership, where an address owns -/// a particular amount of tokens. -mapping(address => uint) userBalances; - -/// @dev This additional mapping tracks ERC-998 ownership, where an ERC-721 token owns -/// a particular amount of tokens. This tracks contractAddres => tokenId => balance -mapping(address => mapping(uint => uint)) nftBalances; -``` - -The complete interface is below. - -```solidity -/// @title `ERC998ERC20` Bottom-Up Composable Fungible Token -/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md -/// Note: The ERC-165 identifier for this interface is 0xffafa991 -interface ERC998ERC20BottomUp { - - /// @dev This emits when a token is transferred to an ERC-721 token - /// @param _toContract The contract the token is transferred to - /// @param _toTokenId The token the token is transferred to - /// @param _amount The amount of tokens transferred - event TransferToParent( - address indexed _toContract, - uint256 indexed _toTokenId, - uint256 _amount - ); - - /// @dev This emits when a token is transferred from an ERC-721 token - /// @param _fromContract The contract the token is transferred from - /// @param _fromTokenId The token the token is transferred from - /// @param _amount The amount of tokens transferred - event TransferFromParent( - address indexed _fromContract, - uint256 indexed _fromTokenId, - uint256 _amount - ); - - /// @notice Get the balance of a non-fungible parent token - /// @param _tokenContract The contract tracking the parent token - /// @param _tokenId The ID of the parent token - /// @return amount The balance of the token - function balanceOfToken( - address _tokenContract, - uint256 _tokenId - ) - external - view - returns (uint256 amount); - - /// @notice Transfer tokens from owner address to a token - /// @param _from The owner address - /// @param _toContract The ERC-721 contract of the receiving token - /// @param _toToken The receiving token - /// @param _amount The amount of tokens to transfer - function transferToParent( - address _from, - address _toContract, - uint256 _toTokenId, - uint256 _amount - ) - external; - - /// @notice Transfer token from a token to an address - /// @param _fromContract The address of the owning contract - /// @param _fromTokenId The owning token - /// @param _to The address the token is transferred to - /// @param _amount The amount of tokens to transfer - function transferFromParent( - address _fromContract, - uint256 _fromTokenId, - address _to, - uint256 _amount - ) - external; - - /// @notice Transfer token from a token to an address, using `ERC-223` semantics - /// @param _fromContract The address of the owning contract - /// @param _fromTokenId The owning token - /// @param _to The address the token is transferred to - /// @param _amount The amount of tokens to transfer - /// @param _data Additional data with no specified format, can be used to specify the sender tokenId - function transferFromParentERC223( - address _fromContract, - uint256 _fromTokenId, - address _to, - uint256 _amount, - bytes _data - ) - external; - - /// @notice Transfer a token from a token to another token - /// @param _fromContract The address of the owning contract - /// @param _fromTokenId The owning token - /// @param _toContract The ERC-721 contract of the receiving token - /// @param _toToken The receiving token - /// @param _amount The amount tokens to transfer - function transferAsChild( - address _fromContract, - uint256 _fromTokenId, - address _toContract, - uint256 _toTokenId, - uint256 _amount - ) - external; -} -``` - -#### balanceOfToken - -```solidity -/// @notice Get the balance of a non-fungible parent token -/// @param _tokenContract The contract tracking the parent token -/// @param _tokenId The ID of the parent token -/// @return amount The balance of the token -function balanceOfToken( - address _tokenContract, - uint256 _tokenId -) - external - view - returns (uint256 amount); -``` - -This function returns the balance of a non-fungible token. It mirrors the standard ERC-20 method `balanceOf`, but accepts the address of the parent token's contract, and the parent token's ID. This method behaves identically to `balanceOf`, but checks for ownership by ERC-721 tokens rather than user addresses. - -#### `transferToParent` - -```solidity -/// @notice Transfer tokens from owner address to a token -/// @param _from The owner address -/// @param _toContract The ERC-721 contract of the receiving token -/// @param _toToken The receiving token -/// @param _amount The amount of tokens to transfer -function transferToParent( - address _from, - address _toContract, - uint256 _toTokenId, - uint256 _amount -) - external; -``` - -This function transfers an amount of tokens from a user address to an ERC-721 token. This function MUST ensure that the recipient contract implements ERC-721 using the ERC-165 `supportsInterface` function. This function SHOULD ensure that the recipient token actually exists, by calling `ownerOf` on the recipient token's contract, and ensuring it neither throws nor returns the zero address. This function MUST emit the `TransferToParent` event upon a successful transfer (in addition to the standard ERC-20 `Transfer` event!). This function MUST throw if the `_from` account balance does not have enough tokens to spend. - -#### `transferFromParent` - -```solidity -/// @notice Transfer token from a token to an address -/// @param _fromContract The address of the owning contract -/// @param _fromTokenId The owning token -/// @param _to The address the token is transferred to -/// @param _amount The amount of tokens to transfer -function transferFromParent( - address _fromContract, - uint256 _fromTokenId, - address _to, - uint256 _amount -) - external; -``` - -This function transfers an amount of tokens from an ERC-721 token to an address. This function MUST emit the `TransferFromParent` event upon a successful transfer (in addition to the standard ERC-20 `Transfer` event!). This function MUST throw if the balance of the sender ERC-721 token is less than the `_amount` specified. This function MUST verify that the `msg.sender` owns the sender ERC-721 token, and MUST throw otherwise. - -#### `transferFromParentERC223` - -```solidity -/// @notice Transfer token from a token to an address, using `ERC-223` semantics -/// @param _fromContract The address of the owning contract -/// @param _fromTokenId The owning token -/// @param _to The address the token is transferred to -/// @param _amount The amount of tokens to transfer -/// @param _data Additional data with no specified format, can be used to specify the sender tokenId -function transferFromParentERC223( - address _fromContract, - uint256 _fromTokenId, - address _to, - uint256 _amount, - bytes _data -) - external; -``` - -This function transfers an amount of tokens from an ERC-721 token to an address. This function has identical requirements to `transferFromParent`, except that it additionally MUST invoke `tokenFallback` on the recipient address, if the address is a contract, as specified by `ERC-223`. - -#### transferAsChild 1 - -```solidity -/// @notice Transfer a token from a token to another token -/// @param _fromContract The address of the owning contract -/// @param _fromTokenId The owning token -/// @param _toContract The ERC-721 contract of the receiving token -/// @param _toToken The receiving token -/// @param _amount The amount tokens to transfer -function transferAsChild( - address _fromContract, - uint256 _fromTokenId, - address _toContract, - uint256 _toTokenId, - uint256 _amount -) - external; -``` - -This function transfers an amount of tokens from an ERC-721 token to another ERC-721 token. This function MUST emit BOTH the `TransferFromParent` and `TransferToParent` events (in addition to the standard ERC-20 `Transfer` event!). This function MUST throw if the balance of the sender ERC-721 token is less than the `_amount` specified. This function MUST verify that the `msg.sender` owns the sender ERC-721 token, and MUST throw otherwise. This function MUST ensure that the recipient contract implements ERC-721 using the ERC-165 `supportsInterface` function. This function SHOULD ensure that the recipient token actually exists, by calling `ownerOf` on the recipient token's contract, and ensuring it neither throws nor returns the zero address. - -### Notes - -For backwards-compatibility, implementations MUST emit the standard ERC-20 `Transfer` event when a transfer occurs, regardless of whether the sender and recipient are addresses or ERC-721 tokens. In the case that either sender or recipient are tokens, the corresponding parameter in the `Transfer` event SHOULD be the contract address of the token. - -Implementations MUST implement all ERC-20 and `ERC-223` functions in addition to the functions specified in this interface. - -## Rationale - -Two different kinds of composable (top-down and bottom-up) exist to handle different use cases. A regular ERC-721 token cannot own a top-down composable, but it can own a bottom-up composable. A bottom-up composable cannot own a regular ERC-721 but a top-down composable can own a regular ERC-721 token. Having multiple kinds of composables enable different token ownership possibilities. - -### Which Kind of Composable To Use? - -If you want to transfer regular ERC-721 tokens to non-fungible tokens, then use top-down composables. - -If you want to transfer non-fungible tokens to regular ERC-721 tokens then use bottom-up composables. - -### Explicit Transfer Parameters - -Every ERC-998 transfer function includes explicit parameters to specify the prior owner and the new owner of a token. Explicitly providing **from** and **to** is done intentionally to avoid situations where tokens are transferred in unintended ways. - -Here is an example of what could occur if **from** was not explicitly provided in transfer functions: -> An exchange contract is an approved operator in a specific composable contract for user A, user B and user C. -> -> User A transfers token 1 to user B. At the same time the exchange contract transfers token 1 to user C (with the implicit intention to transfer from user A). User B gets token 1 for a minute before it gets incorrectly transferred to user C. The second transfer should have failed but it didn't because no explicit **from** was provided to ensure that token 1 came from user A. - -## Backwards Compatibility - -Composables are designed to work with ERC-721, `ERC-223` and ERC-20 tokens. - -Some older ERC-721 contracts do not have a `safeTransferFrom` function. The `getChild` function can still be used to transfer a token to an ERC-721 top-down composable. - -If an ERC-20 contract does not have the `ERC-223` function `transfer(address _to, uint _value, bytes _data)` then the `getERC20` function can still be used to transfer ERC-20 tokens to an ERC-20 top-down composable. - -## Reference Implementation - -An implementation can be found here: `https://github.com/mattlockyer/composables-998` - -## Security Considerations - -Needs discussion. - - -## Copyright - -Copyright and related rights waived via [CC0](../LICENSE.md). - - - diff --git a/EIPS/eip-999.md b/EIPS/eip-999.md deleted file mode 100644 index dccc159..0000000 --- a/EIPS/eip-999.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -eip: 999 -title: Restore Contract Code at 0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4 -author: Afri Schoedon (@5chdn) -discussions-to: https://ethereum-magicians.org/t/eip-999-restore-contract-code-at-0x863df6bfa4/130 -status: Withdrawn -type: Standards Track -category: Core -created: 2018-04-04 ---- - -## Simple Summary -This document proposes to restore the contract code of the `WalletLibrary` -contract at `0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4` with a patched version. -The contract was accidentally self-destructed and renders a significant amount -of Ether inaccessible. - -## Abstract -The `WalletLibrary` contract was used by the -[Parity Wallet](https://www.parity.io/) to reduce gas costs for users deploying -multi-signature wallets on the Ethereum blockchain. It contained basic -functionality such as confirming or revoking multi-signature transactions for -any wallet deployed that depends on this library. The -[accidental self-destruction](https://github.com/paritytech/parity/issues/6995) -of the library contract caused significant amounts of Ether and other assets -owned by many different parties to be inaccessible. This proposal suggests -restoring the `WalletLibrary` by a -[patched](https://github.com/parity-contracts/0x863df6bfa4) version to allow the -owners of the dependent multi-signature wallets regain access to their assets. - -## Motivation -This proposal is necessary because the Ethereum protocol does not allow the -restoration of self-destructed contracts and there is no other simple way to -enable the affected users and companies regaining access to their tokens and -Ether. In opposite to previously discussed proposals, this will not change any -EVM semantics and tries to achieve the goal of unfreezing the funds by a single -state transition as specified in the next section. - -## Specification -The self-destructed contract code at -[`0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4`](https://etherscan.io/address/0x863df6bfa4469f3ead0be8f9f2aae51c91a907b4#code) -shall be replaced with a patched version of the -[`walletLibrary.sol`](https://github.com/parity-contracts/0x863df6bfa4/blob/master/contracts/walletLibrary.sol) -as reviewed, tested, and approved in -[parity-contracts/0x863df6bfa4](https://github.com/parity-contracts/0x863df6bfa4): - -```json -{ - "object": "606060405234156200000d57fe5b5b6000808054806001018281620000259190620002d9565b916000526020600020900160005b6000909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200012081805480602002602001604051908101604052809291908181526020018280548015620000fd57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311620000b2575b505050505060016000620001286401000000000262001d46176401000000009004565b5b5062000330565b600060015411156200013a5760006000fd5b6200015981620001806401000000000262001d71176401000000009004565b620001798383620001c26401000000000262001d9c176401000000009004565b5b5b505050565b60006001541115620001925760006000fd5b80600281905550620001b7620002c16401000000000262001bcf176401000000009004565b6004819055505b5b50565b600060006001541115620001d65760006000fd5b600082111515620001e75760006000fd5b81835110151515620001f95760006000fd5b8251600181905550600090505b8251811015620002b35782818151811015156200021f57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16600582600101610100811015156200025357fe5b0160005b508190555080600101610105600085848151811015156200027457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b80600101905062000206565b816000819055505b5b505050565b60006201518042811515620002d257fe5b0490505b90565b815481835581811511620003035781836000526020600020918201910162000302919062000308565b5b505050565b6200032d91905b80821115620003295760008160009055506001016200030f565b5090565b90565b611ebf80620003406000396000f300606060405236156100ef576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063173825d91461016d5780632f54bf6e146101a35780634123cb6b146101f157806352375093146102175780635c52c2f51461023d578063659010e71461024f5780637065cb4814610275578063746c9171146102ab578063797af627146102d1578063b20d30a91461030d578063b61d27f61461032d578063b75c7dc61461039c578063ba51a6df146103c0578063c2cf7326146103e0578063c41a360a1461043b578063f00d4b5d1461049b578063f1736d86146104f0575b61016b5b6000341115610168577fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3334604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b565b005b341561017557fe5b6101a1600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610516565b005b34156101ab57fe5b6101d7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610659565b604051808215151515815260200191505060405180910390f35b34156101f957fe5b610201610691565b6040518082815260200191505060405180910390f35b341561021f57fe5b610227610697565b6040518082815260200191505060405180910390f35b341561024557fe5b61024d61069d565b005b341561025757fe5b61025f6106d7565b6040518082815260200191505060405180910390f35b341561027d57fe5b6102a9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106dd565b005b34156102b357fe5b6102bb610829565b6040518082815260200191505060405180910390f35b34156102d957fe5b6102f360048080356000191690602001909190505061082f565b604051808215151515815260200191505060405180910390f35b341561031557fe5b61032b6004808035906020019091905050610dcc565b005b341561033557fe5b61037e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919080359060200190820180359060200191909192905050610e06565b60405180826000191660001916815260200191505060405180910390f35b34156103a457fe5b6103be60048080356000191690602001909190505061127d565b005b34156103c857fe5b6103de6004808035906020019091905050611392565b005b34156103e857fe5b61042160048080356000191690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061141a565b604051808215151515815260200191505060405180910390f35b341561044357fe5b610459600480803590602001909190505061149c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a357fe5b6104ee600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114bf565b005b34156104f857fe5b610500611672565b6040518082815260200191505060405180910390f35b600060003660405180838380828437820191505092505050604051809103902061053f81611678565b156106535761010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561057f57610652565b600160015403600054111561059357610652565b6000600583610100811015156105a557fe5b0160005b5081905550600061010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506105e6611890565b6105ee6119d0565b7f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da83604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b505050565b6000600061010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541190505b919050565b60015481565b60045481565b6000366040518083838082843782019150509250505060405180910390206106c481611678565b156106d35760006003819055505b5b5b50565b60035481565b60003660405180838380828437820191505092505050604051809103902061070481611678565b156108245761071282610659565b1561071c57610823565b610724611890565b60fa600154101515610739576107386119d0565b5b60fa60015410151561074a57610823565b6001600081548092919060010191905055508173ffffffffffffffffffffffffffffffffffffffff1660056001546101008110151561078557fe5b0160005b508190555060015461010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c382604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b5050565b60005481565b600060008261083d81611678565b15610dc45760006101086000866000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415806108c757506000610108600086600019166000191681526020019081526020016000206001015414155b80610906575060006101086000866000191660001916815260200190815260200160002060020180546001816001161561010002031660029004905014155b15610dc25760006101086000866000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a5057610a496101086000866000191660001916815260200190815260200160002060010154610108600087600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a3f5780601f10610a1457610100808354040283529160200191610a3f565b820191906000526020600020905b815481529060010190602001808311610a2257829003601f168201915b5050505050611b37565b9150610b71565b6101086000856000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166101086000866000191660001916815260200190815260200160002060010154610108600087600019166000191681526020019081526020016000206002016040518082805460018160011615610100020316600290048015610b4a5780601f10610b1f57610100808354040283529160200191610b4a565b820191906000526020600020905b815481529060010190602001808311610b2d57829003601f168201915b505091505060006040518083038185876185025a03f1925050501515610b705760006000fd5b5b7fe3a3a4111a84df27d76b68dc721e65c7711605ea5eee4afd3a9c58195217365c338561010860008860001916600019168152602001908152602001600020600101546101086000896000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661010860008a6000191660001916815260200190815260200160002060020187604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186600019166000191681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610d475780601f10610d1c57610100808354040283529160200191610d47565b820191906000526020600020905b815481529060010190602001808311610d2a57829003601f168201915b505097505050505050505060405180910390a16101086000856000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000610db79190611be6565b505060019250610dc3565b5b5b5b5050919050565b600036604051808383808284378201915050925050506040518091039020610df381611678565b15610e0157816002819055505b5b5b5050565b60006000610e1333610659565b1561127357600084849050148015610e305750610e2f85611b51565b5b80610e3d57506001600054145b15610fed5760008673ffffffffffffffffffffffffffffffffffffffff161415610ea457610e9d8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611b37565b9050610ef3565b8573ffffffffffffffffffffffffffffffffffffffff168585856040518083838082843782019150509250505060006040518083038185876185025a03f1925050501515610ef25760006000fd5b5b7f9738cd1a8777c86b011f7b01d87d484217dc6ab5154a9d41eda5d14af8caf292338688878786604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437820191505097505050505050505060405180910390a1611271565b6000364360405180848480828437820191505082815260200193505050506040518091039020915060006101086000846000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611099575060006101086000846000191660001916815260200190815260200160002060010154145b80156110d85750600061010860008460001916600019168152602001908152602001600020600201805460018160011615610100020316600290049050145b1561118f57856101086000846000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550846101086000846000191660001916815260200190815260200160002060010181905550838361010860008560001916600019168152602001908152602001600020600201919061118d929190611c2e565b505b6111988261082f565b1515611270577f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328233878988886040518087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b5b5b5b5b50949350505050565b60006000600061010560003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925060008314156112be5761138c565b8260020a9150610106600085600019166000191681526020019081526020016000209050600082826001015416111561138b5780600001600081548092919060010191905055508181600101600082825403925050819055507fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b3385604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182600019166000191681526020019250505060405180910390a15b5b50505050565b6000366040518083838082843782019150509250505060405180910390206113b981611678565b15611415576001548211156113cd57611414565b816000819055506113dc611890565b7facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da826040518082815260200191505060405180910390a15b5b5b5050565b600060006000600061010660008760001916600019168152602001908152602001600020925061010560008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561147f5760009350611493565b8160020a9050600081846001015416141593505b50505092915050565b6000600560018301610100811015156114b157fe5b0160005b505490505b919050565b60006000366040518083838082843782019150509250505060405180910390206114e881611678565b1561166b576114f683610659565b156115005761166a565b61010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561153b5761166a565b611543611890565b8273ffffffffffffffffffffffffffffffffffffffff166005836101008110151561156a57fe5b0160005b5081905550600061010560008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508161010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c8484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b5b5b50505050565b60025481565b600060006000600061010560003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925060008314156116bb57611888565b6101066000866000191660001916815260200190815260200160002091506000826000015414156117455760005482600001819055506000826001018190555061010780548091906001016117109190611cae565b826002018190555084610107836002015481548110151561172d57fe5b906000526020600020900160005b5081600019169055505b8260020a90506000818360010154161415611887577fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda3386604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182600019166000191681526020019250505060405180910390a16001826000015411151561185e57610107610106600087600019166000191681526020019081526020016000206002015481548110151561180a57fe5b906000526020600020900160005b5060009055610106600086600019166000191681526020019081526020016000206000600082016000905560018201600090556002820160009055505060019350611888565b8160000160008154809291906001900391905055508082600101600082825417925050819055505b5b5b505050919050565b60006000610107805490509150600090505b818110156119bc576101086000610107838154811015156118bf57fe5b906000526020600020900160005b50546000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160006119269190611be6565b505060006001026101078281548110151561193d57fe5b906000526020600020900160005b5054600019161415156119b05761010660006101078381548110151561196d57fe5b906000526020600020900160005b505460001916600019168152602001908152602001600020600060008201600090556001820160009055600282016000905550505b5b8060010190506118a2565b61010760006119cb9190611cda565b5b5050565b6000600190505b600154811015611b33575b60015481108015611a095750600060058261010081101515611a0057fe5b0160005b505414155b15611a1b5780806001019150506119e2565b5b6001600154118015611a4557506000600560015461010081101515611a3d57fe5b0160005b5054145b15611a625760016000815480929190600190039190505550611a1c565b60015481108015611a8b57506000600560015461010081101515611a8257fe5b0160005b505414155b8015611aac5750600060058261010081101515611aa457fe5b0160005b5054145b15611b2e57600560015461010081101515611ac357fe5b0160005b505460058261010081101515611ad957fe5b0160005b508190555080610105600060058461010081101515611af857fe5b0160005b50548152602001908152602001600020819055506000600560015461010081101515611b2457fe5b0160005b50819055505b6119d7565b5b50565b600081516020830184f09050803b15610000575b92915050565b6000611b5c33610659565b15611bc957600454611b6c611bcf565b1115611b89576000600381905550611b82611bcf565b6004819055505b600354826003540110158015611ba55750600254826003540111155b15611bc3578160036000828254019250508190555060019050611bc8565b600090505b5b5b919050565b60006201518042811515611bdf57fe5b0490505b90565b50805460018160011615610100020316600290046000825580601f10611c0c5750611c2b565b601f016020900490600052602060002090810190611c2a9190611cfc565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611c6f57803560ff1916838001178555611c9d565b82800160010185558215611c9d579182015b82811115611c9c578235825591602001919060010190611c81565b5b509050611caa9190611cfc565b5090565b815481835581811511611cd557818360005260206000209182019101611cd49190611d21565b5b505050565b5080546000825590600052602060002090810190611cf89190611d21565b5b50565b611d1e91905b80821115611d1a576000816000905550600101611d02565b5090565b90565b611d4391905b80821115611d3f576000816000905550600101611d27565b5090565b90565b60006001541115611d575760006000fd5b611d6081611d71565b611d6a8383611d9c565b5b5b505050565b60006001541115611d825760006000fd5b80600281905550611d91611bcf565b6004819055505b5b50565b600060006001541115611daf5760006000fd5b600082111515611dbf5760006000fd5b81835110151515611dd05760006000fd5b8251600181905550600090505b8251811015611e85578281815181101515611df457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1660058260010161010081101515611e2757fe5b0160005b50819055508060010161010560008584815181101515611e4757fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b806001019050611ddd565b816000819055505b5b5050505600a165627a7a7230582016889f0740f073d397f9d00b0d19900fb050b957e3e2942f861085beb9baab180029", - "opcodes": "PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH3 0xD JUMPI INVALID JUMPDEST JUMPDEST PUSH1 0x0 DUP1 DUP1 SLOAD DUP1 PUSH1 0x1 ADD DUP3 DUP2 PUSH3 0x25 SWAP2 SWAP1 PUSH3 0x2D9 JUMP JUMPDEST SWAP2 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST PUSH1 0x0 SWAP1 SWAP2 SWAP1 SWAP2 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP POP PUSH3 0x120 DUP2 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH3 0xFD JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 ADD SWAP1 DUP1 DUP4 GT PUSH3 0xB2 JUMPI JUMPDEST POP POP POP POP POP PUSH1 0x1 PUSH1 0x0 PUSH3 0x128 PUSH5 0x100000000 MUL PUSH3 0x1D46 OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST JUMPDEST POP PUSH3 0x330 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH3 0x13A JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH3 0x159 DUP2 PUSH3 0x180 PUSH5 0x100000000 MUL PUSH3 0x1D71 OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST PUSH3 0x179 DUP4 DUP4 PUSH3 0x1C2 PUSH5 0x100000000 MUL PUSH3 0x1D9C OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH3 0x192 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP1 PUSH1 0x2 DUP2 SWAP1 SSTORE POP PUSH3 0x1B7 PUSH3 0x2C1 PUSH5 0x100000000 MUL PUSH3 0x1BCF OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST PUSH1 0x4 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH3 0x1D6 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 GT ISZERO ISZERO PUSH3 0x1E7 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP2 DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH3 0x1F9 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 DUP2 SWAP1 SSTORE POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP3 MLOAD DUP2 LT ISZERO PUSH3 0x2B3 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x21F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 DUP3 PUSH1 0x1 ADD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH3 0x253 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP DUP1 PUSH1 0x1 ADD PUSH2 0x105 PUSH1 0x0 DUP6 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x274 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP JUMPDEST DUP1 PUSH1 0x1 ADD SWAP1 POP PUSH3 0x206 JUMP JUMPDEST DUP2 PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH3 0x15180 TIMESTAMP DUP2 ISZERO ISZERO PUSH3 0x2D2 JUMPI INVALID JUMPDEST DIV SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 ISZERO GT PUSH3 0x303 JUMPI DUP2 DUP4 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x302 SWAP2 SWAP1 PUSH3 0x308 JUMP JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH3 0x32D SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x329 JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH3 0x30F JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x1EBF DUP1 PUSH3 0x340 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE CALLDATASIZE ISZERO PUSH2 0xEF JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x173825D9 EQ PUSH2 0x16D JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x1A3 JUMPI DUP1 PUSH4 0x4123CB6B EQ PUSH2 0x1F1 JUMPI DUP1 PUSH4 0x52375093 EQ PUSH2 0x217 JUMPI DUP1 PUSH4 0x5C52C2F5 EQ PUSH2 0x23D JUMPI DUP1 PUSH4 0x659010E7 EQ PUSH2 0x24F JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x275 JUMPI DUP1 PUSH4 0x746C9171 EQ PUSH2 0x2AB JUMPI DUP1 PUSH4 0x797AF627 EQ PUSH2 0x2D1 JUMPI DUP1 PUSH4 0xB20D30A9 EQ PUSH2 0x30D JUMPI DUP1 PUSH4 0xB61D27F6 EQ PUSH2 0x32D JUMPI DUP1 PUSH4 0xB75C7DC6 EQ PUSH2 0x39C JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x3C0 JUMPI DUP1 PUSH4 0xC2CF7326 EQ PUSH2 0x3E0 JUMPI DUP1 PUSH4 0xC41A360A EQ PUSH2 0x43B JUMPI DUP1 PUSH4 0xF00D4B5D EQ PUSH2 0x49B JUMPI DUP1 PUSH4 0xF1736D86 EQ PUSH2 0x4F0 JUMPI JUMPDEST PUSH2 0x16B JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x168 JUMPI PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C CALLER CALLVALUE PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x175 JUMPI INVALID JUMPDEST PUSH2 0x1A1 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x516 JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x1AB JUMPI INVALID JUMPDEST PUSH2 0x1D7 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x659 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x1F9 JUMPI INVALID JUMPDEST PUSH2 0x201 PUSH2 0x691 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x21F JUMPI INVALID JUMPDEST PUSH2 0x227 PUSH2 0x697 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x245 JUMPI INVALID JUMPDEST PUSH2 0x24D PUSH2 0x69D JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x257 JUMPI INVALID JUMPDEST PUSH2 0x25F PUSH2 0x6D7 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x27D JUMPI INVALID JUMPDEST PUSH2 0x2A9 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x6DD JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x2B3 JUMPI INVALID JUMPDEST PUSH2 0x2BB PUSH2 0x829 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x2D9 JUMPI INVALID JUMPDEST PUSH2 0x2F3 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH1 0x0 NOT AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x82F JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x315 JUMPI INVALID JUMPDEST PUSH2 0x32B PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0xDCC JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x335 JUMPI INVALID JUMPDEST PUSH2 0x37E PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP3 ADD DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 SWAP3 SWAP1 POP POP PUSH2 0xE06 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x3A4 JUMPI INVALID JUMPDEST PUSH2 0x3BE PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH1 0x0 NOT AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x127D JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x3C8 JUMPI INVALID JUMPDEST PUSH2 0x3DE PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x1392 JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x3E8 JUMPI INVALID JUMPDEST PUSH2 0x421 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH1 0x0 NOT AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x141A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x443 JUMPI INVALID JUMPDEST PUSH2 0x459 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x149C JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x4A3 JUMPI INVALID JUMPDEST PUSH2 0x4EE PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x14BF JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x4F8 JUMPI INVALID JUMPDEST PUSH2 0x500 PUSH2 0x1672 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x53F DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x653 JUMPI PUSH2 0x105 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP2 POP PUSH1 0x0 DUP3 EQ ISZERO PUSH2 0x57F JUMPI PUSH2 0x652 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 SLOAD SUB PUSH1 0x0 SLOAD GT ISZERO PUSH2 0x593 JUMPI PUSH2 0x652 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x5 DUP4 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x5A5 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH2 0x5E6 PUSH2 0x1890 JUMP JUMPDEST PUSH2 0x5EE PUSH2 0x19D0 JUMP JUMPDEST PUSH32 0x58619076ADF5BB0943D100EF88D52D7C3FD691B19D3A9071B555B651FBF418DA DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD GT SWAP1 POP JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x6C4 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x6D3 JUMPI PUSH1 0x0 PUSH1 0x3 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x3 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x704 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x824 JUMPI PUSH2 0x712 DUP3 PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x71C JUMPI PUSH2 0x823 JUMP JUMPDEST PUSH2 0x724 PUSH2 0x1890 JUMP JUMPDEST PUSH1 0xFA PUSH1 0x1 SLOAD LT ISZERO ISZERO PUSH2 0x739 JUMPI PUSH2 0x738 PUSH2 0x19D0 JUMP JUMPDEST JUMPDEST PUSH1 0xFA PUSH1 0x1 SLOAD LT ISZERO ISZERO PUSH2 0x74A JUMPI PUSH2 0x823 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 ADD SWAP2 SWAP1 POP SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x785 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP PUSH1 0x1 SLOAD PUSH2 0x105 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH32 0x994A936646FE87FFE4F1E469D3D6AA417D6B855598397F323DE5B449F765F0C3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 DUP3 PUSH2 0x83D DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0xDC4 JUMPI PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO DUP1 PUSH2 0x8C7 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD EQ ISZERO JUMPDEST DUP1 PUSH2 0x906 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 POP EQ ISZERO JUMPDEST ISZERO PUSH2 0xDC2 JUMPI PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xA50 JUMPI PUSH2 0xA49 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD PUSH2 0x108 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xA3F JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xA14 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xA3F JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xA22 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP PUSH2 0x1B37 JUMP JUMPDEST SWAP2 POP PUSH2 0xB71 JUMP JUMPDEST PUSH2 0x108 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD PUSH2 0x108 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xB4A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xB1F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xB4A JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xB2D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 PUSH2 0x8502 GAS SUB CALL SWAP3 POP POP POP ISZERO ISZERO PUSH2 0xB70 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST JUMPDEST PUSH32 0xE3A3A4111A84DF27D76B68DC721E65C7711605EA5EEE4AFD3A9C58195217365C CALLER DUP6 PUSH2 0x108 PUSH1 0x0 DUP9 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD PUSH2 0x108 PUSH1 0x0 DUP10 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x108 PUSH1 0x0 DUP11 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP8 PUSH1 0x40 MLOAD DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD DUP6 DUP2 MSTORE PUSH1 0x20 ADD DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xD47 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD1C JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xD47 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xD2A JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP8 POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 PUSH2 0x108 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 PUSH2 0xDB7 SWAP2 SWAP1 PUSH2 0x1BE6 JUMP JUMPDEST POP POP PUSH1 0x1 SWAP3 POP PUSH2 0xDC3 JUMP JUMPDEST JUMPDEST JUMPDEST JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0xDF3 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0xE01 JUMPI DUP2 PUSH1 0x2 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH2 0xE13 CALLER PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x1273 JUMPI PUSH1 0x0 DUP5 DUP5 SWAP1 POP EQ DUP1 ISZERO PUSH2 0xE30 JUMPI POP PUSH2 0xE2F DUP6 PUSH2 0x1B51 JUMP JUMPDEST JUMPDEST DUP1 PUSH2 0xE3D JUMPI POP PUSH1 0x1 PUSH1 0x0 SLOAD EQ JUMPDEST ISZERO PUSH2 0xFED JUMPI PUSH1 0x0 DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xEA4 JUMPI PUSH2 0xE9D DUP6 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP POP POP POP POP PUSH2 0x1B37 JUMP JUMPDEST SWAP1 POP PUSH2 0xEF3 JUMP JUMPDEST DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 PUSH2 0x8502 GAS SUB CALL SWAP3 POP POP POP ISZERO ISZERO PUSH2 0xEF2 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST JUMPDEST PUSH32 0x9738CD1A8777C86B011F7B01D87D484217DC6AB5154A9D41EDA5D14AF8CAF292 CALLER DUP7 DUP9 DUP8 DUP8 DUP7 PUSH1 0x40 MLOAD DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 DUP2 MSTORE PUSH1 0x20 ADD DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP6 DUP6 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP8 POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 PUSH2 0x1271 JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE NUMBER PUSH1 0x40 MLOAD DUP1 DUP5 DUP5 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP4 POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 SWAP2 POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ DUP1 ISZERO PUSH2 0x1099 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD EQ JUMPDEST DUP1 ISZERO PUSH2 0x10D8 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 POP EQ JUMPDEST ISZERO PUSH2 0x118F JUMPI DUP6 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP DUP5 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD DUP2 SWAP1 SSTORE POP DUP4 DUP4 PUSH2 0x108 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD SWAP2 SWAP1 PUSH2 0x118D SWAP3 SWAP2 SWAP1 PUSH2 0x1C2E JUMP JUMPDEST POP JUMPDEST PUSH2 0x1198 DUP3 PUSH2 0x82F JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1270 JUMPI PUSH32 0x1733CBB53659D713B79580F79F3F9FF215F78A7C7AA45890F3B89FC5CDDFBF32 DUP3 CALLER DUP8 DUP10 DUP9 DUP9 PUSH1 0x40 MLOAD DUP1 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP6 DUP2 MSTORE PUSH1 0x20 ADD DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP5 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP8 POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST JUMPDEST JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP3 POP PUSH1 0x0 DUP4 EQ ISZERO PUSH2 0x12BE JUMPI PUSH2 0x138C JUMP JUMPDEST DUP3 PUSH1 0x2 EXP SWAP2 POP PUSH2 0x106 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SWAP1 POP PUSH1 0x0 DUP3 DUP3 PUSH1 0x1 ADD SLOAD AND GT ISZERO PUSH2 0x138B JUMPI DUP1 PUSH1 0x0 ADD PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 ADD SWAP2 SWAP1 POP SSTORE POP DUP2 DUP2 PUSH1 0x1 ADD PUSH1 0x0 DUP3 DUP3 SLOAD SUB SWAP3 POP POP DUP2 SWAP1 SSTORE POP PUSH32 0xC7FB647E59B18047309AA15AAD418E5D7CA96D173AD704F1031A2C3D7591734B CALLER DUP6 PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x13B9 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x1415 JUMPI PUSH1 0x1 SLOAD DUP3 GT ISZERO PUSH2 0x13CD JUMPI PUSH2 0x1414 JUMP JUMPDEST DUP2 PUSH1 0x0 DUP2 SWAP1 SSTORE POP PUSH2 0x13DC PUSH2 0x1890 JUMP JUMPDEST PUSH32 0xACBDB084C721332AC59F9B8E392196C9EB0E4932862DA8EB9BEAF0DAD4F550DA DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH2 0x106 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SWAP3 POP PUSH2 0x105 PUSH1 0x0 DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP2 POP PUSH1 0x0 DUP3 EQ ISZERO PUSH2 0x147F JUMPI PUSH1 0x0 SWAP4 POP PUSH2 0x1493 JUMP JUMPDEST DUP2 PUSH1 0x2 EXP SWAP1 POP PUSH1 0x0 DUP2 DUP5 PUSH1 0x1 ADD SLOAD AND EQ ISZERO SWAP4 POP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 DUP4 ADD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x14B1 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD SWAP1 POP JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x14E8 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x166B JUMPI PUSH2 0x14F6 DUP4 PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x1500 JUMPI PUSH2 0x166A JUMP JUMPDEST PUSH2 0x105 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP2 POP PUSH1 0x0 DUP3 EQ ISZERO PUSH2 0x153B JUMPI PUSH2 0x166A JUMP JUMPDEST PUSH2 0x1543 PUSH2 0x1890 JUMP JUMPDEST DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 DUP4 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x156A JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP DUP2 PUSH2 0x105 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH32 0xB532073B38C83145E3E5135377A08BF9AAB55BC0FD7C1179CD4FB995D2A5159C DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP3 POP PUSH1 0x0 DUP4 EQ ISZERO PUSH2 0x16BB JUMPI PUSH2 0x1888 JUMP JUMPDEST PUSH2 0x106 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SWAP2 POP PUSH1 0x0 DUP3 PUSH1 0x0 ADD SLOAD EQ ISZERO PUSH2 0x1745 JUMPI PUSH1 0x0 SLOAD DUP3 PUSH1 0x0 ADD DUP2 SWAP1 SSTORE POP PUSH1 0x0 DUP3 PUSH1 0x1 ADD DUP2 SWAP1 SSTORE POP PUSH2 0x107 DUP1 SLOAD DUP1 SWAP2 SWAP1 PUSH1 0x1 ADD PUSH2 0x1710 SWAP2 SWAP1 PUSH2 0x1CAE JUMP JUMPDEST DUP3 PUSH1 0x2 ADD DUP2 SWAP1 SSTORE POP DUP5 PUSH2 0x107 DUP4 PUSH1 0x2 ADD SLOAD DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x172D JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP DUP2 PUSH1 0x0 NOT AND SWAP1 SSTORE POP JUMPDEST DUP3 PUSH1 0x2 EXP SWAP1 POP PUSH1 0x0 DUP2 DUP4 PUSH1 0x1 ADD SLOAD AND EQ ISZERO PUSH2 0x1887 JUMPI PUSH32 0xE1C52DC63B719ADE82E8BEA94CC41A0D5D28E4AAF536ADB5E9CCCC9FF8C1AEDA CALLER DUP7 PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 PUSH1 0x1 DUP3 PUSH1 0x0 ADD SLOAD GT ISZERO ISZERO PUSH2 0x185E JUMPI PUSH2 0x107 PUSH2 0x106 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD SLOAD DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x180A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP PUSH1 0x0 SWAP1 SSTORE PUSH2 0x106 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE POP POP PUSH1 0x1 SWAP4 POP PUSH2 0x1888 JUMP JUMPDEST DUP2 PUSH1 0x0 ADD PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 SWAP1 SUB SWAP2 SWAP1 POP SSTORE POP DUP1 DUP3 PUSH1 0x1 ADD PUSH1 0x0 DUP3 DUP3 SLOAD OR SWAP3 POP POP DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH2 0x107 DUP1 SLOAD SWAP1 POP SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x19BC JUMPI PUSH2 0x108 PUSH1 0x0 PUSH2 0x107 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x18BF JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 PUSH2 0x1926 SWAP2 SWAP1 PUSH2 0x1BE6 JUMP JUMPDEST POP POP PUSH1 0x0 PUSH1 0x1 MUL PUSH2 0x107 DUP3 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x193D JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x0 NOT AND EQ ISZERO ISZERO PUSH2 0x19B0 JUMPI PUSH2 0x106 PUSH1 0x0 PUSH2 0x107 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x196D JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE POP POP JUMPDEST JUMPDEST DUP1 PUSH1 0x1 ADD SWAP1 POP PUSH2 0x18A2 JUMP JUMPDEST PUSH2 0x107 PUSH1 0x0 PUSH2 0x19CB SWAP2 SWAP1 PUSH2 0x1CDA JUMP JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SWAP1 POP JUMPDEST PUSH1 0x1 SLOAD DUP2 LT ISZERO PUSH2 0x1B33 JUMPI JUMPDEST PUSH1 0x1 SLOAD DUP2 LT DUP1 ISZERO PUSH2 0x1A09 JUMPI POP PUSH1 0x0 PUSH1 0x5 DUP3 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1A00 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ ISZERO JUMPDEST ISZERO PUSH2 0x1A1B JUMPI DUP1 DUP1 PUSH1 0x1 ADD SWAP2 POP POP PUSH2 0x19E2 JUMP JUMPDEST JUMPDEST PUSH1 0x1 PUSH1 0x1 SLOAD GT DUP1 ISZERO PUSH2 0x1A45 JUMPI POP PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1A3D JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ JUMPDEST ISZERO PUSH2 0x1A62 JUMPI PUSH1 0x1 PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 SWAP1 SUB SWAP2 SWAP1 POP SSTORE POP PUSH2 0x1A1C JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 LT DUP1 ISZERO PUSH2 0x1A8B JUMPI POP PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1A82 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ ISZERO JUMPDEST DUP1 ISZERO PUSH2 0x1AAC JUMPI POP PUSH1 0x0 PUSH1 0x5 DUP3 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AA4 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ JUMPDEST ISZERO PUSH2 0x1B2E JUMPI PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AC3 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x5 DUP3 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AD9 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP DUP1 PUSH2 0x105 PUSH1 0x0 PUSH1 0x5 DUP5 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AF8 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1B24 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP JUMPDEST PUSH2 0x19D7 JUMP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x20 DUP4 ADD DUP5 CREATE SWAP1 POP DUP1 EXTCODESIZE ISZERO PUSH2 0x0 JUMPI JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1B5C CALLER PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x1BC9 JUMPI PUSH1 0x4 SLOAD PUSH2 0x1B6C PUSH2 0x1BCF JUMP JUMPDEST GT ISZERO PUSH2 0x1B89 JUMPI PUSH1 0x0 PUSH1 0x3 DUP2 SWAP1 SSTORE POP PUSH2 0x1B82 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x4 DUP2 SWAP1 SSTORE POP JUMPDEST PUSH1 0x3 SLOAD DUP3 PUSH1 0x3 SLOAD ADD LT ISZERO DUP1 ISZERO PUSH2 0x1BA5 JUMPI POP PUSH1 0x2 SLOAD DUP3 PUSH1 0x3 SLOAD ADD GT ISZERO JUMPDEST ISZERO PUSH2 0x1BC3 JUMPI DUP2 PUSH1 0x3 PUSH1 0x0 DUP3 DUP3 SLOAD ADD SWAP3 POP POP DUP2 SWAP1 SSTORE POP PUSH1 0x1 SWAP1 POP PUSH2 0x1BC8 JUMP JUMPDEST PUSH1 0x0 SWAP1 POP JUMPDEST JUMPDEST JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH3 0x15180 TIMESTAMP DUP2 ISZERO ISZERO PUSH2 0x1BDF JUMPI INVALID JUMPDEST DIV SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST POP DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV PUSH1 0x0 DUP3 SSTORE DUP1 PUSH1 0x1F LT PUSH2 0x1C0C JUMPI POP PUSH2 0x1C2B JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1C2A SWAP2 SWAP1 PUSH2 0x1CFC JUMP JUMPDEST JUMPDEST POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x1C6F JUMPI DUP1 CALLDATALOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x1C9D JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x1C9D JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x1C9C JUMPI DUP3 CALLDATALOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x1C81 JUMP JUMPDEST JUMPDEST POP SWAP1 POP PUSH2 0x1CAA SWAP2 SWAP1 PUSH2 0x1CFC JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 ISZERO GT PUSH2 0x1CD5 JUMPI DUP2 DUP4 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1CD4 SWAP2 SWAP1 PUSH2 0x1D21 JUMP JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST POP DUP1 SLOAD PUSH1 0x0 DUP3 SSTORE SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1CF8 SWAP2 SWAP1 PUSH2 0x1D21 JUMP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH2 0x1D1E SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x1D1A JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH2 0x1D02 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x1D43 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x1D3F JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH2 0x1D27 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH2 0x1D57 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH2 0x1D60 DUP2 PUSH2 0x1D71 JUMP JUMPDEST PUSH2 0x1D6A DUP4 DUP4 PUSH2 0x1D9C JUMP JUMPDEST JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH2 0x1D82 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP1 PUSH1 0x2 DUP2 SWAP1 SSTORE POP PUSH2 0x1D91 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x4 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH2 0x1DAF JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 GT ISZERO ISZERO PUSH2 0x1DBF JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP2 DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x1DD0 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 DUP2 SWAP1 SSTORE POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP3 MLOAD DUP2 LT ISZERO PUSH2 0x1E85 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1DF4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 DUP3 PUSH1 0x1 ADD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1E27 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP DUP1 PUSH1 0x1 ADD PUSH2 0x105 PUSH1 0x0 DUP6 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1E47 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP JUMPDEST DUP1 PUSH1 0x1 ADD SWAP1 POP PUSH2 0x1DDD JUMP JUMPDEST DUP2 PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 SHA3 AND DUP9 SWAP16 SMOD BLOCKHASH CREATE PUSH20 0xD397F9D00B0D19900FB050B957E3E2942F861085 0xbe 0xb9 0xba 0xab XOR STOP 0x29 ", - "sourceMap": "2715:10853:0:-;;;3523:112;;;;;;;3552:18;3574:8;:27;;;;;;;;;;;:::i;:::-;;;;;;;;;;;3596:3;3574:27;;;;;;;;;;;;;;;;;;;;;;;3605:26;3616:8;3605:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3626:1;3629;3605:10;;;;;:26;;;:::i;:::-;3523:112;;2715:10853;;7697:168;7585:1;7571:11;;:15;7567:26;;;7588:5;;;7567:26;7800:23;7813:9;7800:12;;;;;:23;;;:::i;:::-;7827:34;7842:7;7851:9;7827:14;;;;;:34;;;:::i;:::-;7595:1;7697:168;;;;:::o;6966:115::-;7585:1;7571:11;;:15;7567:26;;;7588:5;;;7567:26;7048:6;7033:12;:21;;;;7070:7;:5;;;;;:7;;;:::i;:::-;7058:9;:19;;;;7595:1;6966:115;;:::o;3977:349::-;4171:6;7585:1;7571:11;;:15;7567:26;;;7588:5;;;7567:26;4088:1;4076:9;:13;4068:22;;;;;;;;4120:9;4102:7;:14;:27;;4094:36;;;;;;;;4148:7;:14;4134:11;:28;;;;4180:1;4171:10;;4166:131;4187:7;:14;4183:1;:18;4166:131;;;4238:7;4246:1;4238:10;;;;;;;;;;;;;;;;;;4233:16;;4215:8;4228:1;4224;:5;4215:15;;;;;;;;;;;;:34;;;;;4291:1;4287;:5;4254:12;:30;4272:7;4280:1;4272:10;;;;;;;;;;;;;;;;;;4267:16;;4254:30;;;;;;;;;;;:38;;;;4166:131;4203:3;;;;;4166:131;;;4313:9;4300:10;:22;;;;7595:1;3977:349;;;;:::o;12529:73::-;12572:4;12593:6;12587:3;:12;;;;;;;;12580:19;;12529:73;;:::o;2715:10853::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;", - "linkReferences": {} -} -``` - -To verify the byte-code above, a patched version is deployed at -[`0x21C9E434c669c4d73f55215A6F2130A185E127AC`](https://etherscan.io/address/0x21C9E434c669c4d73f55215A6F2130A185E127AC#code) -to be reviewed. The compiler settings used can be extracted from the following -meta-data: - -```json -{"compiler":{"version":"0.4.10+commit.f0d539ae"},"language":"Solidity","output":{"abi":[{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"removeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_numOwners","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_lastDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"resetSpentToday","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_spentToday","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"addOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_required","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_h","type":"bytes32"}],"name":"confirm","outputs":[{"name":"o_success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newLimit","type":"uint256"}],"name":"setDailyLimit","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"o_hash","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_operation","type":"bytes32"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newRequired","type":"uint256"}],"name":"changeRequirement","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_operation","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"hasConfirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"ownerIndex","type":"uint256"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_dailyLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Confirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"},{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"}],"name":"OwnerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newRequirement","type":"uint256"}],"name":"RequirementChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"},{"indexed":false,"name":"created","type":"address"}],"name":"SingleTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"},{"indexed":false,"name":"created","type":"address"}],"name":"MultiTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"initiator","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"ConfirmationNeeded","type":"event"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"browser/WalletLibrary.sol":"WalletLibrary"},"libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"browser/WalletLibrary.sol":{"keccak256":"0xf72fcdc85e15f93172878ca6a61fb81604d1052e9e724bc3896d65b3b4ab1bb0","urls":["bzzr://009bd59bd78f59804eaffb6111d341caea58888f8e5b5f75aebdf009fc6136c0"]}},"version":1} -``` - -The differences to the originally deployed contract code can be reviewed at: - -* [parity-contracts/0x863df6bfa4#2](https://github.com/parity-contracts/0x863df6bfa4/pull/2): -Remove the `selfdestruct()` -* [parity-contracts/0x863df6bfa4#3](https://github.com/parity-contracts/0x863df6bfa4/pull/3): -Initialize the library owner to `0x0` - -The following sections propose two equivalent specifications, 999a and 999b, -which technically achieve the same results. To implement this proposal only one -of them has to be applied. - -### Direct State Transition via Bytecode (999a) -At `CNSTNTNPL_FORK_BLKNUM`, directly recreate the account -`0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4` with the following parameters: - -* Nonce: `0x1` -* Code: - -``` -0x606060405236156100ef576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063173825d91461016d5780632f54bf6e146101a35780634123cb6b146101f157806352375093146102175780635c52c2f51461023d578063659010e71461024f5780637065cb4814610275578063746c9171146102ab578063797af627146102d1578063b20d30a91461030d578063b61d27f61461032d578063b75c7dc61461039c578063ba51a6df146103c0578063c2cf7326146103e0578063c41a360a1461043b578063f00d4b5d1461049b578063f1736d86146104f0575b61016b5b6000341115610168577fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3334604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b565b005b341561017557fe5b6101a1600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610516565b005b34156101ab57fe5b6101d7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610659565b604051808215151515815260200191505060405180910390f35b34156101f957fe5b610201610691565b6040518082815260200191505060405180910390f35b341561021f57fe5b610227610697565b6040518082815260200191505060405180910390f35b341561024557fe5b61024d61069d565b005b341561025757fe5b61025f6106d7565b6040518082815260200191505060405180910390f35b341561027d57fe5b6102a9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106dd565b005b34156102b357fe5b6102bb610829565b6040518082815260200191505060405180910390f35b34156102d957fe5b6102f360048080356000191690602001909190505061082f565b604051808215151515815260200191505060405180910390f35b341561031557fe5b61032b6004808035906020019091905050610dcc565b005b341561033557fe5b61037e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919080359060200190820180359060200191909192905050610e06565b60405180826000191660001916815260200191505060405180910390f35b34156103a457fe5b6103be60048080356000191690602001909190505061127d565b005b34156103c857fe5b6103de6004808035906020019091905050611392565b005b34156103e857fe5b61042160048080356000191690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061141a565b604051808215151515815260200191505060405180910390f35b341561044357fe5b610459600480803590602001909190505061149c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a357fe5b6104ee600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114bf565b005b34156104f857fe5b610500611672565b6040518082815260200191505060405180910390f35b600060003660405180838380828437820191505092505050604051809103902061053f81611678565b156106535761010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561057f57610652565b600160015403600054111561059357610652565b6000600583610100811015156105a557fe5b0160005b5081905550600061010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506105e6611890565b6105ee6119d0565b7f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da83604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b505050565b6000600061010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541190505b919050565b60015481565b60045481565b6000366040518083838082843782019150509250505060405180910390206106c481611678565b156106d35760006003819055505b5b5b50565b60035481565b60003660405180838380828437820191505092505050604051809103902061070481611678565b156108245761071282610659565b1561071c57610823565b610724611890565b60fa600154101515610739576107386119d0565b5b60fa60015410151561074a57610823565b6001600081548092919060010191905055508173ffffffffffffffffffffffffffffffffffffffff1660056001546101008110151561078557fe5b0160005b508190555060015461010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c382604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b5050565b60005481565b600060008261083d81611678565b15610dc45760006101086000866000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415806108c757506000610108600086600019166000191681526020019081526020016000206001015414155b80610906575060006101086000866000191660001916815260200190815260200160002060020180546001816001161561010002031660029004905014155b15610dc25760006101086000866000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a5057610a496101086000866000191660001916815260200190815260200160002060010154610108600087600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a3f5780601f10610a1457610100808354040283529160200191610a3f565b820191906000526020600020905b815481529060010190602001808311610a2257829003601f168201915b5050505050611b37565b9150610b71565b6101086000856000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166101086000866000191660001916815260200190815260200160002060010154610108600087600019166000191681526020019081526020016000206002016040518082805460018160011615610100020316600290048015610b4a5780601f10610b1f57610100808354040283529160200191610b4a565b820191906000526020600020905b815481529060010190602001808311610b2d57829003601f168201915b505091505060006040518083038185876185025a03f1925050501515610b705760006000fd5b5b7fe3a3a4111a84df27d76b68dc721e65c7711605ea5eee4afd3a9c58195217365c338561010860008860001916600019168152602001908152602001600020600101546101086000896000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661010860008a6000191660001916815260200190815260200160002060020187604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186600019166000191681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610d475780601f10610d1c57610100808354040283529160200191610d47565b820191906000526020600020905b815481529060010190602001808311610d2a57829003601f168201915b505097505050505050505060405180910390a16101086000856000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000610db79190611be6565b505060019250610dc3565b5b5b5b5050919050565b600036604051808383808284378201915050925050506040518091039020610df381611678565b15610e0157816002819055505b5b5b5050565b60006000610e1333610659565b1561127357600084849050148015610e305750610e2f85611b51565b5b80610e3d57506001600054145b15610fed5760008673ffffffffffffffffffffffffffffffffffffffff161415610ea457610e9d8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611b37565b9050610ef3565b8573ffffffffffffffffffffffffffffffffffffffff168585856040518083838082843782019150509250505060006040518083038185876185025a03f1925050501515610ef25760006000fd5b5b7f9738cd1a8777c86b011f7b01d87d484217dc6ab5154a9d41eda5d14af8caf292338688878786604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437820191505097505050505050505060405180910390a1611271565b6000364360405180848480828437820191505082815260200193505050506040518091039020915060006101086000846000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611099575060006101086000846000191660001916815260200190815260200160002060010154145b80156110d85750600061010860008460001916600019168152602001908152602001600020600201805460018160011615610100020316600290049050145b1561118f57856101086000846000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550846101086000846000191660001916815260200190815260200160002060010181905550838361010860008560001916600019168152602001908152602001600020600201919061118d929190611c2e565b505b6111988261082f565b1515611270577f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328233878988886040518087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b5b5b5b5b50949350505050565b60006000600061010560003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925060008314156112be5761138c565b8260020a9150610106600085600019166000191681526020019081526020016000209050600082826001015416111561138b5780600001600081548092919060010191905055508181600101600082825403925050819055507fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b3385604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182600019166000191681526020019250505060405180910390a15b5b50505050565b6000366040518083838082843782019150509250505060405180910390206113b981611678565b15611415576001548211156113cd57611414565b816000819055506113dc611890565b7facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da826040518082815260200191505060405180910390a15b5b5b5050565b600060006000600061010660008760001916600019168152602001908152602001600020925061010560008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561147f5760009350611493565b8160020a9050600081846001015416141593505b50505092915050565b6000600560018301610100811015156114b157fe5b0160005b505490505b919050565b60006000366040518083838082843782019150509250505060405180910390206114e881611678565b1561166b576114f683610659565b156115005761166a565b61010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561153b5761166a565b611543611890565b8273ffffffffffffffffffffffffffffffffffffffff166005836101008110151561156a57fe5b0160005b5081905550600061010560008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508161010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c8484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b5b5b50505050565b60025481565b600060006000600061010560003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925060008314156116bb57611888565b6101066000866000191660001916815260200190815260200160002091506000826000015414156117455760005482600001819055506000826001018190555061010780548091906001016117109190611cae565b826002018190555084610107836002015481548110151561172d57fe5b906000526020600020900160005b5081600019169055505b8260020a90506000818360010154161415611887577fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda3386604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182600019166000191681526020019250505060405180910390a16001826000015411151561185e57610107610106600087600019166000191681526020019081526020016000206002015481548110151561180a57fe5b906000526020600020900160005b5060009055610106600086600019166000191681526020019081526020016000206000600082016000905560018201600090556002820160009055505060019350611888565b8160000160008154809291906001900391905055508082600101600082825417925050819055505b5b5b505050919050565b60006000610107805490509150600090505b818110156119bc576101086000610107838154811015156118bf57fe5b906000526020600020900160005b50546000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160006119269190611be6565b505060006001026101078281548110151561193d57fe5b906000526020600020900160005b5054600019161415156119b05761010660006101078381548110151561196d57fe5b906000526020600020900160005b505460001916600019168152602001908152602001600020600060008201600090556001820160009055600282016000905550505b5b8060010190506118a2565b61010760006119cb9190611cda565b5b5050565b6000600190505b600154811015611b33575b60015481108015611a095750600060058261010081101515611a0057fe5b0160005b505414155b15611a1b5780806001019150506119e2565b5b6001600154118015611a4557506000600560015461010081101515611a3d57fe5b0160005b5054145b15611a625760016000815480929190600190039190505550611a1c565b60015481108015611a8b57506000600560015461010081101515611a8257fe5b0160005b505414155b8015611aac5750600060058261010081101515611aa457fe5b0160005b5054145b15611b2e57600560015461010081101515611ac357fe5b0160005b505460058261010081101515611ad957fe5b0160005b508190555080610105600060058461010081101515611af857fe5b0160005b50548152602001908152602001600020819055506000600560015461010081101515611b2457fe5b0160005b50819055505b6119d7565b5b50565b600081516020830184f09050803b15610000575b92915050565b6000611b5c33610659565b15611bc957600454611b6c611bcf565b1115611b89576000600381905550611b82611bcf565b6004819055505b600354826003540110158015611ba55750600254826003540111155b15611bc3578160036000828254019250508190555060019050611bc8565b600090505b5b5b919050565b60006201518042811515611bdf57fe5b0490505b90565b50805460018160011615610100020316600290046000825580601f10611c0c5750611c2b565b601f016020900490600052602060002090810190611c2a9190611cfc565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611c6f57803560ff1916838001178555611c9d565b82800160010185558215611c9d579182015b82811115611c9c578235825591602001919060010190611c81565b5b509050611caa9190611cfc565b5090565b815481835581811511611cd557818360005260206000209182019101611cd49190611d21565b5b505050565b5080546000825590600052602060002090810190611cf89190611d21565b5b50565b611d1e91905b80821115611d1a576000816000905550600101611d02565b5090565b90565b611d4391905b80821115611d3f576000816000905550600101611d27565b5090565b90565b60006001541115611d575760006000fd5b611d6081611d71565b611d6a8383611d9c565b5b5b505050565b60006001541115611d825760006000fd5b80600281905550611d91611bcf565b6004819055505b5b50565b600060006001541115611daf5760006000fd5b600082111515611dbf5760006000fd5b81835110151515611dd05760006000fd5b8251600181905550600090505b8251811015611e85578281815181101515611df457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1660058260010161010081101515611e2757fe5b0160005b50819055508060010161010560008584815181101515611e4757fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b806001019050611ddd565b816000819055505b5b5050505600a165627a7a7230582084feb3505964efa62a6ffa78d913a175fe7bc168dd50067d25b1d5ddb6d10a1e0029 -``` - -* Storage: - * `0x0000000000000000000000000000000000000000000000000000000000000000`: -`0x0000000000000000000000000000000000000000000000000000000000000001` - * `0x0000000000000000000000000000000000000000000000000000000000000001`: -`0x0000000000000000000000000000000000000000000000000000000000000001` - * `0x0000000000000000000000000000000000000000000000000000000000000004`: -`0x00000000000000000000000000000000000000000000000000000000000044e1` - * `0xa5baec7d73105a3c7298203bb205bbc41b63fa384ae73a6016b890a7ca29ae2d`: -`0x0000000000000000000000000000000000000000000000000000000000000001` - -The balance of the account shall be left unchanged. - -### Alternate Specification via Codehash (999b) -At `CNSTNTNPL_FORK_BLKNUM`, directly recreate the account -`0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4` with the following parameters: - -* Nonce: `0x1` -* Storage: - * `0x0000000000000000000000000000000000000000000000000000000000000000`: -`0x0000000000000000000000000000000000000000000000000000000000000001` - * `0x0000000000000000000000000000000000000000000000000000000000000001`: -`0x0000000000000000000000000000000000000000000000000000000000000001` - * `0x0000000000000000000000000000000000000000000000000000000000000004`: -`0x00000000000000000000000000000000000000000000000000000000000044e1` - * `0xa5baec7d73105a3c7298203bb205bbc41b63fa384ae73a6016b890a7ca29ae2d`: -`0x0000000000000000000000000000000000000000000000000000000000000001` - -In addition, the codehash at that address shall be replaced by the codehash at -address `0x21C9E434c669c4d73f55215A6F2130A185E127AC`. The codehash is -`0x6209d55547da7b035d54ef8d73275e863d3072b91da6ace1614fa6381f4e2c09`. The -balance of the account shall be left unchanged. - -## Rationale -The design decision to restore the `WalletLibrary` contract code in a single -state transition was made after lengthy discussions of -[alternate proposals](https://gist.github.com/5chdn/a9bb8617cc8523a030126a3d1c60baf3) -that explored different ways to improve the Ethereum protocol to allow contract -revivals by adding different built-in contracts. It was eventually concluded -that all of these proposals changing the EVM semantics around self-destructed -contracts were introducing unwanted side-effects and -[potential risks](https://medium.com/@weka/on-paritys-proposed-changes-to-selfdestruct-behaviour-c3f0e5bc0f49) -to the existing smart-contract ecosystem on the Ethereum platform. - -The total supply of Ether is neither changed nor does this proposal require the -transfer of any tokens or assets including Ether. It is assumed that this change -is aligned with the interests both of (A) Parity Technologies that intended to -provide a smart-contracts library for multi-signature wallets to last forever -for its users and (B) the users of the multi-signature wallets that meant to -safely store their assets in a contract accessible any time they desire. Lastly, -the client-side implementation cost of this proposal is estimated to be low. A -sample implementation will be attached and linked in the following sections. - -## Backwards Compatibility -This proposal introduces backwards incompatibilities in the state of the -contract at `0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4`. The Ethereum protocol -does not allow the restoration of self-destructed contracts. To implement this -on the Ethereum blockchain, it is recommended to add the necessary state -transition in a future hard-fork at a well-defined block number, e.g., -`CNSTNTNPL_FORK_BLKNUM` for the Constantinople milestone which is supposed to be -the next scheduled hard-fork on the Ethereum road-map. - -## Implementation -A proof-of-concept implementation is available for the Parity client on branch -[`a5-eip999-poc`](https://github.com/paritytech/parity/compare/a5-eip999-poc) -([#8406](https://github.com/paritytech/parity/pull/8406)). A sample chain -configuration for Parity can be found at the same branch in -[`multisig_test.json`](https://github.com/paritytech/parity/blob/891e633021eec78dd62104bf5a99af50f66b06c7/ethcore/res/ethereum/multisig_test.json#L38-L51) -describing the state change as specified above. - -## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md).