{"sources":{".sol":{"content":"pragma solidity ^0.4.21;\r\n\r\n/** @title  A contract for generating unique identifiers\r\n  *\r\n  * @notice  A contract that provides a identifier generation scheme,\r\n  * guaranteeing uniqueness across all contracts that inherit from it,\r\n  * as well as unpredictability of future identifiers.\r\n  *\r\n  * @dev  This contract is intended to be inherited by any contract that\r\n  * implements the callback software pattern for cooperative custodianship.\r\n  *\r\n  * @author  Gemini Trust Company, LLC\r\n  */\r\ncontract LockRequestable {\r\n\r\n    // MEMBERS\r\n    /// @notice  the count of all invocations of `generateLockId`.\r\n    uint256 public lockRequestCount;\r\n\r\n    // CONSTRUCTOR\r\n    function LockRequestable() public {\r\n        lockRequestCount = 0;\r\n    }\r\n\r\n    // FUNCTIONS\r\n    /** @notice  Returns a fresh unique identifier.\r\n      *\r\n      * @dev the generation scheme uses three components.\r\n      * First, the blockhash of the previous block.\r\n      * Second, the deployed address.\r\n      * Third, the next value of the counter.\r\n      * This ensure that identifiers are unique across all contracts\r\n      * following this scheme, and that future identifiers are\r\n      * unpredictable.\r\n      *\r\n      * @return a 32-byte unique identifier.\r\n      */\r\n    function generateLockId() internal returns (bytes32 lockId) {\r\n        return keccak256(block.blockhash(block.number - 1), address(this), ++lockRequestCount);\r\n    }\r\n}\r\n\r\n\r\n/** @title  A contract to inherit upgradeable custodianship.\r\n  *\r\n  * @notice  A contract that provides re-usable code for upgradeable\r\n  * custodianship. That custodian may be an account or another contract.\r\n  *\r\n  * @dev  This contract is intended to be inherited by any contract\r\n  * requiring a custodian to control some aspect of its functionality.\r\n  * This contract provides the mechanism for that custodianship to be\r\n  * passed from one custodian to the next.\r\n  *\r\n  * @author  Gemini Trust Company, LLC\r\n  */\r\ncontract CustodianUpgradeable is LockRequestable {\r\n\r\n    // TYPES\r\n    /// @dev  The struct type for pending custodian changes.\r\n    struct CustodianChangeRequest {\r\n        address proposedNew;\r\n    }\r\n\r\n    // MEMBERS\r\n    /// @dev  The address of the account or contract that acts as the custodian.\r\n    address public custodian;\r\n\r\n    /// @dev  The map of lock ids to pending custodian changes.\r\n    mapping (bytes32 => CustodianChangeRequest) public custodianChangeReqs;\r\n\r\n    // CONSTRUCTOR\r\n    function CustodianUpgradeable(\r\n        address _custodian\r\n    )\r\n      LockRequestable()\r\n      public\r\n    {\r\n        custodian = _custodian;\r\n    }\r\n\r\n    // MODIFIERS\r\n    modifier onlyCustodian {\r\n        require(msg.sender == custodian);\r\n        _;\r\n    }\r\n\r\n    // PUBLIC FUNCTIONS\r\n    // (UPGRADE)\r\n\r\n    /** @notice  Requests a change of the custodian associated with this contract.\r\n      *\r\n      * @dev  Returns a unique lock id associated with the request.\r\n      * Anyone can call this function, but confirming the request is authorized\r\n      * by the custodian.\r\n      *\r\n      * @param  _proposedCustodian  The address of the new custodian.\r\n      * @return  lockId  A unique identifier for this request.\r\n      */\r\n    function requestCustodianChange(address _proposedCustodian) public returns (bytes32 lockId) {\r\n        require(_proposedCustodian != address(0));\r\n\r\n        lockId = generateLockId();\r\n\r\n        custodianChangeReqs[lockId] = CustodianChangeRequest({\r\n            proposedNew: _proposedCustodian\r\n        });\r\n\r\n        emit CustodianChangeRequested(lockId, msg.sender, _proposedCustodian);\r\n    }\r\n\r\n    /** @notice  Confirms a pending change of the custodian associated with this contract.\r\n      *\r\n      * @dev  When called by the current custodian with a lock id associated with a\r\n      * pending custodian change, the `address custodian` member will be updated with the\r\n      * requested address.\r\n      *\r\n      * @param  _lockId  The identifier of a pending change request.\r\n      */\r\n    function confirmCustodianChange(bytes32 _lockId) public onlyCustodian {\r\n        custodian = getCustodianChangeReq(_lockId);\r\n\r\n        delete custodianChangeReqs[_lockId];\r\n\r\n        emit CustodianChangeConfirmed(_lockId, custodian);\r\n    }\r\n\r\n    // PRIVATE FUNCTIONS\r\n    function getCustodianChangeReq(bytes32 _lockId) private view returns (address _proposedNew) {\r\n        CustodianChangeRequest storage changeRequest = custodianChangeReqs[_lockId];\r\n\r\n        // reject ‘null’ results from the map lookup\r\n        // this can only be the case if an unknown `_lockId` is received\r\n        require(changeRequest.proposedNew != 0);\r\n\r\n        return changeRequest.proposedNew;\r\n    }\r\n\r\n    /// @dev  Emitted by successful `requestCustodianChange` calls.\r\n    event CustodianChangeRequested(\r\n        bytes32 _lockId,\r\n        address _msgSender,\r\n        address _proposedCustodian\r\n    );\r\n\r\n    /// @dev Emitted by successful `confirmCustodianChange` calls.\r\n    event CustodianChangeConfirmed(bytes32 _lockId, address _newCustodian);\r\n}\r\n\r\n\r\n/** @title  A contract to inherit upgradeable token implementations.\r\n  *\r\n  * @notice  A contract that provides re-usable code for upgradeable\r\n  * token implementations. It itself inherits from `CustodianUpgradable`\r\n  * as the upgrade process is controlled by the custodian.\r\n  *\r\n  * @dev  This contract is intended to be inherited by any contract\r\n  * requiring a reference to the active token implementation, either\r\n  * to delegate calls to it, or authorize calls from it. This contract\r\n  * provides the mechanism for that implementation to be be replaced,\r\n  * which constitutes an implementation upgrade.\r\n  *\r\n  * @author Gemini Trust Company, LLC\r\n  */\r\ncontract ERC20ImplUpgradeable is CustodianUpgradeable  {\r\n\r\n    // TYPES\r\n    /// @dev  The struct type for pending implementation changes.\r\n    struct ImplChangeRequest {\r\n        address proposedNew;\r\n    }\r\n\r\n    // MEMBERS\r\n    // @dev  The reference to the active token implementation.\r\n    ERC20Impl public erc20Impl;\r\n\r\n    /// @dev  The map of lock ids to pending implementation changes.\r\n    mapping (bytes32 => ImplChangeRequest) public implChangeReqs;\r\n\r\n    // CONSTRUCTOR\r\n    function ERC20ImplUpgradeable(address _custodian) CustodianUpgradeable(_custodian) public {\r\n        erc20Impl = ERC20Impl(0x0);\r\n    }\r\n\r\n    // MODIFIERS\r\n    modifier onlyImpl {\r\n        require(msg.sender == address(erc20Impl));\r\n        _;\r\n    }\r\n\r\n    // PUBLIC FUNCTIONS\r\n    // (UPGRADE)\r\n    /** @notice  Requests a change of the active implementation associated\r\n      * with this contract.\r\n      *\r\n      * @dev  Returns a unique lock id associated with the request.\r\n      * Anyone can call this function, but confirming the request is authorized\r\n      * by the custodian.\r\n      *\r\n      * @param  _proposedImpl  The address of the new active implementation.\r\n      * @return  lockId  A unique identifier for this request.\r\n      */\r\n    function requestImplChange(address _proposedImpl) public returns (bytes32 lockId) {\r\n        require(_proposedImpl != address(0));\r\n\r\n        lockId = generateLockId();\r\n\r\n        implChangeReqs[lockId] = ImplChangeRequest({\r\n            proposedNew: _proposedImpl\r\n        });\r\n\r\n        emit ImplChangeRequested(lockId, msg.sender, _proposedImpl);\r\n    }\r\n\r\n    /** @notice  Confirms a pending change of the active implementation\r\n      * associated with this contract.\r\n      *\r\n      * @dev  When called by the custodian with a lock id associated with a\r\n      * pending change, the `ERC20Impl erc20Impl` member will be updated\r\n      * with the requested address.\r\n      *\r\n      * @param  _lockId  The identifier of a pending change request.\r\n      */\r\n    function confirmImplChange(bytes32 _lockId) public onlyCustodian {\r\n        erc20Impl = getImplChangeReq(_lockId);\r\n\r\n        delete implChangeReqs[_lockId];\r\n\r\n        emit ImplChangeConfirmed(_lockId, address(erc20Impl));\r\n    }\r\n\r\n    // PRIVATE FUNCTIONS\r\n    function getImplChangeReq(bytes32 _lockId) private view returns (ERC20Impl _proposedNew) {\r\n        ImplChangeRequest storage changeRequest = implChangeReqs[_lockId];\r\n\r\n        // reject ‘null’ results from the map lookup\r\n        // this can only be the case if an unknown `_lockId` is received\r\n        require(changeRequest.proposedNew != address(0));\r\n\r\n        return ERC20Impl(changeRequest.proposedNew);\r\n    }\r\n\r\n    /// @dev  Emitted by successful `requestImplChange` calls.\r\n    event ImplChangeRequested(\r\n        bytes32 _lockId,\r\n        address _msgSender,\r\n        address _proposedImpl\r\n    );\r\n\r\n    /// @dev Emitted by successful `confirmImplChange` calls.\r\n    event ImplChangeConfirmed(bytes32 _lockId, address _newImpl);\r\n}\r\n\r\n\r\ncontract ERC20Interface {\r\n  // METHODS\r\n\r\n  // NOTE:\r\n  //   public getter functions are not currently recognised as an\r\n  //   implementation of the matching abstract function by the compiler.\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#name\r\n  // function name() public view returns (string);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#symbol\r\n  // function symbol() public view returns (string);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#totalsupply\r\n  // function decimals() public view returns (uint8);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#totalsupply\r\n  function totalSupply() public view returns (uint256);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#balanceof\r\n  function balanceOf(address _owner) public view returns (uint256 balance);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transfer\r\n  function transfer(address _to, uint256 _value) public returns (bool success);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transferfrom\r\n  function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#approve\r\n  function approve(address _spender, uint256 _value) public returns (bool success);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#allowance\r\n  function allowance(address _owner, address _spender) public view returns (uint256 remaining);\r\n\r\n  // EVENTS\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transfer-1\r\n  event Transfer(address indexed _from, address indexed _to, uint256 _value);\r\n\r\n  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#approval\r\n  event Approval(address indexed _owner, address indexed _spender, uint256 _value);\r\n}\r\n\r\n\r\n/** @title  Public interface to ERC20 compliant token.\r\n  *\r\n  * @notice  This contract is a permanent entry point to an ERC20 compliant\r\n  * system of contracts.\r\n  *\r\n  * @dev  This contract contains no business logic and instead\r\n  * delegates to an instance of ERC20Impl. This contract also has no storage\r\n  * that constitutes the operational state of the token. This contract is\r\n  * upgradeable in the sense that the `custodian` can update the\r\n  * `erc20Impl` address, thus redirecting the delegation of business logic.\r\n  * The `custodian` is also authorized to pass custodianship.\r\n  *\r\n  * @author  Gemini Trust Company, LLC\r\n  */\r\ncontract ERC20Proxy is ERC20Interface, ERC20ImplUpgradeable {\r\n\r\n    // MEMBERS\r\n    /// @notice  Returns the name of the token.\r\n    string public name;\r\n\r\n    /// @notice  Returns the symbol of the token.\r\n    string public symbol;\r\n\r\n    /// @notice  Returns the number of decimals the token uses.\r\n    uint8 public decimals;\r\n\r\n    // CONSTRUCTOR\r\n    function ERC20Proxy(\r\n        string _name,\r\n        string _symbol,\r\n        uint8 _decimals,\r\n        address _custodian\r\n    )\r\n        ERC20ImplUpgradeable(_custodian)\r\n        public\r\n    {\r\n        name = _name;\r\n        symbol = _symbol;\r\n        decimals = _decimals;\r\n    }\r\n\r\n    // PUBLIC FUNCTIONS\r\n    // (ERC20Interface)\r\n    /** @notice  Returns the total token supply.\r\n      *\r\n      * @return  the total token supply.\r\n      */\r\n    function totalSupply() public view returns (uint256) {\r\n        return erc20Impl.totalSupply();\r\n    }\r\n\r\n    /** @notice  Returns the account balance of another account with address\r\n      * `_owner`.\r\n      *\r\n      * @return  balance  the balance of account with address `_owner`.\r\n      */\r\n    function balanceOf(address _owner) public view returns (uint256 balance) {\r\n        return erc20Impl.balanceOf(_owner);\r\n    }\r\n\r\n    /** @dev Internal use only.\r\n      */\r\n    function emitTransfer(address _from, address _to, uint256 _value) public onlyImpl {\r\n        emit Transfer(_from, _to, _value);\r\n    }\r\n\r\n    /** @notice  Transfers `_value` amount of tokens to address `_to`.\r\n      *\r\n      * @dev Will fire the `Transfer` event. Will revert if the `_from`\r\n      * account balance does not have enough tokens to spend.\r\n      *\r\n      * @return  success  true if transfer completes.\r\n      */\r\n    function transfer(address _to, uint256 _value) public returns (bool success) {\r\n        return erc20Impl.transferWithSender(msg.sender, _to, _value);\r\n    }\r\n\r\n    /** @notice  Transfers `_value` amount of tokens from address `_from`\r\n      * to address `_to`.\r\n      *\r\n      * @dev  Will fire the `Transfer` event. Will revert unless the `_from`\r\n      * account has deliberately authorized the sender of the message\r\n      * via some mechanism.\r\n      *\r\n      * @return  success  true if transfer completes.\r\n      */\r\n    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {\r\n        return erc20Impl.transferFromWithSender(msg.sender, _from, _to, _value);\r\n    }\r\n\r\n    /** @dev Internal use only.\r\n      */\r\n    function emitApproval(address _owner, address _spender, uint256 _value) public onlyImpl {\r\n        emit Approval(_owner, _spender, _value);\r\n    }\r\n\r\n    /** @notice  Allows `_spender` to withdraw from your account multiple times,\r\n      * up to the `_value` amount. If this function is called again it\r\n      * overwrites the current allowance with _value.\r\n      *\r\n      * @dev  Will fire the `Approval` event.\r\n      *\r\n      * @return  success  true if approval completes.\r\n      */\r\n    function approve(address _spender, uint256 _value) public returns (bool success) {\r\n        return erc20Impl.approveWithSender(msg.sender, _spender, _value);\r\n    }\r\n\r\n    /** @notice Increases the amount `_spender` is allowed to withdraw from\r\n      * your account.\r\n      * This function is implemented to avoid the race condition in standard\r\n      * ERC20 contracts surrounding the `approve` method.\r\n      *\r\n      * @dev  Will fire the `Approval` event. This function should be used instead of\r\n      * `approve`.\r\n      *\r\n      * @return  success  true if approval completes.\r\n      */\r\n    function increaseApproval(address _spender, uint256 _addedValue) public returns (bool success) {\r\n        return erc20Impl.increaseApprovalWithSender(msg.sender, _spender, _addedValue);\r\n    }\r\n\r\n    /** @notice  Decreases the amount `_spender` is allowed to withdraw from\r\n      * your account. This function is implemented to avoid the race\r\n      * condition in standard ERC20 contracts surrounding the `approve` method.\r\n      *\r\n      * @dev  Will fire the `Approval` event. This function should be used\r\n      * instead of `approve`.\r\n      *\r\n      * @return  success  true if approval completes.\r\n      */\r\n    function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool success) {\r\n        return erc20Impl.decreaseApprovalWithSender(msg.sender, _spender, _subtractedValue);\r\n    }\r\n\r\n    /** @notice  Returns how much `_spender` is currently allowed to spend from\r\n      * `_owner`'s balance.\r\n      *\r\n      * @return  remaining  the remaining allowance.\r\n      */\r\n    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {\r\n        return erc20Impl.allowance(_owner, _spender);\r\n    }\r\n}\r\n\r\n\r\n/** @title  ERC20 compliant token intermediary contract holding core logic.\r\n  *\r\n  * @notice  This contract serves as an intermediary between the exposed ERC20\r\n  * interface in ERC20Proxy and the store of balances in ERC20Store. This\r\n  * contract contains core logic that the proxy can delegate to\r\n  * and that the store is called by.\r\n  *\r\n  * @dev  This contract contains the core logic to implement the\r\n  * ERC20 specification as well as several extensions.\r\n  * 1. Changes to the token supply.\r\n  * 2. Batched transfers.\r\n  * 3. Relative changes to spending approvals.\r\n  * 4. Delegated transfer control ('sweeping').\r\n  *\r\n  * @author  Gemini Trust Company, LLC\r\n  */\r\ncontract ERC20Impl is CustodianUpgradeable {\r\n\r\n    // TYPES\r\n    /// @dev  The struct type for pending increases to the token supply (print).\r\n    struct PendingPrint {\r\n        address receiver;\r\n        uint256 value;\r\n    }\r\n\r\n    // MEMBERS\r\n    /// @dev  The reference to the proxy.\r\n    ERC20Proxy public erc20Proxy;\r\n\r\n    /// @dev  The reference to the store.\r\n    ERC20Store public erc20Store;\r\n\r\n    /// @dev  The sole authorized caller of delegated transfer control ('sweeping').\r\n    address public sweeper;\r\n\r\n    /** @dev  The static message to be signed by an external account that\r\n      * signifies their permission to forward their balance to any arbitrary\r\n      * address. This is used to consolidate the control of all accounts\r\n      * backed by a shared keychain into the control of a single key.\r\n      * Initialized as the concatenation of the address of this contract\r\n      * and the word \"sweep\". This concatenation is done to prevent a replay\r\n      * attack in a subsequent contract, where the sweep message could\r\n      * potentially be replayed to re-enable sweeping ability.\r\n      */\r\n    bytes32 public sweepMsg;\r\n\r\n    /** @dev  The mapping that stores whether the address in question has\r\n      * enabled sweeping its contents to another account or not.\r\n      * If an address maps to \"true\", it has already enabled sweeping,\r\n      * and thus does not need to re-sign the `sweepMsg` to enact the sweep.\r\n      */\r\n    mapping (address => bool) public sweptSet;\r\n\r\n    /// @dev  The map of lock ids to pending token increases.\r\n    mapping (bytes32 => PendingPrint) public pendingPrintMap;\r\n\r\n    // CONSTRUCTOR\r\n    function ERC20Impl(\r\n          address _erc20Proxy,\r\n          address _erc20Store,\r\n          address _custodian,\r\n          address _sweeper\r\n    )\r\n        CustodianUpgradeable(_custodian)\r\n        public\r\n    {\r\n        require(_sweeper != 0);\r\n        erc20Proxy = ERC20Proxy(_erc20Proxy);\r\n        erc20Store = ERC20Store(_erc20Store);\r\n\r\n        sweeper = _sweeper;\r\n        sweepMsg = keccak256(address(this), \"sweep\");\r\n    }\r\n\r\n    // MODIFIERS\r\n    modifier onlyProxy {\r\n        require(msg.sender == address(erc20Proxy));\r\n        _;\r\n    }\r\n    modifier onlySweeper {\r\n        require(msg.sender == sweeper);\r\n        _;\r\n    }\r\n\r\n\r\n    /** @notice  Core logic of the ERC20 `approve` function.\r\n      *\r\n      * @dev  This function can only be called by the referenced proxy,\r\n      * which has an `approve` function.\r\n      * Every argument passed to that function as well as the original\r\n      * `msg.sender` gets passed to this function.\r\n      * NOTE: approvals for the zero address (unspendable) are disallowed.\r\n      *\r\n      * @param  _sender  The address initiating the approval in proxy.\r\n      */\r\n    function approveWithSender(\r\n        address _sender,\r\n        address _spender,\r\n        uint256 _value\r\n    )\r\n        public\r\n        onlyProxy\r\n        returns (bool success)\r\n    {\r\n        require(_spender != address(0)); // disallow unspendable approvals\r\n        erc20Store.setAllowance(_sender, _spender, _value);\r\n        erc20Proxy.emitApproval(_sender, _spender, _value);\r\n        return true;\r\n    }\r\n\r\n    /** @notice  Core logic of the `increaseApproval` function.\r\n      *\r\n      * @dev  This function can only be called by the referenced proxy,\r\n      * which has an `increaseApproval` function.\r\n      * Every argument passed to that function as well as the original\r\n      * `msg.sender` gets passed to this function.\r\n      * NOTE: approvals for the zero address (unspendable) are disallowed.\r\n      *\r\n      * @param  _sender  The address initiating the approval.\r\n      */\r\n    function increaseApprovalWithSender(\r\n        address _sender,\r\n        address _spender,\r\n        uint256 _addedValue\r\n    )\r\n        public\r\n        onlyProxy\r\n        returns (bool success)\r\n    {\r\n        require(_spender != address(0)); // disallow unspendable approvals\r\n        uint256 currentAllowance = erc20Store.allowed(_sender, _spender);\r\n        uint256 newAllowance = currentAllowance + _addedValue;\r\n\r\n        require(newAllowance >= currentAllowance);\r\n\r\n        erc20Store.setAllowance(_sender, _spender, newAllowance);\r\n        erc20Proxy.emitApproval(_sender, _spender, newAllowance);\r\n        return true;\r\n    }\r\n\r\n    /** @notice  Core logic of the `decreaseApproval` function.\r\n      *\r\n      * @dev  This function can only be called by the referenced proxy,\r\n      * which has a `decreaseApproval` function.\r\n      * Every argument passed to that function as well as the original\r\n      * `msg.sender` gets passed to this function.\r\n      * NOTE: approvals for the zero address (unspendable) are disallowed.\r\n      *\r\n      * @param  _sender  The address initiating the approval.\r\n      */\r\n    function decreaseApprovalWithSender(\r\n        address _sender,\r\n        address _spender,\r\n        uint256 _subtractedValue\r\n    )\r\n        public\r\n        onlyProxy\r\n        returns (bool success)\r\n    {\r\n        require(_spender != address(0)); // disallow unspendable approvals\r\n        uint256 currentAllowance = erc20Store.allowed(_sender, _spender);\r\n        uint256 newAllowance = currentAllowance - _subtractedValue;\r\n\r\n        require(newAllowance <= currentAllowance);\r\n\r\n        erc20Store.setAllowance(_sender, _spender, newAllowance);\r\n        erc20Proxy.emitApproval(_sender, _spender, newAllowance);\r\n        return true;\r\n    }\r\n\r\n    /** @notice  Requests an increase in the token supply, with the newly created\r\n      * tokens to be added to the balance of the specified account.\r\n      *\r\n      * @dev  Returns a unique lock id associated with the request.\r\n      * Anyone can call this function, but confirming the request is authorized\r\n      * by the custodian.\r\n      * NOTE: printing to the zero address is disallowed.\r\n      *\r\n      * @param  _receiver  The receiving address of the print, if confirmed.\r\n      * @param  _value  The number of tokens to add to the total supply and the\r\n      * balance of the receiving address, if confirmed.\r\n      *\r\n      * @return  lockId  A unique identifier for this request.\r\n      */\r\n    function requestPrint(address _receiver, uint256 _value) public returns (bytes32 lockId) {\r\n        require(_receiver != address(0));\r\n\r\n        lockId = generateLockId();\r\n\r\n        pendingPrintMap[lockId] = PendingPrint({\r\n            receiver: _receiver,\r\n            value: _value\r\n        });\r\n\r\n        emit PrintingLocked(lockId, _receiver, _value);\r\n    }\r\n\r\n    /** @notice  Confirms a pending increase in the token supply.\r\n      *\r\n      * @dev  When called by the custodian with a lock id associated with a\r\n      * pending increase, the amount requested to be printed in the print request\r\n      * is printed to the receiving address specified in that same request.\r\n      * NOTE: this function will not execute any print that would overflow the\r\n      * total supply, but it will not revert either.\r\n      *\r\n      * @param  _lockId  The identifier of a pending print request.\r\n      */\r\n    function confirmPrint(bytes32 _lockId) public onlyCustodian {\r\n        PendingPrint storage print = pendingPrintMap[_lockId];\r\n\r\n        // reject ‘null’ results from the map lookup\r\n        // this can only be the case if an unknown `_lockId` is received\r\n        address receiver = print.receiver;\r\n        require (receiver != address(0));\r\n        uint256 value = print.value;\r\n\r\n        delete pendingPrintMap[_lockId];\r\n\r\n        uint256 supply = erc20Store.totalSupply();\r\n        uint256 newSupply = supply + value;\r\n        if (newSupply >= supply) {\r\n          erc20Store.setTotalSupply(newSupply);\r\n          erc20Store.addBalance(receiver, value);\r\n\r\n          emit PrintingConfirmed(_lockId, receiver, value);\r\n          erc20Proxy.emitTransfer(address(0), receiver, value);\r\n        }\r\n    }\r\n\r\n    /** @notice  Burns the specified value from the sender's balance.\r\n      *\r\n      * @dev  Sender's balanced is subtracted by the amount they wish to burn.\r\n      *\r\n      * @param  _value  The amount to burn.\r\n      *\r\n      * @return  success  true if the burn succeeded.\r\n      */\r\n    function burn(uint256 _value) public returns (bool success) {\r\n        uint256 balanceOfSender = erc20Store.balances(msg.sender);\r\n        require(_value <= balanceOfSender);\r\n\r\n        erc20Store.setBalance(msg.sender, balanceOfSender - _value);\r\n        erc20Store.setTotalSupply(erc20Store.totalSupply() - _value);\r\n\r\n        erc20Proxy.emitTransfer(msg.sender, address(0), _value);\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @notice  A function for a sender to issue multiple transfers to multiple\r\n      * different addresses at once. This function is implemented for gas\r\n      * considerations when someone wishes to transfer, as one transaction is\r\n      * cheaper than issuing several distinct individual `transfer` transactions.\r\n      *\r\n      * @dev  By specifying a set of destination addresses and values, the\r\n      * sender can issue one transaction to transfer multiple amounts to\r\n      * distinct addresses, rather than issuing each as a separate\r\n      * transaction. The `_tos` and `_values` arrays must be equal length, and\r\n      * an index in one array corresponds to the same index in the other array\r\n      * (e.g. `_tos[0]` will receive `_values[0]`, `_tos[1]` will receive\r\n      * `_values[1]`, and so on.)\r\n      * NOTE: transfers to the zero address are disallowed.\r\n      *\r\n      * @param  _tos  The destination addresses to receive the transfers.\r\n      * @param  _values  The values for each destination address.\r\n      * @return  success  If transfers succeeded.\r\n      */\r\n    function batchTransfer(address[] _tos, uint256[] _values) public returns (bool success) {\r\n        require(_tos.length == _values.length);\r\n\r\n        uint256 numTransfers = _tos.length;\r\n        uint256 senderBalance = erc20Store.balances(msg.sender);\r\n\r\n        for (uint256 i = 0; i < numTransfers; i++) {\r\n          address to = _tos[i];\r\n          require(to != address(0));\r\n          uint256 v = _values[i];\r\n          require(senderBalance >= v);\r\n\r\n          if (msg.sender != to) {\r\n            senderBalance -= v;\r\n            erc20Store.addBalance(to, v);\r\n          }\r\n          erc20Proxy.emitTransfer(msg.sender, to, v);\r\n        }\r\n\r\n        erc20Store.setBalance(msg.sender, senderBalance);\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @notice  Enables the delegation of transfer control for many\r\n      * accounts to the sweeper account, transferring any balances\r\n      * as well to the given destination.\r\n      *\r\n      * @dev  An account delegates transfer control by signing the\r\n      * value of `sweepMsg`. The sweeper account is the only authorized\r\n      * caller of this function, so it must relay signatures on behalf\r\n      * of accounts that delegate transfer control to it. Enabling\r\n      * delegation is idempotent and permanent. If the account has a\r\n      * balance at the time of enabling delegation, its balance is\r\n      * also transfered to the given destination account `_to`.\r\n      * NOTE: transfers to the zero address are disallowed.\r\n      *\r\n      * @param  _vs  The array of recovery byte components of the ECDSA signatures.\r\n      * @param  _rs  The array of 'R' components of the ECDSA signatures.\r\n      * @param  _ss  The array of 'S' components of the ECDSA signatures.\r\n      * @param  _to  The destination for swept balances.\r\n      */\r\n    function enableSweep(uint8[] _vs, bytes32[] _rs, bytes32[] _ss, address _to) public onlySweeper {\r\n        require(_to != address(0));\r\n        require((_vs.length == _rs.length) && (_vs.length == _ss.length));\r\n\r\n        uint256 numSignatures = _vs.length;\r\n        uint256 sweptBalance = 0;\r\n\r\n        for (uint256 i=0; i<numSignatures; ++i) {\r\n          address from = ecrecover(sweepMsg, _vs[i], _rs[i], _ss[i]);\r\n\r\n          // ecrecover returns 0 on malformed input\r\n          if (from != address(0)) {\r\n            sweptSet[from] = true;\r\n\r\n            uint256 fromBalance = erc20Store.balances(from);\r\n\r\n            if (fromBalance > 0) {\r\n              sweptBalance += fromBalance;\r\n\r\n              erc20Store.setBalance(from, 0);\r\n\r\n              erc20Proxy.emitTransfer(from, _to, fromBalance);\r\n            }\r\n          }\r\n        }\r\n\r\n        if (sweptBalance > 0) {\r\n          erc20Store.addBalance(_to, sweptBalance);\r\n        }\r\n    }\r\n\r\n    /** @notice  For accounts that have delegated, transfer control\r\n      * to the sweeper, this function transfers their balances to the given\r\n      * destination.\r\n      *\r\n      * @dev The sweeper account is the only authorized caller of\r\n      * this function. This function accepts an array of addresses to have their\r\n      * balances transferred for gas efficiency purposes.\r\n      * NOTE: any address for an account that has not been previously enabled\r\n      * will be ignored.\r\n      * NOTE: transfers to the zero address are disallowed.\r\n      *\r\n      * @param  _froms  The addresses to have their balances swept.\r\n      * @param  _to  The destination address of all these transfers.\r\n      */\r\n    function replaySweep(address[] _froms, address _to) public onlySweeper {\r\n        require(_to != address(0));\r\n        uint256 lenFroms = _froms.length;\r\n        uint256 sweptBalance = 0;\r\n\r\n        for (uint256 i=0; i<lenFroms; ++i) {\r\n            address from = _froms[i];\r\n\r\n            if (sweptSet[from]) {\r\n                uint256 fromBalance = erc20Store.balances(from);\r\n\r\n                if (fromBalance > 0) {\r\n                    sweptBalance += fromBalance;\r\n\r\n                    erc20Store.setBalance(from, 0);\r\n\r\n                    erc20Proxy.emitTransfer(from, _to, fromBalance);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (sweptBalance > 0) {\r\n            erc20Store.addBalance(_to, sweptBalance);\r\n        }\r\n    }\r\n\r\n    /** @notice  Core logic of the ERC20 `transferFrom` function.\r\n      *\r\n      * @dev  This function can only be called by the referenced proxy,\r\n      * which has a `transferFrom` function.\r\n      * Every argument passed to that function as well as the original\r\n      * `msg.sender` gets passed to this function.\r\n      * NOTE: transfers to the zero address are disallowed.\r\n      *\r\n      * @param  _sender  The address initiating the transfer in proxy.\r\n      */\r\n    function transferFromWithSender(\r\n        address _sender,\r\n        address _from,\r\n        address _to,\r\n        uint256 _value\r\n    )\r\n        public\r\n        onlyProxy\r\n        returns (bool success)\r\n    {\r\n        require(_to != address(0)); // ensure burn is the cannonical transfer to 0x0\r\n\r\n        uint256 balanceOfFrom = erc20Store.balances(_from);\r\n        require(_value <= balanceOfFrom);\r\n\r\n        uint256 senderAllowance = erc20Store.allowed(_from, _sender);\r\n        require(_value <= senderAllowance);\r\n\r\n        erc20Store.setBalance(_from, balanceOfFrom - _value);\r\n        erc20Store.addBalance(_to, _value);\r\n\r\n        erc20Store.setAllowance(_from, _sender, senderAllowance - _value);\r\n\r\n        erc20Proxy.emitTransfer(_from, _to, _value);\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @notice  Core logic of the ERC20 `transfer` function.\r\n      *\r\n      * @dev  This function can only be called by the referenced proxy,\r\n      * which has a `transfer` function.\r\n      * Every argument passed to that function as well as the original\r\n      * `msg.sender` gets passed to this function.\r\n      * NOTE: transfers to the zero address are disallowed.\r\n      *\r\n      * @param  _sender  The address initiating the transfer in proxy.\r\n      */\r\n    function transferWithSender(\r\n        address _sender,\r\n        address _to,\r\n        uint256 _value\r\n    )\r\n        public\r\n        onlyProxy\r\n        returns (bool success)\r\n    {\r\n        require(_to != address(0)); // ensure burn is the cannonical transfer to 0x0\r\n\r\n        uint256 balanceOfSender = erc20Store.balances(_sender);\r\n        require(_value <= balanceOfSender);\r\n\r\n        erc20Store.setBalance(_sender, balanceOfSender - _value);\r\n        erc20Store.addBalance(_to, _value);\r\n\r\n        erc20Proxy.emitTransfer(_sender, _to, _value);\r\n\r\n        return true;\r\n    }\r\n\r\n    // METHODS (ERC20 sub interface impl.)\r\n    /// @notice  Core logic of the ERC20 `totalSupply` function.\r\n    function totalSupply() public view returns (uint256) {\r\n        return erc20Store.totalSupply();\r\n    }\r\n\r\n    /// @notice  Core logic of the ERC20 `balanceOf` function.\r\n    function balanceOf(address _owner) public view returns (uint256 balance) {\r\n        return erc20Store.balances(_owner);\r\n    }\r\n\r\n    /// @notice  Core logic of the ERC20 `allowance` function.\r\n    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {\r\n        return erc20Store.allowed(_owner, _spender);\r\n    }\r\n\r\n    // EVENTS\r\n    /// @dev  Emitted by successful `requestPrint` calls.\r\n    event PrintingLocked(bytes32 _lockId, address _receiver, uint256 _value);\r\n    /// @dev Emitted by successful `confirmPrint` calls.\r\n    event PrintingConfirmed(bytes32 _lockId, address _receiver, uint256 _value);\r\n}\r\n\r\n\r\n/** @title  ERC20 compliant token balance store.\r\n  *\r\n  * @notice  This contract serves as the store of balances, allowances, and\r\n  * supply for the ERC20 compliant token. No business logic exists here.\r\n  *\r\n  * @dev  This contract contains no business logic and instead\r\n  * is the final destination for any change in balances, allowances, or token\r\n  * supply. This contract is upgradeable in the sense that its custodian can\r\n  * update the `erc20Impl` address, thus redirecting the source of logic that\r\n  * determines how the balances will be updated.\r\n  *\r\n  * @author  Gemini Trust Company, LLC\r\n  */\r\ncontract ERC20Store is ERC20ImplUpgradeable {\r\n\r\n    // MEMBERS\r\n    /// @dev  The total token supply.\r\n    uint256 public totalSupply;\r\n\r\n    /// @dev  The mapping of balances.\r\n    mapping (address => uint256) public balances;\r\n\r\n    /// @dev  The mapping of allowances.\r\n    mapping (address => mapping (address => uint256)) public allowed;\r\n\r\n    // CONSTRUCTOR\r\n    function ERC20Store(address _custodian) ERC20ImplUpgradeable(_custodian) public {\r\n        totalSupply = 0;\r\n    }\r\n\r\n\r\n    // PUBLIC FUNCTIONS\r\n    // (ERC20 Ledger)\r\n\r\n    /** @notice  The function to set the total supply of tokens.\r\n      *\r\n      * @dev  Intended for use by token implementation functions\r\n      * that update the total supply. The only authorized caller\r\n      * is the active implementation.\r\n      *\r\n      * @param _newTotalSupply the value to set as the new total supply\r\n      */\r\n    function setTotalSupply(\r\n        uint256 _newTotalSupply\r\n    )\r\n        public\r\n        onlyImpl\r\n    {\r\n        totalSupply = _newTotalSupply;\r\n    }\r\n\r\n    /** @notice  Sets how much `_owner` allows `_spender` to transfer on behalf\r\n      * of `_owner`.\r\n      *\r\n      * @dev  Intended for use by token implementation functions\r\n      * that update spending allowances. The only authorized caller\r\n      * is the active implementation.\r\n      *\r\n      * @param  _owner  The account that will allow an on-behalf-of spend.\r\n      * @param  _spender  The account that will spend on behalf of the owner.\r\n      * @param  _value  The limit of what can be spent.\r\n      */\r\n    function setAllowance(\r\n        address _owner,\r\n        address _spender,\r\n        uint256 _value\r\n    )\r\n        public\r\n        onlyImpl\r\n    {\r\n        allowed[_owner][_spender] = _value;\r\n    }\r\n\r\n    /** @notice  Sets the balance of `_owner` to `_newBalance`.\r\n      *\r\n      * @dev  Intended for use by token implementation functions\r\n      * that update balances. The only authorized caller\r\n      * is the active implementation.\r\n      *\r\n      * @param  _owner  The account that will hold a new balance.\r\n      * @param  _newBalance  The balance to set.\r\n      */\r\n    function setBalance(\r\n        address _owner,\r\n        uint256 _newBalance\r\n    )\r\n        public\r\n        onlyImpl\r\n    {\r\n        balances[_owner] = _newBalance;\r\n    }\r\n\r\n    /** @notice Adds `_balanceIncrease` to `_owner`'s balance.\r\n      *\r\n      * @dev  Intended for use by token implementation functions\r\n      * that update balances. The only authorized caller\r\n      * is the active implementation.\r\n      * WARNING: the caller is responsible for preventing overflow.\r\n      *\r\n      * @param  _owner  The account that will hold a new balance.\r\n      * @param  _balanceIncrease  The balance to add.\r\n      */\r\n    function addBalance(\r\n        address _owner,\r\n        uint256 _balanceIncrease\r\n    )\r\n        public\r\n        onlyImpl\r\n    {\r\n        balances[_owner] = balances[_owner] + _balanceIncrease;\r\n    }\r\n}"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.4.21+commit.dfe3193c","compilerSettings":{"libraries":{},"optimizer":{"enabled":true}},"name":"ERC20Proxy","fullyQualifiedName":".sol:ERC20Proxy"},"runtimeBytecode":{"onchainBytecode":"0x60606040526004361061010e5763ffffffff60e060020a60003504166306fdde038114610113578063095ea7b31461019d57806315b21082146101d357806318160ddd1461020457806323b872dd1461021757806323de66511461023f578063313ce56714610269578063375b74c3146102925780633a8343ee146102c15780633c389cc4146102d757806348f9e246146102ea5780635687f2b814610309578063661884631461033157806370a08231146103535780638181b0291461037257806395d89b4114610388578063a9059cbb1461039b578063b508069b146103bd578063cb81fecf146103d3578063cf6e4488146103e6578063d73dd623146103fc578063dd62ed3e1461041e575b600080fd5b341561011e57600080fd5b610126610443565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561016257808201518382015260200161014a565b50505050905090810190601f16801561018f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101a857600080fd5b6101bf600160a060020a03600435166024356104e1565b604051901515815260200160405180910390f35b34156101de57600080fd5b6101f2600160a060020a0360043516610564565b60405190815260200160405180910390f35b341561020f57600080fd5b6101f2610629565b341561022257600080fd5b6101bf600160a060020a0360043581169060243516604435610686565b341561024a57600080fd5b610267600160a060020a0360043581169060243516604435610711565b005b341561027457600080fd5b61027c610778565b60405160ff909116815260200160405180910390f35b341561029d57600080fd5b6102a5610781565b604051600160a060020a03909116815260200160405180910390f35b34156102cc57600080fd5b610267600435610790565b34156102e257600080fd5b6102a5610841565b34156102f557600080fd5b6101f2600160a060020a0360043516610850565b341561031457600080fd5b610267600160a060020a0360043581169060243516604435610915565b341561033c57600080fd5b6101bf600160a060020a036004351660243561097c565b341561035e57600080fd5b6101f2600160a060020a03600435166109e2565b341561037d57600080fd5b610267600435610a51565b341561039357600080fd5b610126610b02565b34156103a657600080fd5b6101bf600160a060020a0360043516602435610b6d565b34156103c857600080fd5b6102a5600435610bd3565b34156103de57600080fd5b6101f2610bee565b34156103f157600080fd5b6102a5600435610bf4565b341561040757600080fd5b6101bf600160a060020a0360043516602435610c0f565b341561042957600080fd5b6101f2600160a060020a0360043581169060243516610c75565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b820191906000526020600020905b8154815290600101906020018083116104bc57829003601f168201915b505050505081565b600354600090600160a060020a03166389064fd233858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b5af1151561055457600080fd5b5050506040518051949350505050565b6000600160a060020a038216151561057b57600080fd5b610583610cd0565b905060206040519081016040908152600160a060020a038416825260008381526002602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507fd76fc900a7e1a6fcf11d54b7ba943918df6c53a3128140658c389b3da1e997ba813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b600354600090600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561066b57600080fd5b5af1151561067857600080fd5b505050604051805191505090565b600354600090600160a060020a0316635d5e22cd3386868660405160e060020a63ffffffff8716028152600160a060020a0394851660048201529284166024840152921660448201526064810191909152608401602060405180830381600087803b15156106f357600080fd5b5af1151561070057600080fd5b505050604051805195945050505050565b60035433600160a060020a0390811691161461072c57600080fd5b81600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405190815260200160405180910390a3505050565b60075460ff1681565b600154600160a060020a031681565b60015433600160a060020a039081169116146107ab57600080fd5b6107b481610d1e565b60018054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526002602052604090819020805490921690915590547f9a99272c0f6b7a30ef9e76e684a7cd408bfd4f11a72f36a8e276253c920e442d92849291169051918252600160a060020a031660208201526040908101905180910390a150565b600354600160a060020a031681565b6000600160a060020a038216151561086757600080fd5b61086f610cd0565b905060206040519081016040908152600160a060020a038416825260008381526004602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507f5df12834436b8dc248df3f7f1796a3e39f851d610be49cdcd92514fa821b9f97813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b60035433600160a060020a0390811691161461093057600080fd5b81600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405190815260200160405180910390a3505050565b600354600090600160a060020a03166361e1077d33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a03166370a082318360405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b1515610a3557600080fd5b5af11515610a4257600080fd5b50505060405180519392505050565b60015433600160a060020a03908116911614610a6c57600080fd5b610a7581610d52565b60038054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526004602052604090819020805490921690915590547f9d55b0349a0a4c5b511f72228170bb91d45c9ac78dba8ab5b4175d3ed42f06b392849291169051918252600160a060020a031660208201526040908101905180910390a150565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b600354600090600160a060020a031663dfe0f0ca33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600460205260009081526040902054600160a060020a031681565b60005481565b600260205260009081526040902054600160a060020a031681565b600354600090600160a060020a0316632e0179b533858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a031663dd62ed3e848460405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561054757600080fd5b60008054600101808255600019430140903090604051928352600160a060020a03919091166c0100000000000000000000000002602083015260348201526054016040518091039020905090565b60008181526002602052604081208054600160a060020a03161515610d4257600080fd5b54600160a060020a031692915050565b60008181526004602052604081208054600160a060020a03161515610d4257600080fd00a165627a7a72305820e9510794af44fba3b1d3c8d2d27f071e428847cc4b56c82a806ad15368cfc00b0029","recompiledBytecode":"0x60606040526004361061010e5763ffffffff60e060020a60003504166306fdde038114610113578063095ea7b31461019d57806315b21082146101d357806318160ddd1461020457806323b872dd1461021757806323de66511461023f578063313ce56714610269578063375b74c3146102925780633a8343ee146102c15780633c389cc4146102d757806348f9e246146102ea5780635687f2b814610309578063661884631461033157806370a08231146103535780638181b0291461037257806395d89b4114610388578063a9059cbb1461039b578063b508069b146103bd578063cb81fecf146103d3578063cf6e4488146103e6578063d73dd623146103fc578063dd62ed3e1461041e575b600080fd5b341561011e57600080fd5b610126610443565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561016257808201518382015260200161014a565b50505050905090810190601f16801561018f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101a857600080fd5b6101bf600160a060020a03600435166024356104e1565b604051901515815260200160405180910390f35b34156101de57600080fd5b6101f2600160a060020a0360043516610564565b60405190815260200160405180910390f35b341561020f57600080fd5b6101f2610629565b341561022257600080fd5b6101bf600160a060020a0360043581169060243516604435610686565b341561024a57600080fd5b610267600160a060020a0360043581169060243516604435610711565b005b341561027457600080fd5b61027c610778565b60405160ff909116815260200160405180910390f35b341561029d57600080fd5b6102a5610781565b604051600160a060020a03909116815260200160405180910390f35b34156102cc57600080fd5b610267600435610790565b34156102e257600080fd5b6102a5610841565b34156102f557600080fd5b6101f2600160a060020a0360043516610850565b341561031457600080fd5b610267600160a060020a0360043581169060243516604435610915565b341561033c57600080fd5b6101bf600160a060020a036004351660243561097c565b341561035e57600080fd5b6101f2600160a060020a03600435166109e2565b341561037d57600080fd5b610267600435610a51565b341561039357600080fd5b610126610b02565b34156103a657600080fd5b6101bf600160a060020a0360043516602435610b6d565b34156103c857600080fd5b6102a5600435610bd3565b34156103de57600080fd5b6101f2610bee565b34156103f157600080fd5b6102a5600435610bf4565b341561040757600080fd5b6101bf600160a060020a0360043516602435610c0f565b341561042957600080fd5b6101f2600160a060020a0360043581169060243516610c75565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b820191906000526020600020905b8154815290600101906020018083116104bc57829003601f168201915b505050505081565b600354600090600160a060020a03166389064fd233858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b5af1151561055457600080fd5b5050506040518051949350505050565b6000600160a060020a038216151561057b57600080fd5b610583610cd0565b905060206040519081016040908152600160a060020a038416825260008381526002602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507fd76fc900a7e1a6fcf11d54b7ba943918df6c53a3128140658c389b3da1e997ba813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b600354600090600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561066b57600080fd5b5af1151561067857600080fd5b505050604051805191505090565b600354600090600160a060020a0316635d5e22cd3386868660405160e060020a63ffffffff8716028152600160a060020a0394851660048201529284166024840152921660448201526064810191909152608401602060405180830381600087803b15156106f357600080fd5b5af1151561070057600080fd5b505050604051805195945050505050565b60035433600160a060020a0390811691161461072c57600080fd5b81600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405190815260200160405180910390a3505050565b60075460ff1681565b600154600160a060020a031681565b60015433600160a060020a039081169116146107ab57600080fd5b6107b481610d1e565b60018054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526002602052604090819020805490921690915590547f9a99272c0f6b7a30ef9e76e684a7cd408bfd4f11a72f36a8e276253c920e442d92849291169051918252600160a060020a031660208201526040908101905180910390a150565b600354600160a060020a031681565b6000600160a060020a038216151561086757600080fd5b61086f610cd0565b905060206040519081016040908152600160a060020a038416825260008381526004602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507f5df12834436b8dc248df3f7f1796a3e39f851d610be49cdcd92514fa821b9f97813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b60035433600160a060020a0390811691161461093057600080fd5b81600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405190815260200160405180910390a3505050565b600354600090600160a060020a03166361e1077d33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a03166370a082318360405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b1515610a3557600080fd5b5af11515610a4257600080fd5b50505060405180519392505050565b60015433600160a060020a03908116911614610a6c57600080fd5b610a7581610d52565b60038054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526004602052604090819020805490921690915590547f9d55b0349a0a4c5b511f72228170bb91d45c9ac78dba8ab5b4175d3ed42f06b392849291169051918252600160a060020a031660208201526040908101905180910390a150565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b600354600090600160a060020a031663dfe0f0ca33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600460205260009081526040902054600160a060020a031681565b60005481565b600260205260009081526040902054600160a060020a031681565b600354600090600160a060020a0316632e0179b533858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a031663dd62ed3e848460405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561054757600080fd5b60008054600101808255600019430140903090604051928352600160a060020a03919091166c0100000000000000000000000002602083015260348201526054016040518091039020905090565b60008181526002602052604081208054600160a060020a03161515610d4257600080fd5b54600160a060020a031692915050565b60008181526004602052604081208054600160a060020a03161515610d4257600080fd00a165627a7a7230582007f17f5dae7dcd0c7786f3ebfe9da710494367254ed614bdea7e5020fd4945a70029","sourceMap":"11277:4743:0:-;;;;;;;;;-1:-1:-1;;;11277:4743:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11411:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;11411:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14250:164;;;;;;;;;;-1:-1:-1;;;;;14250:164:0;;;;;;;;;;;;;;;;;;;;;;;;3199:396;;;;;;;;;;-1:-1:-1;;;;;3199:396:0;;;;;;;;;;;;;;;;;;;;12084:102;;;;;;;;;;;;13520:186;;;;;;;;;;-1:-1:-1;;;;;13520:186:0;;;;;;;;;;;;12560:134;;;;;;;;;;-1:-1:-1;;;;;12560:134:0;;;;;;;;;;;;;;11583:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2262:24;;;;;;;;;;;;;;;-1:-1:-1;;;;;2262:24:0;;;;;;;;;;;;;;3997:241;;;;;;;;;;;;;;6012:26;;;;;;;;;;;;6960:356;;;;;;;;;;-1:-1:-1;;;;;6960:356:0;;;;;13757:146;;;;;;;;;;-1:-1:-1;;;;;13757:146:0;;;;;;;;;;;;15468:202;;;;;;;;;;-1:-1:-1;;;;;15468:202:0;;;;;;;12383:126;;;;;;;;;;-1:-1:-1;;;;;12383:126:0;;;;;7723:230;;;;;;;;;;;;;;11489:20;;;;;;;;;;;;12993:156;;;;;;;;;;-1:-1:-1;;;;;12993:156:0;;;;;;;6117:60;;;;;;;;;;;;;;615:31;;;;;;;;;;;;2360:70;;;;;;;;;;;;;;14849:192;;;;;;;;;;-1:-1:-1;;;;;14849:192:0;;;;;;;15861:156;;;;;;;;;;-1:-1:-1;;;;;15861:156:0;;;;;;;;;;11411:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14250:164::-;14349:9;;14317:12;;-1:-1:-1;;;;;14349:9:0;:27;14377:10;14389:8;14399:6;14349:57;;-1:-1:-1;;;14349:57:0;;;;;;-1:-1:-1;;;;;14349:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14250:164;-1:-1:-1;;;;14250:164:0:o;3199:396::-;3275:14;-1:-1:-1;;;;;3310:32:0;;;;3302:41;;;;;;3365:16;:14;:16::i;:::-;3356:25;;3424:81;;;;;;;;;;-1:-1:-1;;;;;3424:81:0;;;;3394:27;;;;:19;:27;;;3424:81;3394:111;;;-1:-1:-1;;3394:111:0;-1:-1:-1;;;;;3394:111:0;;;;;;;-1:-1:-1;3523:64:0;3548:6;3556:10;3568:18;3523:64;;;;;-1:-1:-1;;;;;3523:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;3199:396;;;:::o;12084:102::-;12155:9;;12128:7;;-1:-1:-1;;;;;12155:9:0;:21;:23;;;;;-1:-1:-1;;;12155:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12084:102:0;:::o;13520:186::-;13634:9;;13602:12;;-1:-1:-1;;;;;13634:9:0;:32;13667:10;13679:5;13686:3;13691:6;13634:64;;-1:-1:-1;;;13634:64:0;;;;;;-1:-1:-1;;;;;13634:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13520:186;-1:-1:-1;;;;;13520:186:0:o;12560:134::-;6426:9;;6404:10;-1:-1:-1;;;;;6404:32:0;;;6426:9;;6404:32;6396:41;;;;;;12674:3;-1:-1:-1;;;;;12658:28:0;12667:5;-1:-1:-1;;;;;12658:28:0;;12679:6;12658:28;;;;;;;;;;;;;;12560:134;;;:::o;11583:21::-;;;;;;:::o;2262:24::-;;;-1:-1:-1;;;;;2262:24:0;;:::o;3997:241::-;2692:9;;2678:10;-1:-1:-1;;;;;2678:23:0;;;2692:9;;2678:23;2670:32;;;;;;4090:30;4112:7;4090:21;:30::i;:::-;4078:9;:42;;-1:-1:-1;;;;;4078:42:0;;;-1:-1:-1;;4078:42:0;;;;;;:9;4140:28;;;:19;:28;;;;;;;4133:35;;;;;;;;4220:9;;4186:44;;4160:7;;4220:9;;;4186:44;;;;-1:-1:-1;;;;;4186:44:0;;;;;;;;;;;;;;;;3997:241;:::o;6012:26::-;;;-1:-1:-1;;;;;6012:26:0;;:::o;6960:356::-;7026:14;-1:-1:-1;;;;;7061:27:0;;;;7053:36;;;;;;7111:16;:14;:16::i;:::-;7102:25;;7165:71;;;;;;;;;;-1:-1:-1;;;;;7165:71:0;;;;7140:22;;;;:14;:22;;;7165:71;7140:96;;;-1:-1:-1;;7140:96:0;-1:-1:-1;;;;;7140:96:0;;;;;;;-1:-1:-1;7254:54:0;7274:6;7282:10;7294:13;7254:54;;;;;-1:-1:-1;;;;;7254:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;6960:356;;;:::o;13757:146::-;6426:9;;6404:10;-1:-1:-1;;;;;6404:32:0;;;6426:9;;6404:32;6396:41;;;;;;13878:8;-1:-1:-1;;;;;13861:34:0;13870:6;-1:-1:-1;;;;;13861:34:0;;13888:6;13861:34;;;;;;;;;;;;;;13757:146;;;:::o;15468:202::-;15586:9;;15554:12;;-1:-1:-1;;;;;15586:9:0;:36;15623:10;15635:8;15645:16;15586:76;;-1:-1:-1;;;15586:76:0;;;;;;-1:-1:-1;;;;;15586:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12383:126;12474:9;;12439:15;;-1:-1:-1;;;;;12474:9:0;:19;12494:6;12474:27;;-1:-1:-1;;;12474:27:0;;;;;;-1:-1:-1;;;;;12474:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12383:126;-1:-1:-1;;;12383:126:0:o;7723:230::-;2692:9;;2678:10;-1:-1:-1;;;;;2678:23:0;;;2692:9;;2678:23;2670:32;;;;;;7811:25;7828:7;7811:16;:25::i;:::-;7799:9;:37;;-1:-1:-1;;;;;7799:37:0;;;-1:-1:-1;;7799:37:0;;;;;;:9;7856:23;;;:14;:23;;;;;;;7849:30;;;;;;;;7934:9;;7897:48;;7871:7;;7934:9;;;7897:48;;;;-1:-1:-1;;;;;7897:48:0;;;;;;;;;;;;;;;;7723:230;:::o;11489:20::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12993:156;13088:9;;13056:12;;-1:-1:-1;;;;;13088:9:0;:28;13117:10;13129:3;13134:6;13088:53;;-1:-1:-1;;;13088:53:0;;;;;;-1:-1:-1;;;;;13088:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6117:60;;;;;;;;;;;;-1:-1:-1;;;;;6117:60:0;;:::o;615:31::-;;;;:::o;2360:70::-;;;;;;;;;;;;-1:-1:-1;;;;;2360:70:0;;:::o;14849:192::-;14962:9;;14930:12;;-1:-1:-1;;;;;14962:9:0;:36;14999:10;15011:8;15021:11;14962:71;;-1:-1:-1;;;14962:71:0;;;;;;-1:-1:-1;;;;;14962:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15861:156;15972:9;;15935:17;;-1:-1:-1;;;;;15972:9:0;:19;15992:6;16000:8;15972:37;;-1:-1:-1;;;15972:37:0;;;;;;-1:-1:-1;;;;;15972:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1257:165;1301:14;1395:18;;1376:1;1395:18;;;;-1:-1:-1;;1361:12:0;:16;1345:33;;1388:4;;1335:79;;;;;-1:-1:-1;;;;;1335:79:0;;;;;;;;;;;;;;;;;;;;;;;1328:86;;1257:165;:::o;4272:415::-;4342:20;4422:28;;;:19;:28;;;;;4603:25;;-1:-1:-1;;;;;4603:25:0;:30;;4595:39;;;;;;4654:25;-1:-1:-1;;;;;4654:25:0;;4272:415;-1:-1:-1;;4272:415:0:o;7987:422::-;8052:22;8129:23;;;:14;:23;;;;;8305:25;;-1:-1:-1;;;;;8305:25:0;:39;;8297:48;;;;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa165627a7a7230582007f17f5dae7dcd0c7786f3ebfe9da710494367254ed614bdea7e5020fd4945a70029","offset":3447}},"immutableReferences":{},"transformations":[{"id":"1","type":"replace","offset":3447,"reason":"cborAuxdata"}],"transformationValues":{"cborAuxdata":{"1":"0xa165627a7a72305820e9510794af44fba3b1d3c8d2d27f071e428847cc4b56c82a806ad15368cfc00b0029"}}},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"deployment":{"transactionHash":"0xf51a232b0e5604aa3549f5d22fd470971a627d55536eb7477b39a80b5c38b01b","blockNumber":"6301780","transactionIndex":"10","deployer":"0x4c2F150Fc90fed3d8281114c2349f1906cdE5346"},"matchId":"2157765","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2024-08-08T14:42:53Z","match":"match","chainId":"1","address":"0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd"}