Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 303 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Lend | 11474940 | 1536 days ago | IN | 0 ETH | 0.016979 | ||||
Request Loan | 11420384 | 1544 days ago | IN | 0 ETH | 0.01299468 | ||||
Lend | 11393923 | 1548 days ago | IN | 0 ETH | 0.00862747 | ||||
Lend | 11350633 | 1555 days ago | IN | 0 ETH | 0.00623095 | ||||
Lend | 11344613 | 1556 days ago | IN | 0 ETH | 0.00673422 | ||||
Lend | 11322743 | 1559 days ago | IN | 0 ETH | 0.03943363 | ||||
Lend | 11279226 | 1566 days ago | IN | 0 ETH | 0.03298849 | ||||
Lend | 11254106 | 1570 days ago | IN | 0 ETH | 0.00556948 | ||||
Lend | 11253980 | 1570 days ago | IN | 0 ETH | 0.00513308 | ||||
Lend | 11235093 | 1573 days ago | IN | 0 ETH | 0.00685475 | ||||
Lend | 11192772 | 1579 days ago | IN | 0 ETH | 0.00593953 | ||||
Lend | 11169028 | 1583 days ago | IN | 0 ETH | 0.0059979 | ||||
Request Loan | 11152597 | 1585 days ago | IN | 0 ETH | 0.01264895 | ||||
Lend | 11124431 | 1590 days ago | IN | 0 ETH | 0.00640575 | ||||
Lend | 11119137 | 1591 days ago | IN | 0 ETH | 0.00689759 | ||||
Request Loan | 11101392 | 1593 days ago | IN | 0 ETH | 0.01770853 | ||||
Lend | 11089168 | 1595 days ago | IN | 0 ETH | 0.01368279 | ||||
Lend | 11086152 | 1596 days ago | IN | 0 ETH | 0.0173931 | ||||
Request Loan | 11070081 | 1598 days ago | IN | 0 ETH | 0.00580702 | ||||
Lend | 11068579 | 1598 days ago | IN | 0 ETH | 0.01140232 | ||||
Request Loan | 11049877 | 1601 days ago | IN | 0 ETH | 0.00551954 | ||||
Request Loan | 11010919 | 1607 days ago | IN | 0 ETH | 0.00988918 | ||||
Request Loan | 10984851 | 1611 days ago | IN | 0 ETH | 0.00827974 | ||||
Lend | 10982426 | 1612 days ago | IN | 0 ETH | 0.01713688 | ||||
Lend | 10948242 | 1617 days ago | IN | 0 ETH | 0.02036265 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
LoanManager
Compiler Version
v0.5.11+commit.c082d0b4
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-09-03 */ // File: contracts/interfaces/IERC20.sol pragma solidity ^0.5.11; interface IERC20 { function transfer(address _to, uint _value) external returns (bool success); function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); function allowance(address _owner, address _spender) external view returns (uint256 remaining); function approve(address _spender, uint256 _value) external returns (bool success); function increaseApproval (address _spender, uint _addedValue) external returns (bool success); function balanceOf(address _owner) external view returns (uint256 balance); } // File: contracts/interfaces/IERC165.sol pragma solidity ^0.5.11; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); } // File: contracts/core/diaspore/interfaces/Model.sol pragma solidity ^0.5.11; /** The abstract contract Model defines the whole lifecycle of a debt on the DebtEngine. Models can be used without previous approbation, this is meant to avoid centralization on the development of RCN; this implies that not all models are secure. Models can have back-doors, bugs and they have not guarantee of being autonomous. The DebtEngine is meant to be the User of this model, so all the methods with the ability to perform state changes should only be callable by the DebtEngine. All models should implement the 0xaf498c35 interface. @author Agustin Aguilar */ contract Model is IERC165 { // /// // Events // /// /** @dev This emits when create a new debt. */ event Created(bytes32 indexed _id); /** @dev This emits when the status of debt change. @param _timestamp Timestamp of the registry @param _status New status of the registry */ event ChangedStatus(bytes32 indexed _id, uint256 _timestamp, uint256 _status); /** @dev This emits when the obligation of debt change. @param _timestamp Timestamp of the registry @param _debt New debt of the registry */ event ChangedObligation(bytes32 indexed _id, uint256 _timestamp, uint256 _debt); /** @dev This emits when the frequency of debt change. @param _timestamp Timestamp of the registry @param _frequency New frequency of each installment */ event ChangedFrequency(bytes32 indexed _id, uint256 _timestamp, uint256 _frequency); /** @param _timestamp Timestamp of the registry */ event ChangedDueTime(bytes32 indexed _id, uint256 _timestamp, uint256 _status); /** @param _timestamp Timestamp of the registry @param _dueTime New dueTime of each installment */ event ChangedFinalTime(bytes32 indexed _id, uint256 _timestamp, uint64 _dueTime); /** @dev This emits when the call addDebt function. @param _amount New amount of the debt, old amount plus added */ event AddedDebt(bytes32 indexed _id, uint256 _amount); /** @dev This emits when the call addPaid function. If the registry is fully paid on the call and the amount parameter exceeds the required payment amount, the event emits the real amount paid on the payment. @param _paid Real amount paid */ event AddedPaid(bytes32 indexed _id, uint256 _paid); // Model interface selector bytes4 internal constant MODEL_INTERFACE = 0xaf498c35; uint256 public constant STATUS_ONGOING = 1; uint256 public constant STATUS_PAID = 2; uint256 public constant STATUS_ERROR = 4; // /// // Meta // /// /** @return Identifier of the model */ function modelId() external view returns (bytes32); /** Returns the address of the contract used as Descriptor of the model @dev The descriptor contract should follow the ModelDescriptor.sol scheme @return Address of the descriptor */ function descriptor() external view returns (address); /** If called for any address with the ability to modify the state of the model registries, this method should return True. @dev Some contracts may check if the DebtEngine is an operator to know if the model is operative or not. @param operator Address of the target request operator @return True if operator is able to modify the state of the model */ function isOperator(address operator) external view returns (bool canOperate); /** Validates the data for the creation of a new registry, if returns True the same data should be compatible with the create method. @dev This method can revert the call or return false, and both meant an invalid data. @param data Data to validate @return True if the data can be used to create a new registry */ function validate(bytes calldata data) external view returns (bool isValid); // /// // Getters // /// /** Exposes the current status of the registry. The possible values are: 1: Ongoing - The debt is still ongoing and waiting to be paid 2: Paid - The debt is already paid and 4: Error - There was an Error with the registry @dev This method should always be called by the DebtEngine @param id Id of the registry @return The current status value */ function getStatus(bytes32 id) external view returns (uint256 status); /** Returns the total paid amount on the registry. @dev it should equal to the sum of all real addPaid @param id Id of the registry @return Total paid amount */ function getPaid(bytes32 id) external view returns (uint256 paid); /** If the returned amount does not depend on any interactions and only on the model logic, the defined flag will be True; if the amount is an estimation of the future debt, the flag will be set to False. If timestamp equals the current moment, the defined flag should always be True. @dev This can be a gas-intensive method to call, consider calling the run method before. @param id Id of the registry @param timestamp Timestamp of the obligation query @return amount Amount pending to pay on the given timestamp @return defined True If the amount returned is fixed and can't change */ function getObligation(bytes32 id, uint64 timestamp) external view returns (uint256 amount, bool defined); /** The amount required to fully paid a registry. All registries should be payable in a single time, even when it has multiple installments. If the registry discounts interest for early payment, those discounts should be taken into account in the returned amount. @dev This can be a gas-intensive method to call, consider calling the run method before. @param id Id of the registry @return amount Amount required to fully paid the loan on the current timestamp */ function getClosingObligation(bytes32 id) external view returns (uint256 amount); /** The timestamp of the next required payment. After this moment, if the payment goal is not met the debt will be considered overdue. The getObligation method can be used to know the required payment on the future timestamp. @param id Id of the registry @return timestamp The timestamp of the next due time */ function getDueTime(bytes32 id) external view returns (uint256 timestamp); // /// // Metadata // /// /** If the loan has multiple installments returns the duration of each installment in seconds, if the loan has not installments it should return 1. @param id Id of the registry @return frequency Frequency of each installment */ function getFrequency(bytes32 id) external view returns (uint256 frequency); /** If the loan has multiple installments returns the total of installments, if the loan has not installments it should return 1. @param id Id of the registry @return installments Total of installments */ function getInstallments(bytes32 id) external view returns (uint256 installments); /** The registry could be paid before or after the date, but the debt will always be considered overdue if paid after this timestamp. This is the estimated final payment date of the debt if it's always paid on each exact dueTime. @param id Id of the registry @return timestamp Timestamp of the final due time */ function getFinalTime(bytes32 id) external view returns (uint256 timestamp); /** Similar to getFinalTime returns the expected payment remaining if paid always on the exact dueTime. If the model has no interest discounts for early payments, this method should return the same value as getClosingObligation. @param id Id of the registry @return amount Expected payment amount */ function getEstimateObligation(bytes32 id) external view returns (uint256 amount); // /// // State interface // /// /** Creates a new registry using the provided data and id, it should fail if the id already exists or if calling validate(data) returns false or throws. @dev This method should only be callable by an operator @param id Id of the registry to create @param data Data to construct the new registry @return success True if the registry was created */ function create(bytes32 id, bytes calldata data) external returns (bool success); /** If the registry is fully paid on the call and the amount parameter exceeds the required payment amount, the method returns the real amount used on the payment. The payment taken should always be the same as the requested unless the registry is fully paid on the process. @dev This method should only be callable by an operator @param id If of the registry @param amount Amount to pay @return real Real amount paid */ function addPaid(bytes32 id, uint256 amount) external returns (uint256 real); /** Adds a new amount to be paid on the debt model, each model can handle the addition of more debt freely. @dev This method should only be callable by an operator @param id Id of the registry @param amount Debt amount to add to the registry @return added True if the debt was added */ function addDebt(bytes32 id, uint256 amount) external returns (bool added); // /// // Utils // /// /** Runs the internal clock of a registry, this is used to compute the last changes on the state. It can make transactions cheaper by avoiding multiple calculations when calling views. Not all models have internal clocks, a model without an internal clock should always return false. Calls to this method should be possible from any address, multiple calls to run shouldn't affect the internal calculations of the model. @dev If the call had no effect the method would return False, that is no sign of things going wrong, and the call shouldn't be wrapped on a require @param id If of the registry @return effect True if the run performed a change on the state */ function run(bytes32 id) external returns (bool effect); } // File: contracts/core/diaspore/interfaces/RateOracle.sol pragma solidity ^0.5.11; /** @dev Defines the interface of a standard Diaspore RCN Oracle, The contract should also implement it's ERC165 interface: 0xa265d8e0 @notice Each oracle can only support one currency @author Agustin Aguilar */ contract RateOracle is IERC165 { uint256 public constant VERSION = 5; bytes4 internal constant RATE_ORACLE_INTERFACE = 0xa265d8e0; constructor() internal {} /** 3 or 4 letters symbol of the currency, Ej: ETH */ function symbol() external view returns (string memory); /** Descriptive name of the currency, Ej: Ethereum */ function name() external view returns (string memory); /** The number of decimals of the currency represented by this Oracle, it should be the most common number of decimal places */ function decimals() external view returns (uint256); /** The base token on which the sample is returned should be the RCN Token address. */ function token() external view returns (address); /** The currency symbol encoded on a UTF-8 Hex */ function currency() external view returns (bytes32); /** The name of the Individual or Company in charge of this Oracle */ function maintainer() external view returns (string memory); /** Returns the url where the oracle exposes a valid "oracleData" if needed */ function url() external view returns (string memory); /** Returns a sample on how many token() are equals to how many currency() */ function readSample(bytes calldata _data) external returns (uint256 _tokens, uint256 _equivalent); } // File: contracts/utils/IsContract.sol pragma solidity ^0.5.11; library IsContract { function isContract(address _addr) internal view returns (bool) { uint size; assembly { size := extcodesize(_addr) } return size > 0; } } // File: contracts/utils/SafeMath.sol pragma solidity ^0.5.11; library SafeMath { function add(uint256 x, uint256 y) internal pure returns (uint256) { uint256 z = x + y; require(z >= x, "Add overflow"); return z; } function sub(uint256 x, uint256 y) internal pure returns (uint256) { require(x >= y, "Sub overflow"); return x - y; } function mult(uint256 x, uint256 y) internal pure returns (uint256) { if (x == 0) { return 0; } uint256 z = x * y; require(z/x == y, "Mult overflow"); return z; } } // File: contracts/commons/ERC165.sol pragma solidity ^0.5.11; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor() internal { _registerInterface(_InterfaceId_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff, "Can't register 0xffffffff"); _supportedInterfaces[interfaceId] = true; } } // File: contracts/commons/ERC721Base.sol pragma solidity ^0.5.11; interface URIProvider { function tokenURI(uint256 _tokenId) external view returns (string memory); } contract ERC721Base is ERC165 { using SafeMath for uint256; using IsContract for address; mapping(uint256 => address) private _holderOf; // Owner to array of assetId mapping(address => uint256[]) private _assetsOf; // AssetId to index on array in _assetsOf mapping mapping(uint256 => uint256) private _indexOfAsset; mapping(address => mapping(address => bool)) private _operators; mapping(uint256 => address) private _approval; bytes4 private constant ERC721_RECEIVED = 0x150b7a02; bytes4 private constant ERC721_RECEIVED_LEGACY = 0xf0b9e5ba; event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); bytes4 private constant ERC_721_INTERFACE = 0x80ac58cd; bytes4 private constant ERC_721_METADATA_INTERFACE = 0x5b5e139f; bytes4 private constant ERC_721_ENUMERATION_INTERFACE = 0x780e9d63; constructor( string memory name, string memory symbol ) public { _name = name; _symbol = symbol; _registerInterface(ERC_721_INTERFACE); _registerInterface(ERC_721_METADATA_INTERFACE); _registerInterface(ERC_721_ENUMERATION_INTERFACE); } // /// // ERC721 Metadata // /// /// ERC-721 Non-Fungible Token Standard, optional metadata extension /// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 identifier for this interface is 0x5b5e139f. event SetURIProvider(address _uriProvider); string private _name; string private _symbol; URIProvider private _uriProvider; // @notice A descriptive name for a collection of NFTs in this contract function name() external view returns (string memory) { return _name; } // @notice An abbreviated name for NFTs in this contract function symbol() external view returns (string memory) { return _symbol; } /** * @notice A distinct Uniform Resource Identifier (URI) for a given asset. * @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC * 3986. The URI may point to a JSON file that conforms to the "ERC721 * Metadata JSON Schema". */ function tokenURI(uint256 _tokenId) external view returns (string memory) { require(_holderOf[_tokenId] != address(0), "Asset does not exist"); URIProvider provider = _uriProvider; return address(provider) == address(0) ? "" : provider.tokenURI(_tokenId); } function _setURIProvider(URIProvider _provider) internal returns (bool) { emit SetURIProvider(address(_provider)); _uriProvider = _provider; return true; } // /// // ERC721 Enumeration // /// /// ERC-721 Non-Fungible Token Standard, optional enumeration extension /// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 identifier for this interface is 0x780e9d63. uint256[] private _allTokens; /** * @dev Gets the total of assets stored by the contract * Warning: this method can consume all the gas of the transaction, it should not be * called from another contract, it should only be used in external calls * @return an array with total assets */ function allTokens() external view returns (uint256[] memory) { return _allTokens; } /** * @dev Gets the total of assets of the owner * Warning: this method can consume all the gas of the transaction, it should not be * called from another contract, it should only be used in external calls * @param _owner the address of owner * @return an array with total assets of owner */ function assetsOf(address _owner) external view returns (uint256[] memory) { return _assetsOf[_owner]; } /** * @dev Gets the total amount of assets stored by the contract * @return uint256 representing the total amount of assets */ function totalSupply() external view returns (uint256) { return _allTokens.length; } /** * @notice Enumerate valid NFTs * @dev Throws if `_index` >= `totalSupply()`. * @param _index A counter less than `totalSupply()` * @return The token identifier for the `_index` of the NFT, * (sort order not specified) */ function tokenByIndex(uint256 _index) external view returns (uint256) { require(_index < _allTokens.length, "Index out of bounds"); return _allTokens[_index]; } /** * @notice Enumerate NFTs assigned to an owner * @dev Throws if `_index` >= `balanceOf(_owner)` or if * `_owner` is the zero address, representing invalid NFTs. * @param _owner An address where we are interested in NFTs owned by them * @param _index A counter less than `balanceOf(_owner)` * @return The token identifier for the `_index` of the NFT assigned to `_owner`, * (sort order not specified) */ function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256) { require(_owner != address(0), "0x0 Is not a valid owner"); require(_index < _balanceOf(_owner), "Index out of bounds"); return _assetsOf[_owner][_index]; } // // Asset-centric getter functions // /** * @dev Queries what address owns an asset. This method does not throw. * In order to check if the asset exists, use the `exists` function or check if the * return value of this call is `0`. * @return uint256 the assetId */ function ownerOf(uint256 _assetId) external view returns (address) { return _ownerOf(_assetId); } function _ownerOf(uint256 _assetId) internal view returns (address) { return _holderOf[_assetId]; } // // Holder-centric getter functions // /** * @dev Gets the balance of the specified address * @param _owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address _owner) external view returns (uint256) { return _balanceOf(_owner); } function _balanceOf(address _owner) internal view returns (uint256) { return _assetsOf[_owner].length; } // // Authorization getters // /** * @dev Query whether an address has been authorized to move any assets on behalf of someone else * @param _operator the address that might be authorized * @param _assetHolder the address that provided the authorization * @return bool true if the operator has been authorized to move any assets */ function isApprovedForAll( address _operator, address _assetHolder ) external view returns (bool) { return _isApprovedForAll(_operator, _assetHolder); } function _isApprovedForAll( address _operator, address _assetHolder ) internal view returns (bool) { return _operators[_assetHolder][_operator]; } /** * @dev Query what address has been particularly authorized to move an asset * @param _assetId the asset to be queried for * @return bool true if the asset has been approved by the holder */ function getApproved(uint256 _assetId) external view returns (address) { return _getApproved(_assetId); } function _getApproved(uint256 _assetId) internal view returns (address) { return _approval[_assetId]; } /** * @dev Query if an operator can move an asset. * @param _operator the address that might be authorized * @param _assetId the asset that has been `approved` for transfer * @return bool true if the asset has been approved by the holder */ function isAuthorized(address _operator, uint256 _assetId) external view returns (bool) { return _isAuthorized(_operator, _assetId); } function _isAuthorized(address _operator, uint256 _assetId) internal view returns (bool) { require(_operator != address(0), "0x0 is an invalid operator"); address owner = _ownerOf(_assetId); return _operator == owner || _isApprovedForAll(_operator, owner) || _getApproved(_assetId) == _operator; } // // Authorization // /** * @dev Authorize a third party operator to manage (send) msg.sender's asset * @param _operator address to be approved * @param _authorized bool set to true to authorize, false to withdraw authorization */ function setApprovalForAll(address _operator, bool _authorized) external { if (_operators[msg.sender][_operator] != _authorized) { _operators[msg.sender][_operator] = _authorized; emit ApprovalForAll(msg.sender, _operator, _authorized); } } /** * @dev Authorize a third party operator to manage one particular asset * @param _operator address to be approved * @param _assetId asset to approve */ function approve(address _operator, uint256 _assetId) external { address holder = _ownerOf(_assetId); require(msg.sender == holder || _isApprovedForAll(msg.sender, holder), "msg.sender can't approve"); if (_getApproved(_assetId) != _operator) { _approval[_assetId] = _operator; emit Approval(holder, _operator, _assetId); } } // // Internal Operations // function _addAssetTo(address _to, uint256 _assetId) private { // Store asset owner _holderOf[_assetId] = _to; // Store index of the asset uint256 length = _balanceOf(_to); _assetsOf[_to].push(_assetId); _indexOfAsset[_assetId] = length; // Save main enumerable _allTokens.push(_assetId); } function _transferAsset(address _from, address _to, uint256 _assetId) private { uint256 assetIndex = _indexOfAsset[_assetId]; uint256 lastAssetIndex = _balanceOf(_from).sub(1); if (assetIndex != lastAssetIndex) { // Replace current asset with last asset uint256 lastAssetId = _assetsOf[_from][lastAssetIndex]; // Insert the last asset into the position previously occupied by the asset to be removed _assetsOf[_from][assetIndex] = lastAssetId; _indexOfAsset[lastAssetId] = assetIndex; } // Resize the array _assetsOf[_from][lastAssetIndex] = 0; _assetsOf[_from].length--; // Change owner _holderOf[_assetId] = _to; // Update the index of positions of the asset uint256 length = _balanceOf(_to); _assetsOf[_to].push(_assetId); _indexOfAsset[_assetId] = length; } function _clearApproval(address _holder, uint256 _assetId) private { if (_approval[_assetId] != address(0)) { _approval[_assetId] = address(0); emit Approval(_holder, address(0), _assetId); } } // // Supply-altering functions // function _generate(uint256 _assetId, address _beneficiary) internal { require(_holderOf[_assetId] == address(0), "Asset already exists"); _addAssetTo(_beneficiary, _assetId); emit Transfer(address(0), _beneficiary, _assetId); } // // Transaction related operations // modifier onlyAuthorized(uint256 _assetId) { require(_isAuthorized(msg.sender, _assetId), "msg.sender Not authorized"); _; } modifier isCurrentOwner(address _from, uint256 _assetId) { require(_ownerOf(_assetId) == _from, "Not current owner"); _; } modifier addressDefined(address _target) { require(_target != address(0), "Target can't be 0x0"); _; } /** * @dev Alias of `safeTransferFrom(from, to, assetId, '')` * * @param _from address that currently owns an asset * @param _to address to receive the ownership of the asset * @param _assetId uint256 ID of the asset to be transferred */ function safeTransferFrom(address _from, address _to, uint256 _assetId) external { return _doTransferFrom( _from, _to, _assetId, "", true ); } /** * @dev Securely transfers the ownership of a given asset from one address to * another address, calling the method `onNFTReceived` on the target address if * there's code associated with it * * @param _from address that currently owns an asset * @param _to address to receive the ownership of the asset * @param _assetId uint256 ID of the asset to be transferred * @param _userData bytes arbitrary user information to attach to this transfer */ function safeTransferFrom( address _from, address _to, uint256 _assetId, bytes calldata _userData ) external { return _doTransferFrom( _from, _to, _assetId, _userData, true ); } /** * @dev Transfers the ownership of a given asset from one address to another address * Warning! This function does not attempt to verify that the target address can send * tokens. * * @param _from address sending the asset * @param _to address to receive the ownership of the asset * @param _assetId uint256 ID of the asset to be transferred */ function transferFrom(address _from, address _to, uint256 _assetId) external { return _doTransferFrom( _from, _to, _assetId, "", false ); } /** * Internal function that moves an asset from one holder to another */ function _doTransferFrom( address _from, address _to, uint256 _assetId, bytes memory _userData, bool _doCheck ) internal onlyAuthorized(_assetId) addressDefined(_to) isCurrentOwner(_from, _assetId) { address holder = _holderOf[_assetId]; _clearApproval(holder, _assetId); _transferAsset(holder, _to, _assetId); if (_doCheck && _to.isContract()) { // Call dest contract // Perform check with the new safe call // onERC721Received(address,address,uint256,bytes) (bool success, bytes4 result) = _noThrowCall( _to, abi.encodeWithSelector( ERC721_RECEIVED, msg.sender, holder, _assetId, _userData ) ); if (!success || result != ERC721_RECEIVED) { // Try legacy safe call // onERC721Received(address,uint256,bytes) (success, result) = _noThrowCall( _to, abi.encodeWithSelector( ERC721_RECEIVED_LEGACY, holder, _assetId, _userData ) ); require( success && result == ERC721_RECEIVED_LEGACY, "Contract rejected the token" ); } } emit Transfer(holder, _to, _assetId); } // // Utilities // /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), * relaxing the requirement on the return value * @param _contract The contract that receives the ERC721 * @param _data The call data * @return True if the call not reverts and the result of the call */ function _noThrowCall( address _contract, bytes memory _data ) internal returns (bool success, bytes4 result) { bytes memory returnData; (success, returnData) = _contract.call(_data); if (returnData.length > 0) result = abi.decode(returnData, (bytes4)); } } // File: contracts/interfaces/IERC173.sol pragma solidity ^0.5.11; /// @title ERC-173 Contract Ownership Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-173.md /// Note: the ERC-165 identifier for this interface is 0x7f5828d0 contract IERC173 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner); /// @notice Get the address of the owner /// @return The address of the owner. //// function owner() external view returns (address); /// @notice Set the address of the new owner of the contract /// @param _newOwner The address of the new owner of the contract function transferOwnership(address _newOwner) external; } // File: contracts/commons/Ownable.sol pragma solidity ^0.5.11; contract Ownable is IERC173 { address internal _owner; modifier onlyOwner() { require(msg.sender == _owner, "The owner should be the sender"); _; } constructor() public { _owner = msg.sender; emit OwnershipTransferred(address(0x0), msg.sender); } function owner() external view returns (address) { return _owner; } /** @dev Transfers the ownership of the contract. @param _newOwner Address of the new owner */ function transferOwnership(address _newOwner) external onlyOwner { require(_newOwner != address(0), "0x0 Is not a valid owner"); emit OwnershipTransferred(_owner, _newOwner); _owner = _newOwner; } } // File: contracts/core/diaspore/DebtEngine.sol pragma solidity ^0.5.11; contract DebtEngine is ERC721Base, Ownable { using IsContract for address; event Created( bytes32 indexed _id, uint256 _nonce, bytes _data ); event Created2( bytes32 indexed _id, uint256 _salt, bytes _data ); event Created3( bytes32 indexed _id, uint256 _salt, bytes _data ); event Paid( bytes32 indexed _id, address _sender, address _origin, uint256 _requested, uint256 _requestedTokens, uint256 _paid, uint256 _tokens ); event ReadedOracleBatch( address _oracle, uint256 _count, uint256 _tokens, uint256 _equivalent ); event ReadedOracle( bytes32 indexed _id, uint256 _tokens, uint256 _equivalent ); event PayBatchError( bytes32 indexed _id, address _targetOracle ); event Withdrawn( bytes32 indexed _id, address _sender, address _to, uint256 _amount ); event Error( bytes32 indexed _id, address _sender, uint256 _value, uint256 _gasLeft, uint256 _gasLimit, bytes _callData ); event ErrorRecover( bytes32 indexed _id, address _sender, uint256 _value, uint256 _gasLeft, uint256 _gasLimit, bytes32 _result, bytes _callData ); IERC20 public token; mapping(bytes32 => Debt) public debts; mapping(address => uint256) public nonces; struct Debt { bool error; uint128 balance; Model model; address creator; address oracle; } constructor ( IERC20 _token ) public ERC721Base("RCN Debt Record", "RDR") { token = _token; // Sanity checks require(address(_token).isContract(), "Token should be a contract"); } function setURIProvider(URIProvider _provider) external onlyOwner { _setURIProvider(_provider); } function create( Model _model, address _owner, address _oracle, bytes calldata _data ) external returns (bytes32 id) { uint256 nonce = nonces[msg.sender]++; id = keccak256( abi.encodePacked( uint8(1), address(this), msg.sender, nonce ) ); debts[id] = Debt({ error: false, balance: 0, creator: msg.sender, model: _model, oracle: _oracle }); _generate(uint256(id), _owner); require(_model.create(id, _data), "Error creating debt in model"); emit Created({ _id: id, _nonce: nonce, _data: _data }); } function create2( Model _model, address _owner, address _oracle, uint256 _salt, bytes calldata _data ) external returns (bytes32 id) { id = keccak256( abi.encodePacked( uint8(2), address(this), msg.sender, _model, _oracle, _salt, _data ) ); debts[id] = Debt({ error: false, balance: 0, creator: msg.sender, model: _model, oracle: _oracle }); _generate(uint256(id), _owner); require(_model.create(id, _data), "Error creating debt in model"); emit Created2({ _id: id, _salt: _salt, _data: _data }); } function create3( Model _model, address _owner, address _oracle, uint256 _salt, bytes calldata _data ) external returns (bytes32 id) { id = keccak256( abi.encodePacked( uint8(3), address(this), msg.sender, _salt ) ); debts[id] = Debt({ error: false, balance: 0, creator: msg.sender, model: _model, oracle: _oracle }); _generate(uint256(id), _owner); require(_model.create(id, _data), "Error creating debt in model"); emit Created3({ _id: id, _salt: _salt, _data: _data }); } function buildId( address _creator, uint256 _nonce ) external view returns (bytes32) { return keccak256( abi.encodePacked( uint8(1), address(this), _creator, _nonce ) ); } function buildId2( address _creator, address _model, address _oracle, uint256 _salt, bytes calldata _data ) external view returns (bytes32) { return keccak256( abi.encodePacked( uint8(2), address(this), _creator, _model, _oracle, _salt, _data ) ); } function buildId3( address _creator, uint256 _salt ) external view returns (bytes32) { return keccak256( abi.encodePacked( uint8(3), address(this), _creator, _salt ) ); } function pay( bytes32 _id, uint256 _amount, address _origin, bytes calldata _oracleData ) external returns (uint256 paid, uint256 paidToken) { Debt storage debt = debts[_id]; // Paid only required amount paid = _safePay(_id, debt.model, _amount); require(paid <= _amount, "Paid can't be more than requested"); RateOracle oracle = RateOracle(debt.oracle); if (address(oracle) != address(0)) { // Convert (uint256 tokens, uint256 equivalent) = oracle.readSample(_oracleData); emit ReadedOracle(_id, tokens, equivalent); paidToken = _toToken(paid, tokens, equivalent); } else { paidToken = paid; } // Pull tokens from payer require(token.transferFrom(msg.sender, address(this), paidToken), "Error pulling payment tokens"); // Add balance to the debt uint256 newBalance = paidToken.add(debt.balance); require(newBalance < 340282366920938463463374607431768211456, "uint128 Overflow"); debt.balance = uint128(newBalance); // Emit pay event emit Paid({ _id: _id, _sender: msg.sender, _origin: _origin, _requested: _amount, _requestedTokens: 0, _paid: paid, _tokens: paidToken }); } function payToken( bytes32 id, uint256 amount, address origin, bytes calldata oracleData ) external returns (uint256 paid, uint256 paidToken) { Debt storage debt = debts[id]; // Read storage RateOracle oracle = RateOracle(debt.oracle); uint256 equivalent; uint256 tokens; uint256 available; // Get available <currency> amount if (address(oracle) != address(0)) { (tokens, equivalent) = oracle.readSample(oracleData); emit ReadedOracle(id, tokens, equivalent); available = _fromToken(amount, tokens, equivalent); } else { available = amount; } // Call addPaid on model paid = _safePay(id, debt.model, available); require(paid <= available, "Paid can't exceed available"); // Convert back to required pull amount if (address(oracle) != address(0)) { paidToken = _toToken(paid, tokens, equivalent); require(paidToken <= amount, "Paid can't exceed requested"); } else { paidToken = paid; } // Pull tokens from payer require(token.transferFrom(msg.sender, address(this), paidToken), "Error pulling tokens"); // Add balance to the debt // WARNING: Reusing variable **available** available = paidToken.add(debt.balance); require(available < 340282366920938463463374607431768211456, "uint128 Overflow"); debt.balance = uint128(available); // Emit pay event emit Paid({ _id: id, _sender: msg.sender, _origin: origin, _requested: 0, _requestedTokens: amount, _paid: paid, _tokens: paidToken }); } function payBatch( bytes32[] calldata _ids, uint256[] calldata _amounts, address _origin, address _oracle, bytes calldata _oracleData ) external returns (uint256[] memory paid, uint256[] memory paidTokens) { uint256 count = _ids.length; require(count == _amounts.length, "_ids and _amounts should have the same length"); uint256 tokens; uint256 equivalent; if (_oracle != address(0)) { (tokens, equivalent) = RateOracle(_oracle).readSample(_oracleData); emit ReadedOracleBatch(_oracle, count, tokens, equivalent); } paid = new uint256[](count); paidTokens = new uint256[](count); for (uint256 i = 0; i < count; i++) { uint256 amount = _amounts[i]; (paid[i], paidTokens[i]) = _pay(_ids[i], _oracle, amount, tokens, equivalent); emit Paid({ _id: _ids[i], _sender: msg.sender, _origin: _origin, _requested: amount, _requestedTokens: 0, _paid: paid[i], _tokens: paidTokens[i] }); } } function payTokenBatch( bytes32[] calldata _ids, uint256[] calldata _tokenAmounts, address _origin, address _oracle, bytes calldata _oracleData ) external returns (uint256[] memory paid, uint256[] memory paidTokens) { uint256 count = _ids.length; require(count == _tokenAmounts.length, "_ids and _amounts should have the same length"); uint256 tokens; uint256 equivalent; if (_oracle != address(0)) { (tokens, equivalent) = RateOracle(_oracle).readSample(_oracleData); emit ReadedOracleBatch(_oracle, count, tokens, equivalent); } paid = new uint256[](count); paidTokens = new uint256[](count); for (uint256 i = 0; i < count; i++) { uint256 tokenAmount = _tokenAmounts[i]; (paid[i], paidTokens[i]) = _pay( _ids[i], _oracle, _oracle != address(0) ? _fromToken(tokenAmount, tokens, equivalent) : tokenAmount, tokens, equivalent ); require(paidTokens[i] <= tokenAmount, "Paid can't exceed requested"); emit Paid({ _id: _ids[i], _sender: msg.sender, _origin: _origin, _requested: 0, _requestedTokens: tokenAmount, _paid: paid[i], _tokens: paidTokens[i] }); } } /** Internal method to pay a loan, during a payment batch context @param _id Pay identifier @param _oracle Address of the Oracle contract, if the loan does not use any oracle, this field should be 0x0. @param _amount Amount to pay, in currency @param _tokens How many tokens @param _equivalent How much currency _tokens equivales @return paid and paidTokens, similar to external pay */ function _pay( bytes32 _id, address _oracle, uint256 _amount, uint256 _tokens, uint256 _equivalent ) internal returns (uint256 paid, uint256 paidToken){ Debt storage debt = debts[_id]; if (_oracle != debt.oracle) { emit PayBatchError( _id, _oracle ); return (0,0); } // Paid only required amount paid = _safePay(_id, debt.model, _amount); require(paid <= _amount, "Paid can't be more than requested"); // Get token amount to use as payment paidToken = _oracle != address(0) ? _toToken(paid, _tokens, _equivalent) : paid; // Pull tokens from payer require(token.transferFrom(msg.sender, address(this), paidToken), "Error pulling payment tokens"); // Add balance to debt uint256 newBalance = paidToken.add(debt.balance); require(newBalance < 340282366920938463463374607431768211456, "uint128 Overflow"); debt.balance = uint128(newBalance); } function _safePay( bytes32 _id, Model _model, uint256 _available ) internal returns (uint256) { require(_model != Model(0), "Debt does not exist"); (bool success, bytes32 paid) = _safeGasCall( address(_model), abi.encodeWithSelector( _model.addPaid.selector, _id, _available ) ); if (success) { if (debts[_id].error) { emit ErrorRecover({ _id: _id, _sender: msg.sender, _value: 0, _gasLeft: gasleft(), _gasLimit: block.gaslimit, _result: paid, _callData: msg.data }); delete debts[_id].error; } return uint256(paid); } else { emit Error({ _id: _id, _sender: msg.sender, _value: msg.value, _gasLeft: gasleft(), _gasLimit: block.gaslimit, _callData: msg.data }); debts[_id].error = true; } } /** Converts an amount in the rate currency to an amount in token @param _amount Amount to convert in rate currency @param _tokens How many tokens @param _equivalent How much currency _tokens equivales @return Amount in tokens */ function _toToken( uint256 _amount, uint256 _tokens, uint256 _equivalent ) internal pure returns (uint256 _result) { require(_tokens != 0 && _equivalent != 0, "Oracle provided invalid rate"); uint256 aux = _tokens.mult(_amount); _result = aux / _equivalent; if (aux % _equivalent > 0) { _result = _result.add(1); } } /** Converts an amount in token to the rate currency @param _amount Amount to convert in token @param _tokens How many tokens @param _equivalent How much currency _tokens equivales @return Amount in rate currency */ function _fromToken( uint256 _amount, uint256 _tokens, uint256 _equivalent ) internal pure returns (uint256) { require(_tokens != 0 && _equivalent != 0, "Oracle provided invalid rate"); return _amount.mult(_equivalent) / _tokens; } function run(bytes32 _id) external returns (bool) { Debt storage debt = debts[_id]; require(debt.model != Model(0), "Debt does not exist"); (bool success, bytes32 result) = _safeGasCall( address(debt.model), abi.encodeWithSelector( debt.model.run.selector, _id ) ); if (success) { if (debt.error) { emit ErrorRecover({ _id: _id, _sender: msg.sender, _value: 0, _gasLeft: gasleft(), _gasLimit: block.gaslimit, _result: result, _callData: msg.data }); delete debt.error; } return result == bytes32(uint256(1)); } else { emit Error({ _id: _id, _sender: msg.sender, _value: 0, _gasLeft: gasleft(), _gasLimit: block.gaslimit, _callData: msg.data }); debt.error = true; } } function withdraw(bytes32 _id, address _to) external returns (uint256 amount) { require(_to != address(0x0), "_to should not be 0x0"); require(_isAuthorized(msg.sender, uint256(_id)), "Sender not authorized"); Debt storage debt = debts[_id]; amount = debt.balance; debt.balance = 0; require(token.transfer(_to, amount), "Error sending tokens"); emit Withdrawn({ _id: _id, _sender: msg.sender, _to: _to, _amount: amount }); } function withdrawPartial(bytes32 _id, address _to, uint256 _amount) external returns (bool success) { require(_to != address(0x0), "_to should not be 0x0"); require(_isAuthorized(msg.sender, uint256(_id)), "Sender not authorized"); Debt storage debt = debts[_id]; require(debt.balance >= _amount, "Debt balance is not enought"); debt.balance = uint128(uint256(debt.balance).sub(_amount)); require(token.transfer(_to, _amount), "Error sending tokens"); emit Withdrawn({ _id: _id, _sender: msg.sender, _to: _to, _amount: _amount }); success = true; } function withdrawBatch(bytes32[] calldata _ids, address _to) external returns (uint256 total) { require(_to != address(0x0), "_to should not be 0x0"); bytes32 target; uint256 balance; for (uint256 i = 0; i < _ids.length; i++) { target = _ids[i]; if (_isAuthorized(msg.sender, uint256(target))) { balance = debts[target].balance; debts[target].balance = 0; total += balance; emit Withdrawn({ _id: target, _sender: msg.sender, _to: _to, _amount: balance }); } } require(token.transfer(_to, total), "Error sending tokens"); } function getStatus(bytes32 _id) external view returns (uint256) { Debt storage debt = debts[_id]; if (debt.error) { return 4; } else { (bool success, uint256 result) = _safeGasStaticCall( address(debt.model), abi.encodeWithSelector( debt.model.getStatus.selector, _id ) ); return success ? result : 4; } } function _safeGasStaticCall( address _contract, bytes memory _data ) internal view returns (bool success, uint256 result) { bytes memory returnData; uint256 _gas = (block.gaslimit * 80) / 100; (success, returnData) = _contract.staticcall.gas(gasleft() < _gas ? gasleft() : _gas)(_data); if (returnData.length > 0) result = abi.decode(returnData, (uint256)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), * relaxing the requirement on the return value * @param _contract The contract that receives the call * @param _data The call data * @return True if the call not reverts and the result of the call */ function _safeGasCall( address _contract, bytes memory _data ) internal returns (bool success, bytes32 result) { bytes memory returnData; uint256 _gas = (block.gaslimit * 80) / 100; (success, returnData) = _contract.call.gas(gasleft() < _gas ? gasleft() : _gas)(_data); if (returnData.length > 0) result = abi.decode(returnData, (bytes32)); } } // File: contracts/core/diaspore/interfaces/LoanApprover.sol pragma solidity ^0.5.11; /** A contract implementing LoanApprover is able to approve loan requests using callbacks, to approve a loan the contract should respond the callbacks the result of one designated value XOR keccak256("approve-loan-request") keccak256("approve-loan-request"): 0xdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a To receive calls on the callbacks, the contract should also implement the following ERC165 interfaces: approveRequest: 0x76ba6009 settleApproveRequest: 0xcd40239e LoanApprover: 0xbbfa4397 */ contract LoanApprover is IERC165 { /** Request the approve of a loan created using requestLoan, if the borrower is this contract, to approve the request the contract should return: _futureDebt XOR 0xdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a @param _futureDebt ID of the loan to approve @return _futureDebt XOR keccak256("approve-loan-request"), if the approve is accepted */ function approveRequest(bytes32 _futureDebt) external returns (bytes32); /** Request the approve of a loan being settled, the contract can be called as borrower or creator. To approve the request the contract should return: _id XOR 0xdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a @param _requestData All the parameters of the loan request @param _loanData Data to feed to the Model @param _isBorrower True if this contract is the borrower, False if the contract is the creator @param _id loanManager.requestSignature(_requestDatam _loanData) @return _id XOR keccak256("approve-loan-request"), if the approve is accepted */ function settleApproveRequest( bytes calldata _requestData, bytes calldata _loanData, bool _isBorrower, uint256 _id ) external returns (bytes32); } // File: contracts/core/diaspore/interfaces/LoanCallback.sol pragma solidity ^0.5.11; interface LoanCallback { function scheme() external view returns (string memory); function onLent( bytes32 _id, address _lender, bytes calldata _data ) external returns (bool); function acceptsLoan( address _engine, bytes32 _id, address _lender, bytes calldata _data ) external view returns (bool); } // File: contracts/interfaces/Cosigner.sol pragma solidity ^0.5.11; /** @dev Defines the interface of a standard RCN cosigner. The cosigner is an agent that gives an insurance to the lender in the event of a defaulted loan, the confitions of the insurance and the cost of the given are defined by the cosigner. The lender will decide what cosigner to use, if any; the address of the cosigner and the valid data provided by the agent should be passed as params when the lender calls the "lend" method on the engine. When the default conditions defined by the cosigner aligns with the status of the loan, the lender of the engine should be able to call the "claim" method to receive the benefit; the cosigner can define aditional requirements to call this method, like the transfer of the ownership of the loan. */ contract Cosigner { uint256 public constant VERSION = 2; /** @return the url of the endpoint that exposes the insurance offers. */ function url() public view returns (string memory); /** @dev Retrieves the cost of a given insurance, this amount should be exact. @return the cost of the cosign, in RCN wei */ function cost( address engine, uint256 index, bytes memory data, bytes memory oracleData ) public view returns (uint256); /** @dev The engine calls this method for confirmation of the conditions, if the cosigner accepts the liability of the insurance it must call the method "cosign" of the engine. If the cosigner does not call that method, or does not return true to this method, the operation fails. @return true if the cosigner accepts the liability */ function requestCosign( address engine, uint256 index, bytes memory data, bytes memory oracleData ) public returns (bool); /** @dev Claims the benefit of the insurance if the loan is defaulted, this method should be only calleable by the current lender of the loan. @return true if the claim was done correctly. */ function claim(address engine, uint256 index, bytes memory oracleData) public returns (bool); } // File: contracts/utils/ImplementsInterface.sol pragma solidity ^0.5.11; library ImplementsInterface { bytes4 constant InvalidID = 0xffffffff; bytes4 constant ERC165ID = 0x01ffc9a7; function implementsMethod(address _contract, bytes4 _interfaceId) internal view returns (bool) { (uint256 success, uint256 result) = _noThrowImplements(_contract, ERC165ID); if ((success==0)||(result==0)) { return false; } (success, result) = _noThrowImplements(_contract, InvalidID); if ((success==0)||(result!=0)) { return false; } (success, result) = _noThrowImplements(_contract, _interfaceId); if ((success==1)&&(result==1)) { return true; } return false; } function _noThrowImplements( address _contract, bytes4 _interfaceId ) private view returns (uint256 success, uint256 result) { bytes4 erc165ID = ERC165ID; assembly { let x := mload(0x40) // Find empty storage location using "free memory pointer" mstore(x, erc165ID) // Place signature at begining of empty storage mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature success := staticcall( 30000, // 30k gas _contract, // To addr x, // Inputs are stored at location x 0x24, // Inputs are 32 bytes long x, // Store output over input (saves space) 0x20) // Outputs are 32 bytes long result := mload(x) // Load the result } } } // File: contracts/utils/BytesUtils.sol pragma solidity ^0.5.11; contract BytesUtils { function readBytes32(bytes memory data, uint256 index) internal pure returns (bytes32 o) { require(data.length / 32 > index, "Reading bytes out of bounds"); assembly { o := mload(add(data, add(32, mul(32, index)))) } } function read(bytes memory data, uint256 offset, uint256 length) internal pure returns (bytes32 o) { require(data.length >= offset + length, "Reading bytes out of bounds"); assembly { o := mload(add(data, add(32, offset))) let lb := sub(32, length) if lb { o := div(o, exp(2, mul(lb, 8))) } } } function decode( bytes memory _data, uint256 _la ) internal pure returns (bytes32 _a) { require(_data.length >= _la, "Reading bytes out of bounds"); assembly { _a := mload(add(_data, 32)) let l := sub(32, _la) if l { _a := div(_a, exp(2, mul(l, 8))) } } } function decode( bytes memory _data, uint256 _la, uint256 _lb ) internal pure returns (bytes32 _a, bytes32 _b) { uint256 o; assembly { let s := add(_data, 32) _a := mload(s) let l := sub(32, _la) if l { _a := div(_a, exp(2, mul(l, 8))) } o := add(s, _la) _b := mload(o) l := sub(32, _lb) if l { _b := div(_b, exp(2, mul(l, 8))) } o := sub(o, s) } require(_data.length >= o, "Reading bytes out of bounds"); } function decode( bytes memory _data, uint256 _la, uint256 _lb, uint256 _lc ) internal pure returns (bytes32 _a, bytes32 _b, bytes32 _c) { uint256 o; assembly { let s := add(_data, 32) _a := mload(s) let l := sub(32, _la) if l { _a := div(_a, exp(2, mul(l, 8))) } o := add(s, _la) _b := mload(o) l := sub(32, _lb) if l { _b := div(_b, exp(2, mul(l, 8))) } o := add(o, _lb) _c := mload(o) l := sub(32, _lc) if l { _c := div(_c, exp(2, mul(l, 8))) } o := sub(o, s) } require(_data.length >= o, "Reading bytes out of bounds"); } function decode( bytes memory _data, uint256 _la, uint256 _lb, uint256 _lc, uint256 _ld ) internal pure returns (bytes32 _a, bytes32 _b, bytes32 _c, bytes32 _d) { uint256 o; assembly { let s := add(_data, 32) _a := mload(s) let l := sub(32, _la) if l { _a := div(_a, exp(2, mul(l, 8))) } o := add(s, _la) _b := mload(o) l := sub(32, _lb) if l { _b := div(_b, exp(2, mul(l, 8))) } o := add(o, _lb) _c := mload(o) l := sub(32, _lc) if l { _c := div(_c, exp(2, mul(l, 8))) } o := add(o, _lc) _d := mload(o) l := sub(32, _ld) if l { _d := div(_d, exp(2, mul(l, 8))) } o := sub(o, s) } require(_data.length >= o, "Reading bytes out of bounds"); } function decode( bytes memory _data, uint256 _la, uint256 _lb, uint256 _lc, uint256 _ld, uint256 _le ) internal pure returns (bytes32 _a, bytes32 _b, bytes32 _c, bytes32 _d, bytes32 _e) { uint256 o; assembly { let s := add(_data, 32) _a := mload(s) let l := sub(32, _la) if l { _a := div(_a, exp(2, mul(l, 8))) } o := add(s, _la) _b := mload(o) l := sub(32, _lb) if l { _b := div(_b, exp(2, mul(l, 8))) } o := add(o, _lb) _c := mload(o) l := sub(32, _lc) if l { _c := div(_c, exp(2, mul(l, 8))) } o := add(o, _lc) _d := mload(o) l := sub(32, _ld) if l { _d := div(_d, exp(2, mul(l, 8))) } o := add(o, _ld) _e := mload(o) l := sub(32, _le) if l { _e := div(_e, exp(2, mul(l, 8))) } o := sub(o, s) } require(_data.length >= o, "Reading bytes out of bounds"); } function decode( bytes memory _data, uint256 _la, uint256 _lb, uint256 _lc, uint256 _ld, uint256 _le, uint256 _lf ) internal pure returns ( bytes32 _a, bytes32 _b, bytes32 _c, bytes32 _d, bytes32 _e, bytes32 _f ) { uint256 o; assembly { let s := add(_data, 32) _a := mload(s) let l := sub(32, _la) if l { _a := div(_a, exp(2, mul(l, 8))) } o := add(s, _la) _b := mload(o) l := sub(32, _lb) if l { _b := div(_b, exp(2, mul(l, 8))) } o := add(o, _lb) _c := mload(o) l := sub(32, _lc) if l { _c := div(_c, exp(2, mul(l, 8))) } o := add(o, _lc) _d := mload(o) l := sub(32, _ld) if l { _d := div(_d, exp(2, mul(l, 8))) } o := add(o, _ld) _e := mload(o) l := sub(32, _le) if l { _e := div(_e, exp(2, mul(l, 8))) } o := add(o, _le) _f := mload(o) l := sub(32, _lf) if l { _f := div(_f, exp(2, mul(l, 8))) } o := sub(o, s) } require(_data.length >= o, "Reading bytes out of bounds"); } } // File: contracts/core/diaspore/LoanManager.sol pragma solidity ^0.5.11; contract LoanManager is BytesUtils { using ImplementsInterface for address; using IsContract for address; using SafeMath for uint256; uint256 public constant GAS_CALLBACK = 300000; DebtEngine public debtEngine; IERC20 public token; mapping(bytes32 => Request) public requests; mapping(bytes32 => bool) public canceledSettles; event Requested( bytes32 indexed _id, uint128 _amount, address _model, address _creator, address _oracle, address _borrower, address _callback, uint256 _salt, bytes _loanData, uint256 _expiration ); event Approved(bytes32 indexed _id); event Lent(bytes32 indexed _id, address _lender, uint256 _tokens); event Cosigned(bytes32 indexed _id, address _cosigner, uint256 _cost); event Canceled(bytes32 indexed _id, address _canceler); event ReadedOracle(address _oracle, uint256 _tokens, uint256 _equivalent); event ApprovedRejected(bytes32 indexed _id, bytes32 _response); event ApprovedError(bytes32 indexed _id, bytes32 _response); event ApprovedByCallback(bytes32 indexed _id); event ApprovedBySignature(bytes32 indexed _id); event CreatorByCallback(bytes32 indexed _id); event BorrowerByCallback(bytes32 indexed _id); event CreatorBySignature(bytes32 indexed _id); event BorrowerBySignature(bytes32 indexed _id); event SettledLend(bytes32 indexed _id, address _lender, uint256 _tokens); event SettledCancel(bytes32 indexed _id, address _canceler); constructor(DebtEngine _debtEngine) public { debtEngine = _debtEngine; token = debtEngine.token(); require(address(token) != address(0), "Error loading token"); } // uint256 getters(legacy) function getBorrower(uint256 _id) external view returns (address) { return requests[bytes32(_id)].borrower; } function getCreator(uint256 _id) external view returns (address) { return requests[bytes32(_id)].creator; } function getOracle(uint256 _id) external view returns (address) { return requests[bytes32(_id)].oracle; } function getCosigner(uint256 _id) external view returns (address) { return requests[bytes32(_id)].cosigner; } function getCurrency(uint256 _id) external view returns (bytes32) { address oracle = requests[bytes32(_id)].oracle; return oracle == address(0) ? bytes32(0x0) : RateOracle(oracle).currency(); } function getAmount(uint256 _id) external view returns (uint256) { return requests[bytes32(_id)].amount; } function getExpirationRequest(uint256 _id) external view returns (uint256) { return requests[bytes32(_id)].expiration; } function getApproved(uint256 _id) external view returns (bool) { return requests[bytes32(_id)].approved; } function getDueTime(uint256 _id) external view returns (uint256) { return Model(requests[bytes32(_id)].model).getDueTime(bytes32(_id)); } function getClosingObligation(uint256 _id) external view returns (uint256) { return Model(requests[bytes32(_id)].model).getClosingObligation(bytes32(_id)); } function getLoanData(uint256 _id) external view returns (bytes memory) { return requests[bytes32(_id)].loanData; } function getStatus(uint256 _id) external view returns (uint256) { Request storage request = requests[bytes32(_id)]; return request.open ? 0 : debtEngine.getStatus(bytes32(_id)); } function ownerOf(uint256 _id) external view returns (address) { return debtEngine.ownerOf(_id); } // bytes32 getters function getBorrower(bytes32 _id) external view returns (address) { return requests[_id].borrower; } function getCreator(bytes32 _id) external view returns (address) { return requests[_id].creator; } function getOracle(bytes32 _id) external view returns (address) { return requests[_id].oracle; } function getCosigner(bytes32 _id) external view returns (address) { return requests[_id].cosigner; } function getCurrency(bytes32 _id) external view returns (bytes32) { address oracle = requests[_id].oracle; return oracle == address(0) ? bytes32(0x0) : RateOracle(oracle).currency(); } function getAmount(bytes32 _id) external view returns (uint256) { return requests[_id].amount; } function getExpirationRequest(bytes32 _id) external view returns (uint256) { return requests[_id].expiration; } function getApproved(bytes32 _id) external view returns (bool) { return requests[_id].approved; } function getDueTime(bytes32 _id) external view returns (uint256) { return Model(requests[_id].model).getDueTime(bytes32(_id)); } function getClosingObligation(bytes32 _id) external view returns (uint256) { return Model(requests[_id].model).getClosingObligation(bytes32(_id)); } function getLoanData(bytes32 _id) external view returns (bytes memory) { return requests[_id].loanData; } function getStatus(bytes32 _id) external view returns (uint256) { Request storage request = requests[_id]; return request.open ? 0 : debtEngine.getStatus(bytes32(_id)); } function ownerOf(bytes32 _id) external view returns (address) { return debtEngine.ownerOf(uint256(_id)); } function getCallback(bytes32 _id) external view returns (address) { return requests[_id].callback; } struct Request { bool open; bool approved; uint64 expiration; uint128 amount; address cosigner; address model; address creator; address oracle; address borrower; address callback; uint256 salt; bytes loanData; } function calcId( uint128 _amount, address _borrower, address _creator, address _model, address _oracle, address _callback, uint256 _salt, uint64 _expiration, bytes memory _data ) public view returns (bytes32) { uint256 internalSalt = _buildInternalSalt( _amount, _borrower, _creator, _callback, _salt, _expiration ); return keccak256( abi.encodePacked( uint8(2), debtEngine, address(this), _model, _oracle, internalSalt, _data ) ); } function buildInternalSalt( uint128 _amount, address _borrower, address _creator, address _callback, uint256 _salt, uint64 _expiration ) external pure returns (uint256) { return _buildInternalSalt( _amount, _borrower, _creator, _callback, _salt, _expiration ); } function internalSalt(bytes32 _id) external view returns (uint256) { Request storage request = requests[_id]; require(request.borrower != address(0), "Request does not exist"); return _internalSalt(request); } function _internalSalt(Request memory _request) internal view returns (uint256) { return _buildInternalSalt( _request.amount, _request.borrower, _request.creator, _request.callback, _request.salt, _request.expiration ); } function requestLoan( uint128 _amount, address _model, address _oracle, address _borrower, address _callback, uint256 _salt, uint64 _expiration, bytes calldata _loanData ) external returns (bytes32 id) { require(_borrower != address(0), "The request should have a borrower"); require(Model(_model).validate(_loanData), "The loan data is not valid"); id = calcId( _amount, _borrower, msg.sender, _model, _oracle, _callback, _salt, _expiration, _loanData ); require(!canceledSettles[id], "The debt was canceled"); require(requests[id].borrower == address(0), "Request already exist"); bool approved = msg.sender == _borrower; requests[id] = Request({ open: true, approved: approved, cosigner: address(0), amount: _amount, model: _model, creator: msg.sender, oracle: _oracle, borrower: _borrower, callback: _callback, salt: _salt, loanData: _loanData, expiration: _expiration }); emit Requested( id, _amount, _model, msg.sender, _oracle, _borrower, _callback, _salt, _loanData, _expiration ); if (!approved) { // implements: 0x76ba6009 = approveRequest(bytes32) if (_borrower.isContract() && _borrower.implementsMethod(0x76ba6009)) { approved = _requestContractApprove(id, _borrower); requests[id].approved = approved; } } if (approved) { emit Approved(id); } } function _requestContractApprove( bytes32 _id, address _borrower ) internal returns (bool approved) { // bytes32 expected = _id XOR keccak256("approve-loan-request"); bytes32 expected = _id ^ 0xdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a; (bool success, bytes32 result) = _safeCall( _borrower, abi.encodeWithSelector( 0x76ba6009, _id ) ); approved = success && result == expected; // Emit events if approve was rejected or failed if (approved) { emit ApprovedByCallback(_id); } else { if (!success) { emit ApprovedError(_id, result); } else { emit ApprovedRejected(_id, result); } } } function approveRequest( bytes32 _id ) external returns (bool) { Request storage request = requests[_id]; require(msg.sender == request.borrower, "Only borrower can approve"); if (!request.approved) { request.approved = true; emit Approved(_id); } return true; } function registerApproveRequest( bytes32 _id, bytes calldata _signature ) external returns (bool approved) { Request storage request = requests[_id]; address borrower = request.borrower; if (!request.approved) { if (borrower.isContract() && borrower.implementsMethod(0x76ba6009)) { approved = _requestContractApprove(_id, borrower); } else { bytes32 _hash = keccak256( abi.encodePacked( _id, "sign approve request" ) ); address signer = ecrecovery( keccak256( abi.encodePacked( "\x19Ethereum Signed Message:\n32", _hash ) ), _signature ); if (borrower == signer) { emit ApprovedBySignature(_id); approved = true; } } } // Check request.approved again, protect against reentrancy if (approved && !request.approved) { request.approved = true; emit Approved(_id); } } function lend( bytes32 _id, bytes memory _oracleData, address _cosigner, uint256 _cosignerLimit, bytes memory _cosignerData, bytes memory _callbackData ) public returns (bool) { Request storage request = requests[_id]; require(request.open, "Request is no longer open"); require(request.approved, "The request is not approved by the borrower"); require(request.expiration > now, "The request is expired"); request.open = false; uint256 tokens = _currencyToToken(request.oracle, request.amount, _oracleData); require( token.transferFrom( msg.sender, request.borrower, tokens ), "Error sending tokens to borrower" ); emit Lent(_id, msg.sender, tokens); // Generate the debt require( debtEngine.create2( Model(request.model), msg.sender, request.oracle, _internalSalt(request), request.loanData ) == _id, "Error creating the debt" ); // Call the cosigner if (_cosigner != address(0)) { uint256 auxSalt = request.salt; request.cosigner = address(uint256(_cosigner) + 2); request.salt = _cosignerLimit; // Risky ? require( Cosigner(_cosigner).requestCosign( address(this), uint256(_id), _cosignerData, _oracleData ), "Cosign method returned false" ); require(request.cosigner == _cosigner, "Cosigner didn't callback"); request.salt = auxSalt; } // Call the loan callback address callback = request.callback; if (callback != address(0)) { require(LoanCallback(callback).onLent.gas(GAS_CALLBACK)(_id, msg.sender, _callbackData), "Rejected by loan callback"); } return true; } function cancel(bytes32 _id) external returns (bool) { Request storage request = requests[_id]; require(request.open, "Request is no longer open or not requested"); require( request.creator == msg.sender || request.borrower == msg.sender, "Only borrower or creator can cancel a request" ); delete request.loanData; delete requests[_id]; canceledSettles[_id] = true; emit Canceled(_id, msg.sender); return true; } function cosign(uint256 _id, uint256 _cost) external returns (bool) { Request storage request = requests[bytes32(_id)]; require(request.cosigner != address(0), "Cosigner 0x0 is not valid"); require(request.expiration > now, "Request is expired"); require(request.cosigner == address(uint256(msg.sender) + 2), "Cosigner not valid"); request.cosigner = msg.sender; if (_cost != 0){ require(request.salt >= _cost, "Cosigner cost exceeded"); require(token.transferFrom(debtEngine.ownerOf(_id), msg.sender, _cost), "Error paying cosigner"); } emit Cosigned(bytes32(_id), msg.sender, _cost); return true; } // /// // Offline requests // /// uint256 private constant L_AMOUNT = 16; uint256 private constant O_AMOUNT = 0; uint256 private constant O_MODEL = L_AMOUNT; uint256 private constant L_MODEL = 20; uint256 private constant O_ORACLE = O_MODEL + L_MODEL; uint256 private constant L_ORACLE = 20; uint256 private constant O_BORROWER = O_ORACLE + L_ORACLE; uint256 private constant L_BORROWER = 20; uint256 private constant O_SALT = O_BORROWER + L_BORROWER; uint256 private constant L_SALT = 32; uint256 private constant O_EXPIRATION = O_SALT + L_SALT; uint256 private constant L_EXPIRATION = 8; uint256 private constant O_CREATOR = O_EXPIRATION + L_EXPIRATION; uint256 private constant L_CREATOR = 20; uint256 private constant O_CALLBACK = O_CREATOR + L_CREATOR; uint256 private constant L_CALLBACK = 20; function encodeRequest( uint128 _amount, address _model, address _oracle, address _borrower, address _callback, uint256 _salt, uint64 _expiration, address _creator, bytes calldata _loanData ) external view returns (bytes memory requestData, bytes32 id) { requestData = abi.encodePacked( _amount, _model, _oracle, _borrower, _salt, _expiration, _creator, _callback ); uint256 innerSalt = _buildInternalSalt( _amount, _borrower, _creator, _callback, _salt, _expiration ); id = debtEngine.buildId2( address(this), _model, _oracle, innerSalt, _loanData ); } function settleLend( bytes memory _requestData, bytes memory _loanData, address _cosigner, uint256 _maxCosignerCost, bytes memory _cosignerData, bytes memory _oracleData, bytes memory _creatorSig, bytes memory _borrowerSig, bytes memory _callbackData ) public returns (bytes32 id) { // Validate request require(uint256(read(_requestData, O_EXPIRATION, L_EXPIRATION)) > now, "Loan request is expired"); // Get id uint256 innerSalt; (id, innerSalt) = _buildSettleId(_requestData, _loanData); require(requests[id].borrower == address(0), "Request already exist"); // Transfer tokens to borrower uint256 tokens = _currencyToToken(_requestData, _oracleData); require( token.transferFrom( msg.sender, address(uint256(read(_requestData, O_BORROWER, L_BORROWER))), tokens ), "Error sending tokens to borrower" ); // Generate the debt require( _createDebt( _requestData, _loanData, innerSalt ) == id, "Error creating debt registry" ); emit SettledLend(id, msg.sender, tokens); // Save the request info requests[id] = Request({ open: false, approved: true, cosigner: _cosigner, amount: uint128(uint256(read(_requestData, O_AMOUNT, L_AMOUNT))), model: address(uint256(read(_requestData, O_MODEL, L_MODEL))), creator: address(uint256(read(_requestData, O_CREATOR, L_CREATOR))), oracle: address(uint256(read(_requestData, O_ORACLE, L_ORACLE))), borrower: address(uint256(read(_requestData, O_BORROWER, L_BORROWER))), callback: address(uint256(read(_requestData, O_CALLBACK, L_CALLBACK))), salt: _cosigner != address(0) ? _maxCosignerCost : uint256(read(_requestData, O_SALT, L_SALT)), loanData: _loanData, expiration: uint64(uint256(read(_requestData, O_EXPIRATION, L_EXPIRATION))) }); Request storage request = requests[id]; // Validate signatures _validateSettleSignatures(id, _requestData, _loanData, _creatorSig, _borrowerSig); // Call the cosigner if (_cosigner != address(0)) { request.cosigner = address(uint256(_cosigner) + 2); require(Cosigner(_cosigner).requestCosign(address(this), uint256(id), _cosignerData, _oracleData), "Cosign method returned false"); require(request.cosigner == _cosigner, "Cosigner didn't callback"); request.salt = uint256(read(_requestData, O_SALT, L_SALT)); } // Call the loan callback address callback = address(uint256(read(_requestData, O_CALLBACK, L_CALLBACK))); if (callback != address(0)) { require(LoanCallback(callback).onLent.gas(GAS_CALLBACK)(id, msg.sender, _callbackData), "Rejected by loan callback"); } } function settleCancel( bytes calldata _requestData, bytes calldata _loanData ) external returns (bool) { (bytes32 id, ) = _buildSettleId(_requestData, _loanData); require( msg.sender == address(uint256(read(_requestData, O_BORROWER, L_BORROWER))) || msg.sender == address(uint256(read(_requestData, O_CREATOR, L_CREATOR))), "Only borrower or creator can cancel a settle" ); canceledSettles[id] = true; emit SettledCancel(id, msg.sender); return true; } function _validateSettleSignatures( bytes32 _id, bytes memory _requestData, bytes memory _loanData, bytes memory _creatorSig, bytes memory _borrowerSig ) internal { require(!canceledSettles[_id], "Settle was canceled"); // bytes32 expected = uint256(_id) XOR keccak256("approve-loan-request"); bytes32 expected = _id ^ 0xdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a; address borrower = address(uint256(read(_requestData, O_BORROWER, L_BORROWER))); address creator = address(uint256(read(_requestData, O_CREATOR, L_CREATOR))); bytes32 _hash; if (borrower.isContract()) { require( LoanApprover(borrower).settleApproveRequest(_requestData, _loanData, true, uint256(_id)) == expected, "Borrower contract rejected the loan" ); emit BorrowerByCallback(_id); } else { _hash = keccak256( abi.encodePacked( _id, "sign settle lend as borrower" ) ); require( borrower == ecrecovery(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)), _borrowerSig), "Invalid borrower signature" ); emit BorrowerBySignature(_id); } if (borrower != creator) { if (creator.isContract()) { require( LoanApprover(creator).settleApproveRequest(_requestData, _loanData, false, uint256(_id)) == expected, "Creator contract rejected the loan" ); emit CreatorByCallback(_id); } else { _hash = keccak256( abi.encodePacked( _id, "sign settle lend as creator" ) ); require( creator == ecrecovery(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)), _creatorSig), "Invalid creator signature" ); emit CreatorBySignature(_id); } } } function _currencyToToken( bytes memory _requestData, bytes memory _oracleData ) internal returns (uint256) { return _currencyToToken( address(uint256(read(_requestData, O_ORACLE, L_ORACLE))), uint256(read(_requestData, O_AMOUNT, L_AMOUNT)), _oracleData ); } function _createDebt( bytes memory _requestData, bytes memory _loanData, uint256 _innerSalt ) internal returns (bytes32) { return debtEngine.create2( Model(address(uint256(read(_requestData, O_MODEL, L_MODEL)))), msg.sender, address(uint256(read(_requestData, O_ORACLE, L_ORACLE))), _innerSalt, _loanData ); } function _buildSettleId( bytes memory _requestData, bytes memory _loanData ) internal view returns (bytes32 id, uint256 innerSalt) { ( uint128 amount, address model, address oracle, address borrower, uint256 salt, uint64 expiration, address creator ) = _decodeSettle(_requestData); innerSalt = _buildInternalSalt( amount, borrower, creator, address(uint256(read(_requestData, O_CALLBACK, L_CALLBACK))), salt, expiration ); id = debtEngine.buildId2( address(this), model, oracle, innerSalt, _loanData ); } function _buildInternalSalt( uint128 _amount, address _borrower, address _creator, address _callback, uint256 _salt, uint64 _expiration ) internal pure returns (uint256) { return uint256( keccak256( abi.encodePacked( _amount, _borrower, _creator, _callback, _salt, _expiration ) ) ); } function _decodeSettle( bytes memory _data ) internal pure returns ( uint128 amount, address model, address oracle, address borrower, uint256 salt, uint64 expiration, address creator ) { ( bytes32 _amount, bytes32 _model, bytes32 _oracle, bytes32 _borrower, bytes32 _salt, bytes32 _expiration ) = decode(_data, L_AMOUNT, L_MODEL, L_ORACLE, L_BORROWER, L_SALT, L_EXPIRATION); amount = uint128(uint256(_amount)); model = address(uint256(_model)); oracle = address(uint256(_oracle)); borrower = address(uint256(_borrower)); salt = uint256(_salt); expiration = uint64(uint256(_expiration)); creator = address(uint256(read(_data, O_CREATOR, L_CREATOR))); } function ecrecovery(bytes32 _hash, bytes memory _sig) internal pure returns (address) { bytes32 r; bytes32 s; uint8 v; assembly { r := mload(add(_sig, 32)) s := mload(add(_sig, 64)) v := and(mload(add(_sig, 65)), 255) } if (v < 27) { v += 27; } return ecrecover(_hash, v, r, s); } function _currencyToToken( address _oracle, uint256 _amount, bytes memory _oracleData ) internal returns (uint256) { if (_oracle == address(0)) return _amount; (uint256 tokens, uint256 equivalent) = RateOracle(_oracle).readSample(_oracleData); emit ReadedOracle(_oracle, tokens, equivalent); return tokens.mult(_amount) / equivalent; } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), * relaxing the requirement on the return value * @param _contract The borrower contract that receives the approveRequest(bytes32) call * @param _data The call data * @return True if the call not reverts and the result of the call */ function _safeCall( address _contract, bytes memory _data ) internal returns (bool success, bytes32 result) { bytes memory returnData; (success, returnData) = _contract.call(_data); if (returnData.length > 0) result = abi.decode(returnData, (bytes32)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getCreator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint128","name":"_amount","type":"uint128"},{"internalType":"address","name":"_model","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_callback","type":"address"},{"internalType":"uint256","name":"_salt","type":"uint256"},{"internalType":"uint64","name":"_expiration","type":"uint64"},{"internalType":"bytes","name":"_loanData","type":"bytes"}],"name":"requestLoan","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_requestData","type":"bytes"},{"internalType":"bytes","name":"_loanData","type":"bytes"},{"internalType":"address","name":"_cosigner","type":"address"},{"internalType":"uint256","name":"_maxCosignerCost","type":"uint256"},{"internalType":"bytes","name":"_cosignerData","type":"bytes"},{"internalType":"bytes","name":"_oracleData","type":"bytes"},{"internalType":"bytes","name":"_creatorSig","type":"bytes"},{"internalType":"bytes","name":"_borrowerSig","type":"bytes"},{"internalType":"bytes","name":"_callbackData","type":"bytes"}],"name":"settleLend","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getClosingObligation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_requestData","type":"bytes"},{"internalType":"bytes","name":"_loanData","type":"bytes"}],"name":"settleCancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getDueTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint128","name":"_amount","type":"uint128"},{"internalType":"address","name":"_model","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_callback","type":"address"},{"internalType":"uint256","name":"_salt","type":"uint256"},{"internalType":"uint64","name":"_expiration","type":"uint64"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"bytes","name":"_loanData","type":"bytes"}],"name":"encodeRequest","outputs":[{"internalType":"bytes","name":"requestData","type":"bytes"},{"internalType":"bytes32","name":"id","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"internalSalt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getCallback","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getLoanData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint128","name":"_amount","type":"uint128"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"address","name":"_model","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_callback","type":"address"},{"internalType":"uint256","name":"_salt","type":"uint256"},{"internalType":"uint64","name":"_expiration","type":"uint64"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"calcId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"cosign","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getBorrower","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"approveRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"debtEngine","outputs":[{"internalType":"contract DebtEngine","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getBorrower","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"registerApproveRequest","outputs":[{"internalType":"bool","name":"approved","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getCosigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getClosingObligation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requests","outputs":[{"internalType":"bool","name":"open","type":"bool"},{"internalType":"bool","name":"approved","type":"bool"},{"internalType":"uint64","name":"expiration","type":"uint64"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"address","name":"cosigner","type":"address"},{"internalType":"address","name":"model","type":"address"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"loanData","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getCosigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"GAS_CALLBACK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"canceledSettles","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"cancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getLoanData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getExpirationRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getDueTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getCurrency","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getCurrency","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getCreator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"bytes","name":"_oracleData","type":"bytes"},{"internalType":"address","name":"_cosigner","type":"address"},{"internalType":"uint256","name":"_cosignerLimit","type":"uint256"},{"internalType":"bytes","name":"_cosignerData","type":"bytes"},{"internalType":"bytes","name":"_callbackData","type":"bytes"}],"name":"lend","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint128","name":"_amount","type":"uint128"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"address","name":"_callback","type":"address"},{"internalType":"uint256","name":"_salt","type":"uint256"},{"internalType":"uint64","name":"_expiration","type":"uint64"}],"name":"buildInternalSalt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getExpirationRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract DebtEngine","name":"_debtEngine","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"_amount","type":"uint128"},{"indexed":false,"internalType":"address","name":"_model","type":"address"},{"indexed":false,"internalType":"address","name":"_creator","type":"address"},{"indexed":false,"internalType":"address","name":"_oracle","type":"address"},{"indexed":false,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"address","name":"_callback","type":"address"},{"indexed":false,"internalType":"uint256","name":"_salt","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_loanData","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"_expiration","type":"uint256"}],"name":"Requested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"Approved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_lender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"Lent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_cosigner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"Cosigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_canceler","type":"address"}],"name":"Canceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oracle","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_equivalent","type":"uint256"}],"name":"ReadedOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_response","type":"bytes32"}],"name":"ApprovedRejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_response","type":"bytes32"}],"name":"ApprovedError","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"ApprovedByCallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"ApprovedBySignature","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"CreatorByCallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"BorrowerByCallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"CreatorBySignature","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"BorrowerBySignature","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_lender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"SettledLend","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_canceler","type":"address"}],"name":"SettledCancel","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620051b3380380620051b3833981810160405260208110156200003757600080fd5b5051600080546001600160a01b0319166001600160a01b038084169190911791829055604080517ffc0c546a0000000000000000000000000000000000000000000000000000000081529051929091169163fc0c546a91600480820192602092909190829003018186803b158015620000af57600080fd5b505afa158015620000c4573d6000803e3d6000fd5b505050506040513d6020811015620000db57600080fd5b5051600180546001600160a01b0319166001600160a01b039283161790819055166200016857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4572726f72206c6f6164696e6720746f6b656e00000000000000000000000000604482015290519081900360640190fd5b5061503a80620001796000396000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80638500d91911610151578063c955bde2116100c3578063dafaf94a11610087578063dafaf94a14610312578063db97eb4414610e8d578063e3bab7ce14611057578063e6c8fcf114610e53578063ef270ee2146102b2578063fc0c546a146110b257610274565b8063c955bde214610e53578063cdd8750e1461089d578063cdf9b77e14610e70578063d383b80d14610e70578063d48e638a1461027957610274565b80639d866985116101155780639d86698514610cf7578063a56d9dda14610cda578063a9f649e814610e11578063abf6ac0914610e19578063c4d252f514610e36578063c4d2b1b314610a5457610274565b80638500d91914610c2357806390cd0d0614610c65578063964f61f914610cda5780639980ec86146102e35780639a6203e9146107c257610274565b80635de28ae0116101ea5780636352211e116101ae5780636352211e14610be35780636394536d14610c00578063728c3ea214610c2357806376ba600914610c405780637cdef83c14610c5d5780637dd5641114610be357610274565b80635de28ae0146108ba5780635f7cfe4914610a1a5780636135a0ad14610a37578063622fe39f14610a54578063629d2f3414610ae657610274565b8063385584bf1161023c578063385584bf146103ea57806351cbb299146107c25780635900477a146107df578063593570451461089d5780635c622a0e146108ba5780635d9c4afe146108d757610274565b8063060a7ef114610279578063081812fc146102b25780630e0a0d74146102e357806310a9de6014610312578063167d76031461032f575b600080fd5b6102966004803603602081101561028f57600080fd5b50356110ba565b604080516001600160a01b039092168252519081900360200190f35b6102cf600480360360208110156102c857600080fd5b50356110d8565b604080519115158252519081900360200190f35b610300600480360360208110156102f957600080fd5b50356110f2565b60408051918252519081900360200190f35b6102966004803603602081101561032857600080fd5b5035611114565b610300600480360361010081101561034657600080fd5b6001600160801b03823516916001600160a01b036020820135811692604083013582169260608101358316926080820135169160a0820135916001600160401b0360c08201351691810190610100810160e0820135600160201b8111156103ac57600080fd5b8201836020820111156103be57600080fd5b803590602001918460018302840111600160201b831117156103df57600080fd5b509092509050611132565b610300600480360361012081101561040157600080fd5b810190602081018135600160201b81111561041b57600080fd5b82018360208201111561042d57600080fd5b803590602001918460018302840111600160201b8311171561044e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104a057600080fd5b8201836020820111156104b257600080fd5b803590602001918460018302840111600160201b831117156104d357600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092956001600160a01b0385351695602086013595919450925060608101915060400135600160201b81111561053a57600080fd5b82018360208201111561054c57600080fd5b803590602001918460018302840111600160201b8311171561056d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156105bf57600080fd5b8201836020820111156105d157600080fd5b803590602001918460018302840111600160201b831117156105f257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561064457600080fd5b82018360208201111561065657600080fd5b803590602001918460018302840111600160201b8311171561067757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156106c957600080fd5b8201836020820111156106db57600080fd5b803590602001918460018302840111600160201b831117156106fc57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561074e57600080fd5b82018360208201111561076057600080fd5b803590602001918460018302840111600160201b8311171561078157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061176a945050505050565b610300600480360360208110156107d857600080fd5b5035612018565b6102cf600480360360408110156107f557600080fd5b810190602081018135600160201b81111561080f57600080fd5b82018360208201111561082157600080fd5b803590602001918460018302840111600160201b8311171561084257600080fd5b919390929091602081019035600160201b81111561085f57600080fd5b82018360208201111561087157600080fd5b803590602001918460018302840111600160201b8311171561089257600080fd5b5090925090506120a2565b610300600480360360208110156108b357600080fd5b5035612258565b610300600480360360208110156108d057600080fd5b50356122b0565b61099b60048036036101208110156108ee57600080fd5b6001600160801b03823516916001600160a01b03602082013581169260408301358216926060810135831692608082013581169260a0830135926001600160401b0360c0820135169260e082013516918101906101208101610100820135600160201b81111561095d57600080fd5b82018360208201111561096f57600080fd5b803590602001918460018302840111600160201b8311171561099057600080fd5b50909250905061234e565b6040518080602001838152602001828103825284818151815260200191508051906020019080838360005b838110156109de5781810151838201526020016109c6565b50505050905090810190601f168015610a0b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61030060048036036020811015610a3057600080fd5b50356124fc565b61029660048036036020811015610a4d57600080fd5b50356126ab565b610a7160048036036020811015610a6a57600080fd5b50356126c9565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610aab578181015183820152602001610a93565b50505050905090810190601f168015610ad85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103006004803603610120811015610afd57600080fd5b6001600160801b03823516916001600160a01b03602082013581169260408301358216926060810135831692608082013581169260a08301359091169160c0810135916001600160401b0360e08301351691908101906101208101610100820135600160201b811115610b6f57600080fd5b820183602082011115610b8157600080fd5b803590602001918460018302840111600160201b83111715610ba257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061276b945050505050565b61029660048036036020811015610bf957600080fd5b5035612862565b6102cf60048036036040811015610c1657600080fd5b50803590602001356128af565b61029660048036036020811015610c3957600080fd5b5035612bd0565b6102cf60048036036020811015610c5657600080fd5b5035612bee565b610296612cad565b6102cf60048036036040811015610c7b57600080fd5b81359190810190604081016020820135600160201b811115610c9c57600080fd5b820183602082011115610cae57600080fd5b803590602001918460018302840111600160201b83111715610ccf57600080fd5b509092509050612cbc565b61029660048036036020811015610cf057600080fd5b5035612ea9565b610d1460048036036020811015610d0d57600080fd5b5035612ec7565b604080518d151581528c15156020808301919091526001600160401b038d16928201929092526001600160801b038b1660608201526001600160a01b03808b16608083015289811660a083015288811660c083015287811660e08301528681166101008301528516610120820152610140810184905261018061016082018181528451918301919091528351919290916101a084019185019080838360005b83811015610dcb578181015183820152602001610db3565b50505050905090810190601f168015610df85780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390f35b610300612fdb565b6102cf60048036036020811015610e2f57600080fd5b5035612fe2565b6102cf60048036036020811015610e4c57600080fd5b5035612ff7565b61030060048036036020811015610e6957600080fd5b503561318a565b61030060048036036020811015610e8657600080fd5b50356131ab565b6102cf600480360360c0811015610ea357600080fd5b81359190810190604081016020820135600160201b811115610ec457600080fd5b820183602082011115610ed657600080fd5b803590602001918460018302840111600160201b83111715610ef757600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092956001600160a01b0385351695602086013595919450925060608101915060400135600160201b811115610f5e57600080fd5b820183602082011115610f7057600080fd5b803590602001918460018302840111600160201b83111715610f9157600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610fe357600080fd5b820183602082011115610ff557600080fd5b803590602001918460018302840111600160201b8311171561101657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613205945050505050565b610300600480360360c081101561106d57600080fd5b5080356001600160801b03169060208101356001600160a01b039081169160408101358216916060820135169060808101359060a001356001600160401b0316613c1b565b610296613c36565b6000908152600260205260409020600301546001600160a01b031690565b600090815260026020526040902054610100900460ff1690565b600090815260026020526040902054600160501b90046001600160801b031690565b6000908152600260205260409020600401546001600160a01b031690565b60006001600160a01b0387166111795760405162461bcd60e51b8152600401808060200182810382526022815260200180614f696022913960400191505060405180910390fd5b60405163c16e50ef60e01b8152602060048201908152602482018490526001600160a01b038b169163c16e50ef9186918691908190604401848480828437600083820152604051601f909101601f191690920195506020945090925050508083038186803b1580156111ea57600080fd5b505afa1580156111fe573d6000803e3d6000fd5b505050506040513d602081101561121457600080fd5b5051611267576040805162461bcd60e51b815260206004820152601a60248201527f546865206c6f616e2064617461206973206e6f742076616c6964000000000000604482015290519081900360640190fd5b6112ae8a88338c8c8b8b8b8b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276b92505050565b60008181526003602052604090205490915060ff161561130d576040805162461bcd60e51b8152602060048201526015602482015274151a19481919589d081dd85cc818d85b98d95b1959605a1b604482015290519081900360640190fd5b6000818152600260205260409020600501546001600160a01b031615611372576040805162461bcd60e51b815260206004820152601560248201527414995c5d595cdd08185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b6000876001600160a01b0316336001600160a01b03161490506040518061018001604052806001151581526020018215158152602001866001600160401b031681526020018c6001600160801b0316815260200160006001600160a01b031681526020018b6001600160a01b03168152602001336001600160a01b031681526020018a6001600160a01b03168152602001896001600160a01b03168152602001886001600160a01b0316815260200187815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505084815260026020818152604092839020855181548784015195880151606089015160ff199092169215159290921761ff00191661010096151587021769ffffffffffffffff00001916620100006001600160401b039093169290920291909117600160501b600160d01b031916600160501b6001600160801b039092169190910217815560808601516001820180546001600160a01b03199081166001600160a01b039384161790915560a0880151948301805482169583169590951790945560c0870151600383018054861691831691909117905560e08701516004830180548616918316919091179055938601516005820180548516918616919091179055610120860151600682018054909416941693909317909155610140840151600783015561016084015180519293506115a19260088501929190910190614e0e565b50905050817f200404915876dec9fd44568ed7f5358a7fc4b212c1cdfc404ab17be21a1cf4af8c8c338d8d8d8d8c8c8f604051808b6001600160801b03166001600160801b031681526020018a6001600160a01b03166001600160a01b03168152602001896001600160a01b03166001600160a01b03168152602001886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b0316815260200185815260200180602001836001600160401b031681526020018281038252858582818152602001925080828437600083820152604051601f909101601f19169092018290039d50909b505050505050505050505050a28061172a576116d2886001600160a01b0316613c45565b80156116f957506116f96001600160a01b0389166376ba600960e01b63ffffffff613c4b16565b1561172a576117088289613cee565b6000838152600260205260409020805461ff0019166101008315150217905590505b801561175c5760405182907f6fb7fd1eda743aa3eb32c69f3b8cf14a5aeadf26db51057a7c5c78ba10eac8a490600090a25b509998505050505050505050565b60004261177a8b606c6008613e24565b116117cc576040805162461bcd60e51b815260206004820152601760248201527f4c6f616e20726571756573742069732065787069726564000000000000000000604482015290519081900360640190fd5b60006117d88b8b613ea5565b60008281526002602052604090206005015491935091506001600160a01b031615611842576040805162461bcd60e51b815260206004820152601560248201527414995c5d595cdd08185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b600061184e8c88614036565b6001549091506001600160a01b03166323b872dd336118708f60386014613e24565b604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152604482018590525160648083019260209291908290030181600087803b1580156118c757600080fd5b505af11580156118db573d6000803e3d6000fd5b505050506040513d60208110156118f157600080fd5b5051611944576040805162461bcd60e51b815260206004820181905260248201527f4572726f722073656e64696e6720746f6b656e7320746f20626f72726f776572604482015290519081900360640190fd5b826119508d8d8561405b565b146119a2576040805162461bcd60e51b815260206004820152601c60248201527f4572726f72206372656174696e67206465627420726567697374727900000000604482015290519081900360640190fd5b6040805133815260208101839052815185927fb1d906969e9527a5ad3ac2ca84eb415890ddf44581528edf18d0e7154d7f126d928290030190a260408051610180810182526000815260016020820152908101611a028e606c6008613e24565b6001600160401b03168152602001611a1d8e60006010613e24565b6001600160801b031681526001600160a01b038c166020820152604001611a478e60106014613e24565b6001600160a01b03168152602001611a628e60746014613e24565b6001600160a01b03168152602001611a7d8e60246014613e24565b6001600160a01b03168152602001611a988e60386014613e24565b6001600160a01b03168152602001611ab38e60886014613e24565b6001600160a01b0390811682526020909101908c16611ade57611ad98e604c6020613e24565b611ae0565b8a5b815260209081018d905260008581526002808352604091829020845181548686015194870151606088015160ff199092169215159290921761ff00191661010095151586021769ffffffffffffffff00001916620100006001600160401b039093169290920291909117600160501b600160d01b031916600160501b6001600160801b039092169190910217815560808501516001820180546001600160a01b03199081166001600160a01b039384161790915560a0870151938301805482169483169490941790935560c0860151600383018054851691831691909117905560e086015160048301805485169183169190911790559285015160058201805484169185169190911790556101208501516006820180549093169316929092179055610140830151600782015561016083015180519192611c2992600885019290910190614e0e565b5050506000838152600260205260409020611c47848e8e8a8a61418a565b6001600160a01b038b1615611eae578a6001600160a01b03166002018160010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6001600160a01b031663bb26d9d1308660001c8c8c6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015611d0f578181015183820152602001611cf7565b50505050905090810190601f168015611d3c5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015611d6f578181015183820152602001611d57565b50505050905090810190601f168015611d9c5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b158015611dbf57600080fd5b505af1158015611dd3573d6000803e3d6000fd5b505050506040513d6020811015611de957600080fd5b5051611e3c576040805162461bcd60e51b815260206004820152601c60248201527f436f7369676e206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b60018101546001600160a01b038c8116911614611e9b576040805162461bcd60e51b8152602060048201526018602482015277436f7369676e6572206469646e27742063616c6c6261636b60401b604482015290519081900360640190fd5b611ea88d604c6020613e24565b60078201555b6000611ebd8e60886014613e24565b90506001600160a01b038116156120075760405163d911b43f60e01b81526004810186815233602483018190526060604484019081528951606485015289516001600160a01b0386169463d911b43f94620493e0948c9490938e9360840190602085019080838360005b83811015611f3f578181015183820152602001611f27565b50505050905090810190601f168015611f6c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600088803b158015611f8d57600080fd5b5087f1158015611fa1573d6000803e3d6000fd5b50505050506040513d6020811015611fb857600080fd5b5051612007576040805162461bcd60e51b815260206004820152601960248201527852656a6563746564206279206c6f616e2063616c6c6261636b60381b604482015290519081900360640190fd5b505050509998505050505050505050565b6000818152600260208181526040808420909201548251639a6203e960e01b81526004810186905292516001600160a01b0390911692639a6203e9926024808301939192829003018186803b15801561207057600080fd5b505afa158015612084573d6000803e3d6000fd5b505050506040513d602081101561209a57600080fd5b505192915050565b60008061211886868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881529250889150879081908401838280828437600092019190915250613ea592505050565b50905061216086868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506038925060149150613e249050565b6001600160a01b03163314806121c257506121b686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506074925060149150613e249050565b6001600160a01b031633145b6121fd5760405162461bcd60e51b815260040180806020018281038252602c815260200180614fad602c913960400191505060405180910390fd5b600081815260036020908152604091829020805460ff191660011790558151338152915183927f029e3e789ef1a202e83e668d22e38205106d93105847601f49983c21efb8cfbe92908290030190a250600195945050505050565b60008181526002602081815260408084209092015482516366ec3a8760e11b81526004810186905292516001600160a01b039091169263cdd8750e926024808301939192829003018186803b15801561207057600080fd5b6000818152600260205260408120805460ff1661234457600054604080516302ef145760e51b81526004810186905290516001600160a01b0390921691635de28ae091602480820192602092909190829003018186803b15801561231357600080fd5b505afa158015612327573d6000803e3d6000fd5b505050506040513d602081101561233d57600080fd5b5051612347565b60005b9392505050565b604080516001600160801b031960808d901b1660208201526001600160601b031960608c811b821660308401528b811b821660448401528a811b82166058840152606c83018990526001600160c01b031960c089901b16608c84015286811b8216609484015289901b1660a88201528151609c81830301815260bc9091019091526000806123e08d8b888c8c8c61484d565b90506000809054906101000a90046001600160a01b03166001600160a01b031663f57ae7b9308e8e858a8a6040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505097505050505050505060206040518083038186803b1580156124bc57600080fd5b505afa1580156124d0573d6000803e3d6000fd5b505050506040513d60208110156124e657600080fd5b5051929d929c50919a5050505050505050505050565b600081815260026020526040812060058101546001600160a01b0316612562576040805162461bcd60e51b815260206004820152601660248201527514995c5d595cdd08191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b6040805161018081018252825460ff8082161515835261010080830490911615156020808501919091526201000083046001600160401b031684860152600160501b9092046001600160801b031660608401526001808601546001600160a01b039081166080860152600280880154821660a08701526003880154821660c08701526004880154821660e08701526005880154821684870152600688015490911661012086015260078701546101408601526008870180548751938116159094026000190190931604601f8101849004840282018401909552848152612347948693610160860193919083018282801561269d5780601f106126725761010080835404028352916020019161269d565b820191906000526020600020905b81548152906001019060200180831161268057829003601f168201915b5050505050815250506148ca565b6000908152600260205260409020600601546001600160a01b031690565b600081815260026020818152604092839020600801805484516001821615610100026000190190911693909304601f8101839004830284018301909452838352606093909183018282801561275f5780601f106127345761010080835404028352916020019161275f565b820191906000526020600020905b81548152906001019060200180831161274257829003601f168201915b50505050509050919050565b60008061277c8b8b8b89898961484d565b600054604051600160f91b6020808301918252606084811b6001600160601b031990811660218601523080831b60358701528f831b82166049870152918e901b16605d8501526071840186905288519596506002956001600160a01b039095169490938e938e9389938c93609101918401908083835b602083106128115780518252601f1990920191602091820191016127f2565b6001836020036101000a038019825116818451168082178552505050505050905001975050505050505050604051602081830303815290604052805190602001209150509998505050505050505050565b60008054604080516331a9108f60e11b81526004810185905290516001600160a01b0390921691636352211e91602480820192602092909190829003018186803b15801561207057600080fd5b600082815260026020526040812060018101546001600160a01b031661291c576040805162461bcd60e51b815260206004820152601960248201527f436f7369676e657220307830206973206e6f742076616c696400000000000000604482015290519081900360640190fd5b805442620100009091046001600160401b031611612976576040805162461bcd60e51b815260206004820152601260248201527114995c5d595cdd081a5cc8195e1c1a5c995960721b604482015290519081900360640190fd5b6001810154336002016001600160a01b039081169116146129d3576040805162461bcd60e51b815260206004820152601260248201527110dbdcda59db995c881b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6001810180546001600160a01b031916331790558215612b8a578281600701541015612a3f576040805162461bcd60e51b815260206004820152601660248201527510dbdcda59db995c8818dbdcdd08195e18d95959195960521b604482015290519081900360640190fd5b600154600054604080516331a9108f60e11b81526004810188905290516001600160a01b03938416936323b872dd931691636352211e916024808301926020929190829003018186803b158015612a9557600080fd5b505afa158015612aa9573d6000803e3d6000fd5b505050506040513d6020811015612abf57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152336024830152604482018790525160648083019260209291908290030181600087803b158015612b1557600080fd5b505af1158015612b29573d6000803e3d6000fd5b505050506040513d6020811015612b3f57600080fd5b5051612b8a576040805162461bcd60e51b815260206004820152601560248201527422b93937b9103830bcb4b7339031b7b9b4b3b732b960591b604482015290519081900360640190fd5b6040805133815260208101859052815186927f8a4448add099432884d9833a6b44c465104441b7659c2c00b037da123a54f9d2928290030190a260019150505b92915050565b6000908152600260205260409020600501546001600160a01b031690565b600081815260026020526040812060058101546001600160a01b03163314612c5d576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c7920626f72726f7765722063616e20617070726f766500000000000000604482015290519081900360640190fd5b8054610100900460ff16612ca457805461ff00191661010017815560405183907f6fb7fd1eda743aa3eb32c69f3b8cf14a5aeadf26db51057a7c5c78ba10eac8a490600090a25b50600192915050565b6000546001600160a01b031681565b6000838152600260205260408120600581015481546001600160a01b0390911690610100900460ff16612e4e57612cfb816001600160a01b0316613c45565b8015612d225750612d226001600160a01b0382166376ba600960e01b63ffffffff613c4b16565b15612d3857612d318682613cee565b9250612e4e565b604080516020808201899052731cda59db88185c1c1c9bdd99481c995c5d595cdd60621b82840152825160348184030181526054830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000607484015260908084018290528451808503909101815260b0840180865281519184019190912060d0601f8b01859004909402850184019095528881529093600093612dff939192918b918b918291018382808284376000920191909152506148f592505050565b9050806001600160a01b0316836001600160a01b03161415612e4b5760405188907fac4faa318b3929891fe5ee57344cce181e72bced7246f5aa4a788ab61e7bb5d290600090a2600194505b50505b828015612e6257508154610100900460ff16155b15612ea057815461ff00191661010017825560405186907f6fb7fd1eda743aa3eb32c69f3b8cf14a5aeadf26db51057a7c5c78ba10eac8a490600090a25b50509392505050565b6000908152600260205260409020600101546001600160a01b031690565b6002602081815260009283526040928390208054600180830154838601546003850154600486015460058701546006880154600789015460088a0180548e516101009a8216158b02600019019091169d909d04601f81018d90048d028e018d01909e528d8d5260ff808b169e998b04169c620100008b046001600160401b03169c600160501b909b046001600160801b03169b6001600160a01b03998a169b988a169a978a1699968716989587169796909416959294909290830182828015612fd15780601f10612fa657610100808354040283529160200191612fd1565b820191906000526020600020905b815481529060010190602001808311612fb457829003601f168201915b505050505090508c565b620493e081565b60036020526000908152604090205460ff1681565b6000818152600260205260408120805460ff166130455760405162461bcd60e51b815260040180806020018281038252602a815260200180614ef1602a913960400191505060405180910390fd5b60038101546001600160a01b031633148061306c575060058101546001600160a01b031633145b6130a75760405162461bcd60e51b815260040180806020018281038252602d815260200180614fd9602d913960400191505060405180910390fd5b6130b5600882016000614e8c565b6000838152600260208190526040822080546001600160d01b03191681556001810180546001600160a01b031990811690915591810180548316905560038101805483169055600481018054831690556005810180548316905560068101805490921690915560078101829055906131306008830182614e8c565b5050600083815260036020908152604091829020805460ff191660011790558151338152915185927f5f32c817b1de98e681044c3d78ca791e6018e4c3b4f230e4d85bbcc3815989f392908290030190a250600192915050565b6000908152600260205260409020546201000090046001600160401b031690565b6000818152600260205260408120600401546001600160a01b0316801561234457806001600160a01b031663e5a6b10f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561231357600080fd5b6000868152600260205260408120805460ff16613269576040805162461bcd60e51b815260206004820152601960248201527f52657175657374206973206e6f206c6f6e676572206f70656e00000000000000604482015290519081900360640190fd5b8054610100900460ff166132ae5760405162461bcd60e51b815260040180806020018281038252602b815260200180614f3e602b913960400191505060405180910390fd5b805442620100009091046001600160401b03161161330c576040805162461bcd60e51b8152602060048201526016602482015275151a19481c995c5d595cdd081a5cc8195e1c1a5c995960521b604482015290519081900360640190fd5b805460ff19168082556004820154600091613341916001600160a01b031690600160501b90046001600160801b03168a614985565b6001546005840154604080516323b872dd60e01b81523360048201526001600160a01b0392831660248201526044810185905290519394509116916323b872dd916064808201926020929091908290030181600087803b1580156133a457600080fd5b505af11580156133b8573d6000803e3d6000fd5b505050506040513d60208110156133ce57600080fd5b5051613421576040805162461bcd60e51b815260206004820181905260248201527f4572726f722073656e64696e6720746f6b656e7320746f20626f72726f776572604482015290519081900360640190fd5b604080513381526020810183905281518b927ff701a0be7203a591a078aa39b506b74dcf910d7a73b1f73a4dff4d0df3968361928290030190a2886000809054906101000a90046001600160a01b03166001600160a01b0316632ed042658460020160009054906101000a90046001600160a01b0316338660040160009054906101000a90046001600160a01b03166136e688604051806101800160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a90046001600160401b03166001600160401b03166001600160401b0316815260200160008201600a9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020016001820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016004820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016005820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016006820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160078201548152602001600882018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561269d5780601f106126725761010080835404028352916020019161269d565b6040516001600160e01b031960e087901b1681526001600160a01b0380861660048301908152858216602484015290841660448301526064820183905260a06084830190815260088c0180546002600019610100600184161502019091160460a48501819052909360c40190849080156137a15780601f10613776576101008083540402835291602001916137a1565b820191906000526020600020905b81548152906001019060200180831161378457829003601f168201915b50509650505050505050602060405180830381600087803b1580156137c557600080fd5b505af11580156137d9573d6000803e3d6000fd5b505050506040513d60208110156137ef57600080fd5b505114613843576040805162461bcd60e51b815260206004820152601760248201527f4572726f72206372656174696e67207468652064656274000000000000000000604482015290519081900360640190fd5b6001600160a01b03871615613aaf57600082600701549050876001600160a01b03166002018360010160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550868360070181905550876001600160a01b031663bb26d9d1308c60001c898d6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561391d578181015183820152602001613905565b50505050905090810190601f16801561394a5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561397d578181015183820152602001613965565b50505050905090810190601f1680156139aa5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156139cd57600080fd5b505af11580156139e1573d6000803e3d6000fd5b505050506040513d60208110156139f757600080fd5b5051613a4a576040805162461bcd60e51b815260206004820152601c60248201527f436f7369676e206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b60018301546001600160a01b03898116911614613aa9576040805162461bcd60e51b8152602060048201526018602482015277436f7369676e6572206469646e27742063616c6c6261636b60401b604482015290519081900360640190fd5b60078301555b60068201546001600160a01b03168015613c0b57806001600160a01b031663d911b43f620493e08c33896040518563ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613b43578181015183820152602001613b2b565b50505050905090810190601f168015613b705780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600088803b158015613b9157600080fd5b5087f1158015613ba5573d6000803e3d6000fd5b50505050506040513d6020811015613bbc57600080fd5b5051613c0b576040805162461bcd60e51b815260206004820152601960248201527852656a6563746564206279206c6f616e2063616c6c6261636b60381b604482015290519081900360640190fd5b5060019998505050505050505050565b6000613c2b87878787878761484d565b979650505050505050565b6001546001600160a01b031681565b3b151590565b60008080613c60856301ffc9a760e01b614ae8565b915091508160001480613c71575080155b15613c8157600092505050612bca565b613c93856001600160e01b0319614ae8565b9092509050811580613ca457508015155b15613cb457600092505050612bca565b613cbe8585614ae8565b9092509050600182148015613cd35750806001145b15613ce357600192505050612bca565b506000949350505050565b6040805160248082018590528251808303909101815260449091019091526020810180516001600160e01b03166376ba600960e01b1790526000907fdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a84189082908190613d5c908690614b1c565b91509150818015613d6c57508281145b93508315613da45760405186907fbcd1a053efeeac2159254030853620c82ddeffb174f76982dc0dd1083648ade390600090a2613e1b565b81613de45760408051828152905187917f04843e870d380c72a3ffb37e0afa8b10e7948a34dee4ef9c1d6754cc0699c3d3919081900360200190a2613e1b565b60408051828152905187917f7b550df26fb29cebc893b0071262bded4c36eb15da43317bf72c3f9f5aeb554a919081900360200190a25b50505092915050565b600081830184511015613e7e576040805162461bcd60e51b815260206004820152601b60248201527f52656164696e67206279746573206f7574206f6620626f756e64730000000000604482015290519081900360640190fd5b826020018401519050816020038015613e9d576008810260020a820491505b509392505050565b6000806000806000806000806000613ebc8b614bf1565b959c50939a509198509650945092509050613ee7878583613ee08f60886014613e24565b878761484d565b97506000809054906101000a90046001600160a01b03166001600160a01b031663f57ae7b93088888c8f6040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613fab578181015183820152602001613f93565b50505050905090810190601f168015613fd85780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b158015613ff957600080fd5b505afa15801561400d573d6000803e3d6000fd5b505050506040513d602081101561402357600080fd5b50519b979a509698505050505050505050565b60006123476140488460246014613e24565b6140558560006010613e24565b84614985565b600080546001600160a01b0316632ed0426561407a8660106014613e24565b336140888860246014613e24565b6040516001600160e01b031960e086901b1681526001600160a01b0380851660048301908152848216602484015290831660448301526064820189905260a0608483019081528a5160a48401528a518a938c93929160c490910190602085019080838360005b838110156141065781810151838201526020016140ee565b50505050905090810190601f1680156141335780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561415657600080fd5b505af115801561416a573d6000803e3d6000fd5b505050506040513d602081101561418057600080fd5b5051949350505050565b60008581526003602052604090205460ff16156141e4576040805162461bcd60e51b815260206004820152601360248201527214d95d1d1b19481dd85cc818d85b98d95b1959606a1b604482015290519081900360640190fd5b7fdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a851860006142168660386014613e24565b905060006142278760746014613e24565b9050600061423d6001600160a01b038416613c45565b156144025783836001600160a01b031663b700f67a8a8a60018e60001c6040518563ffffffff1660e01b815260040180806020018060200185151515158152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156142ba5781810151838201526020016142a2565b50505050905090810190601f1680156142e75780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b8381101561431a578181015183820152602001614302565b50505050905090810190601f1680156143475780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561436a57600080fd5b505af115801561437e573d6000803e3d6000fd5b505050506040513d602081101561439457600080fd5b5051146143d25760405162461bcd60e51b8152600401808060200182810382526023815260200180614f1b6023913960400191505060405180910390fd5b60405189907f168544dde877630d31a353bc62115efd38d8e072b48761461075d8421620e77290600090a261452a565b506040805160208082018b90527f7369676e20736574746c65206c656e6420617320626f72726f77657200000000828401528251603c818403018152605c830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000607c84015260988084018290528451808503909101815260b8909301909352815191012061449990866148f5565b6001600160a01b0316836001600160a01b0316146144fe576040805162461bcd60e51b815260206004820152601a60248201527f496e76616c696420626f72726f776572207369676e6174757265000000000000604482015290519081900360640190fd5b60405189907f04acecab035917c895d49033509a027f3fbb1913e978eec824926f605370653b90600090a25b816001600160a01b0316836001600160a01b03161461484257614555826001600160a01b0316613c45565b1561471a5783826001600160a01b031663b700f67a8a8a60008e60001c6040518563ffffffff1660e01b815260040180806020018060200185151515158152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b8381101561463257818101518382015260200161461a565b50505050905090810190601f16801561465f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561468257600080fd5b505af1158015614696573d6000803e3d6000fd5b505050506040513d60208110156146ac57600080fd5b5051146146ea5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f8b6022913960400191505060405180910390fd5b60405189907f025f21426e185fab3bf170a9374c750b17a510c3ed51549fa4ff068dbca6605790600090a2614842565b506040805160208082018b90527f7369676e20736574746c65206c656e642061732063726561746f720000000000828401528251603b818403018152605b830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000607b84015260978084018290528451808503909101815260b790930190935281519101206147b190876148f5565b6001600160a01b0316826001600160a01b031614614816576040805162461bcd60e51b815260206004820152601960248201527f496e76616c69642063726561746f72207369676e617475726500000000000000604482015290519081900360640190fd5b60405189907f3971d1c591487c96ba2561ab5f74f00001a6134408897ab8b0124c1673055dd290600090a25b505050505050505050565b6040805160809790971b6001600160801b031916602080890191909152606096871b6001600160601b031990811660308a015295871b861660448901529390951b9093166058860152606c85015260c09190911b6001600160c01b031916608c840152815180840360740181526094909301909152815191012090565b6000612bca82606001518361010001518460c00151856101200151866101400151876040015161484d565b602081015160408201516041830151600092919060ff16601b81101561491957601b015b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015614970573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006001600160a01b03841661499c575081612347565b600080856001600160a01b031663b077c09b856040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156149fb5781810151838201526020016149e3565b50505050905090810190601f168015614a285780820380516001836020036101000a031916815260200191505b50925050506040805180830381600087803b158015614a4657600080fd5b505af1158015614a5a573d6000803e3d6000fd5b505050506040513d6040811015614a7057600080fd5b508051602091820151604080516001600160a01b038b1681529384018390528381018290525191945092507f0b53fa0f90e4773f861d84b5da681ae7b3dd6b29358fdb4a38ba8dec13fc80f39181900360600190a180614ad6838763ffffffff614c7a16565b81614add57fe5b049695505050505050565b6040516301ffc9a760e01b8082526004820183905260009182919060208160248189617530fa905190969095509350505050565b6000806060846001600160a01b0316846040518082805190602001908083835b60208310614b5b5780518252601f199092019160209182019101614b3c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614bbd576040519150601f19603f3d011682016040523d82523d6000602084013e614bc2565b606091505b508051919450915015614be957808060200190516020811015614be457600080fd5b505191505b509250929050565b6000806000806000806000806000806000806000614c198e6010601480601460206008614cd9565b9550955095509550955095508560001c9c508460001c9b508360001c9a508260001c99508160001c98508060001c9750614c648e600860206014806014601001010101016014613e24565b60001c9650505050505050919395979092949650565b600082614c8957506000612bca565b82820282848281614c9657fe5b0414612347576040805162461bcd60e51b815260206004820152600d60248201526c4d756c74206f766572666c6f7760981b604482015290519081900360640190fd5b600080600080600080600060208e01805197508d6020038015614d02576008810260020a890498505b8e82019250825197508d60200390508015614d23576008810260020a880497505b50908c01805195509060208c90038015614d43576008810260020a870496505b50908b01805194509060208b90038015614d63576008810260020a860495505b50908a01805193509060208a90038015614d83576008810260020a850494505b50908901805192509060208990038015614da3576008810260020a840493505b508e51910390811115614dfd576040805162461bcd60e51b815260206004820152601b60248201527f52656164696e67206279746573206f7574206f6620626f756e64730000000000604482015290519081900360640190fd5b509750975097509750975097915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614e4f57805160ff1916838001178555614e7c565b82800160010185558215614e7c579182015b82811115614e7c578251825591602001919060010190614e61565b50614e88929150614ed3565b5090565b50805460018160011615610100020316600290046000825580601f10614eb25750614ed0565b601f016020900490600052602060002090810190614ed09190614ed3565b50565b614eed91905b80821115614e885760008155600101614ed9565b9056fe52657175657374206973206e6f206c6f6e676572206f70656e206f72206e6f7420726571756573746564426f72726f77657220636f6e74726163742072656a656374656420746865206c6f616e5468652072657175657374206973206e6f7420617070726f7665642062792074686520626f72726f77657254686520726571756573742073686f756c642068617665206120626f72726f77657243726561746f7220636f6e74726163742072656a656374656420746865206c6f616e4f6e6c7920626f72726f776572206f722063726561746f722063616e2063616e63656c206120736574746c654f6e6c7920626f72726f776572206f722063726561746f722063616e2063616e63656c20612072657175657374a265627a7a72315820636d7e7ae7f2447934281cf8ec9198f51a4e88c8f8d6452f62845a122b95226a64736f6c634300050b003200000000000000000000000080db22675dad70e44b64029510778583187faddb
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102745760003560e01c80638500d91911610151578063c955bde2116100c3578063dafaf94a11610087578063dafaf94a14610312578063db97eb4414610e8d578063e3bab7ce14611057578063e6c8fcf114610e53578063ef270ee2146102b2578063fc0c546a146110b257610274565b8063c955bde214610e53578063cdd8750e1461089d578063cdf9b77e14610e70578063d383b80d14610e70578063d48e638a1461027957610274565b80639d866985116101155780639d86698514610cf7578063a56d9dda14610cda578063a9f649e814610e11578063abf6ac0914610e19578063c4d252f514610e36578063c4d2b1b314610a5457610274565b80638500d91914610c2357806390cd0d0614610c65578063964f61f914610cda5780639980ec86146102e35780639a6203e9146107c257610274565b80635de28ae0116101ea5780636352211e116101ae5780636352211e14610be35780636394536d14610c00578063728c3ea214610c2357806376ba600914610c405780637cdef83c14610c5d5780637dd5641114610be357610274565b80635de28ae0146108ba5780635f7cfe4914610a1a5780636135a0ad14610a37578063622fe39f14610a54578063629d2f3414610ae657610274565b8063385584bf1161023c578063385584bf146103ea57806351cbb299146107c25780635900477a146107df578063593570451461089d5780635c622a0e146108ba5780635d9c4afe146108d757610274565b8063060a7ef114610279578063081812fc146102b25780630e0a0d74146102e357806310a9de6014610312578063167d76031461032f575b600080fd5b6102966004803603602081101561028f57600080fd5b50356110ba565b604080516001600160a01b039092168252519081900360200190f35b6102cf600480360360208110156102c857600080fd5b50356110d8565b604080519115158252519081900360200190f35b610300600480360360208110156102f957600080fd5b50356110f2565b60408051918252519081900360200190f35b6102966004803603602081101561032857600080fd5b5035611114565b610300600480360361010081101561034657600080fd5b6001600160801b03823516916001600160a01b036020820135811692604083013582169260608101358316926080820135169160a0820135916001600160401b0360c08201351691810190610100810160e0820135600160201b8111156103ac57600080fd5b8201836020820111156103be57600080fd5b803590602001918460018302840111600160201b831117156103df57600080fd5b509092509050611132565b610300600480360361012081101561040157600080fd5b810190602081018135600160201b81111561041b57600080fd5b82018360208201111561042d57600080fd5b803590602001918460018302840111600160201b8311171561044e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104a057600080fd5b8201836020820111156104b257600080fd5b803590602001918460018302840111600160201b831117156104d357600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092956001600160a01b0385351695602086013595919450925060608101915060400135600160201b81111561053a57600080fd5b82018360208201111561054c57600080fd5b803590602001918460018302840111600160201b8311171561056d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156105bf57600080fd5b8201836020820111156105d157600080fd5b803590602001918460018302840111600160201b831117156105f257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561064457600080fd5b82018360208201111561065657600080fd5b803590602001918460018302840111600160201b8311171561067757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156106c957600080fd5b8201836020820111156106db57600080fd5b803590602001918460018302840111600160201b831117156106fc57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561074e57600080fd5b82018360208201111561076057600080fd5b803590602001918460018302840111600160201b8311171561078157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061176a945050505050565b610300600480360360208110156107d857600080fd5b5035612018565b6102cf600480360360408110156107f557600080fd5b810190602081018135600160201b81111561080f57600080fd5b82018360208201111561082157600080fd5b803590602001918460018302840111600160201b8311171561084257600080fd5b919390929091602081019035600160201b81111561085f57600080fd5b82018360208201111561087157600080fd5b803590602001918460018302840111600160201b8311171561089257600080fd5b5090925090506120a2565b610300600480360360208110156108b357600080fd5b5035612258565b610300600480360360208110156108d057600080fd5b50356122b0565b61099b60048036036101208110156108ee57600080fd5b6001600160801b03823516916001600160a01b03602082013581169260408301358216926060810135831692608082013581169260a0830135926001600160401b0360c0820135169260e082013516918101906101208101610100820135600160201b81111561095d57600080fd5b82018360208201111561096f57600080fd5b803590602001918460018302840111600160201b8311171561099057600080fd5b50909250905061234e565b6040518080602001838152602001828103825284818151815260200191508051906020019080838360005b838110156109de5781810151838201526020016109c6565b50505050905090810190601f168015610a0b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61030060048036036020811015610a3057600080fd5b50356124fc565b61029660048036036020811015610a4d57600080fd5b50356126ab565b610a7160048036036020811015610a6a57600080fd5b50356126c9565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610aab578181015183820152602001610a93565b50505050905090810190601f168015610ad85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103006004803603610120811015610afd57600080fd5b6001600160801b03823516916001600160a01b03602082013581169260408301358216926060810135831692608082013581169260a08301359091169160c0810135916001600160401b0360e08301351691908101906101208101610100820135600160201b811115610b6f57600080fd5b820183602082011115610b8157600080fd5b803590602001918460018302840111600160201b83111715610ba257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061276b945050505050565b61029660048036036020811015610bf957600080fd5b5035612862565b6102cf60048036036040811015610c1657600080fd5b50803590602001356128af565b61029660048036036020811015610c3957600080fd5b5035612bd0565b6102cf60048036036020811015610c5657600080fd5b5035612bee565b610296612cad565b6102cf60048036036040811015610c7b57600080fd5b81359190810190604081016020820135600160201b811115610c9c57600080fd5b820183602082011115610cae57600080fd5b803590602001918460018302840111600160201b83111715610ccf57600080fd5b509092509050612cbc565b61029660048036036020811015610cf057600080fd5b5035612ea9565b610d1460048036036020811015610d0d57600080fd5b5035612ec7565b604080518d151581528c15156020808301919091526001600160401b038d16928201929092526001600160801b038b1660608201526001600160a01b03808b16608083015289811660a083015288811660c083015287811660e08301528681166101008301528516610120820152610140810184905261018061016082018181528451918301919091528351919290916101a084019185019080838360005b83811015610dcb578181015183820152602001610db3565b50505050905090810190601f168015610df85780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390f35b610300612fdb565b6102cf60048036036020811015610e2f57600080fd5b5035612fe2565b6102cf60048036036020811015610e4c57600080fd5b5035612ff7565b61030060048036036020811015610e6957600080fd5b503561318a565b61030060048036036020811015610e8657600080fd5b50356131ab565b6102cf600480360360c0811015610ea357600080fd5b81359190810190604081016020820135600160201b811115610ec457600080fd5b820183602082011115610ed657600080fd5b803590602001918460018302840111600160201b83111715610ef757600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092956001600160a01b0385351695602086013595919450925060608101915060400135600160201b811115610f5e57600080fd5b820183602082011115610f7057600080fd5b803590602001918460018302840111600160201b83111715610f9157600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610fe357600080fd5b820183602082011115610ff557600080fd5b803590602001918460018302840111600160201b8311171561101657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613205945050505050565b610300600480360360c081101561106d57600080fd5b5080356001600160801b03169060208101356001600160a01b039081169160408101358216916060820135169060808101359060a001356001600160401b0316613c1b565b610296613c36565b6000908152600260205260409020600301546001600160a01b031690565b600090815260026020526040902054610100900460ff1690565b600090815260026020526040902054600160501b90046001600160801b031690565b6000908152600260205260409020600401546001600160a01b031690565b60006001600160a01b0387166111795760405162461bcd60e51b8152600401808060200182810382526022815260200180614f696022913960400191505060405180910390fd5b60405163c16e50ef60e01b8152602060048201908152602482018490526001600160a01b038b169163c16e50ef9186918691908190604401848480828437600083820152604051601f909101601f191690920195506020945090925050508083038186803b1580156111ea57600080fd5b505afa1580156111fe573d6000803e3d6000fd5b505050506040513d602081101561121457600080fd5b5051611267576040805162461bcd60e51b815260206004820152601a60248201527f546865206c6f616e2064617461206973206e6f742076616c6964000000000000604482015290519081900360640190fd5b6112ae8a88338c8c8b8b8b8b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276b92505050565b60008181526003602052604090205490915060ff161561130d576040805162461bcd60e51b8152602060048201526015602482015274151a19481919589d081dd85cc818d85b98d95b1959605a1b604482015290519081900360640190fd5b6000818152600260205260409020600501546001600160a01b031615611372576040805162461bcd60e51b815260206004820152601560248201527414995c5d595cdd08185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b6000876001600160a01b0316336001600160a01b03161490506040518061018001604052806001151581526020018215158152602001866001600160401b031681526020018c6001600160801b0316815260200160006001600160a01b031681526020018b6001600160a01b03168152602001336001600160a01b031681526020018a6001600160a01b03168152602001896001600160a01b03168152602001886001600160a01b0316815260200187815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505084815260026020818152604092839020855181548784015195880151606089015160ff199092169215159290921761ff00191661010096151587021769ffffffffffffffff00001916620100006001600160401b039093169290920291909117600160501b600160d01b031916600160501b6001600160801b039092169190910217815560808601516001820180546001600160a01b03199081166001600160a01b039384161790915560a0880151948301805482169583169590951790945560c0870151600383018054861691831691909117905560e08701516004830180548616918316919091179055938601516005820180548516918616919091179055610120860151600682018054909416941693909317909155610140840151600783015561016084015180519293506115a19260088501929190910190614e0e565b50905050817f200404915876dec9fd44568ed7f5358a7fc4b212c1cdfc404ab17be21a1cf4af8c8c338d8d8d8d8c8c8f604051808b6001600160801b03166001600160801b031681526020018a6001600160a01b03166001600160a01b03168152602001896001600160a01b03166001600160a01b03168152602001886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b0316815260200185815260200180602001836001600160401b031681526020018281038252858582818152602001925080828437600083820152604051601f909101601f19169092018290039d50909b505050505050505050505050a28061172a576116d2886001600160a01b0316613c45565b80156116f957506116f96001600160a01b0389166376ba600960e01b63ffffffff613c4b16565b1561172a576117088289613cee565b6000838152600260205260409020805461ff0019166101008315150217905590505b801561175c5760405182907f6fb7fd1eda743aa3eb32c69f3b8cf14a5aeadf26db51057a7c5c78ba10eac8a490600090a25b509998505050505050505050565b60004261177a8b606c6008613e24565b116117cc576040805162461bcd60e51b815260206004820152601760248201527f4c6f616e20726571756573742069732065787069726564000000000000000000604482015290519081900360640190fd5b60006117d88b8b613ea5565b60008281526002602052604090206005015491935091506001600160a01b031615611842576040805162461bcd60e51b815260206004820152601560248201527414995c5d595cdd08185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b600061184e8c88614036565b6001549091506001600160a01b03166323b872dd336118708f60386014613e24565b604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152604482018590525160648083019260209291908290030181600087803b1580156118c757600080fd5b505af11580156118db573d6000803e3d6000fd5b505050506040513d60208110156118f157600080fd5b5051611944576040805162461bcd60e51b815260206004820181905260248201527f4572726f722073656e64696e6720746f6b656e7320746f20626f72726f776572604482015290519081900360640190fd5b826119508d8d8561405b565b146119a2576040805162461bcd60e51b815260206004820152601c60248201527f4572726f72206372656174696e67206465627420726567697374727900000000604482015290519081900360640190fd5b6040805133815260208101839052815185927fb1d906969e9527a5ad3ac2ca84eb415890ddf44581528edf18d0e7154d7f126d928290030190a260408051610180810182526000815260016020820152908101611a028e606c6008613e24565b6001600160401b03168152602001611a1d8e60006010613e24565b6001600160801b031681526001600160a01b038c166020820152604001611a478e60106014613e24565b6001600160a01b03168152602001611a628e60746014613e24565b6001600160a01b03168152602001611a7d8e60246014613e24565b6001600160a01b03168152602001611a988e60386014613e24565b6001600160a01b03168152602001611ab38e60886014613e24565b6001600160a01b0390811682526020909101908c16611ade57611ad98e604c6020613e24565b611ae0565b8a5b815260209081018d905260008581526002808352604091829020845181548686015194870151606088015160ff199092169215159290921761ff00191661010095151586021769ffffffffffffffff00001916620100006001600160401b039093169290920291909117600160501b600160d01b031916600160501b6001600160801b039092169190910217815560808501516001820180546001600160a01b03199081166001600160a01b039384161790915560a0870151938301805482169483169490941790935560c0860151600383018054851691831691909117905560e086015160048301805485169183169190911790559285015160058201805484169185169190911790556101208501516006820180549093169316929092179055610140830151600782015561016083015180519192611c2992600885019290910190614e0e565b5050506000838152600260205260409020611c47848e8e8a8a61418a565b6001600160a01b038b1615611eae578a6001600160a01b03166002018160010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6001600160a01b031663bb26d9d1308660001c8c8c6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015611d0f578181015183820152602001611cf7565b50505050905090810190601f168015611d3c5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015611d6f578181015183820152602001611d57565b50505050905090810190601f168015611d9c5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b158015611dbf57600080fd5b505af1158015611dd3573d6000803e3d6000fd5b505050506040513d6020811015611de957600080fd5b5051611e3c576040805162461bcd60e51b815260206004820152601c60248201527f436f7369676e206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b60018101546001600160a01b038c8116911614611e9b576040805162461bcd60e51b8152602060048201526018602482015277436f7369676e6572206469646e27742063616c6c6261636b60401b604482015290519081900360640190fd5b611ea88d604c6020613e24565b60078201555b6000611ebd8e60886014613e24565b90506001600160a01b038116156120075760405163d911b43f60e01b81526004810186815233602483018190526060604484019081528951606485015289516001600160a01b0386169463d911b43f94620493e0948c9490938e9360840190602085019080838360005b83811015611f3f578181015183820152602001611f27565b50505050905090810190601f168015611f6c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600088803b158015611f8d57600080fd5b5087f1158015611fa1573d6000803e3d6000fd5b50505050506040513d6020811015611fb857600080fd5b5051612007576040805162461bcd60e51b815260206004820152601960248201527852656a6563746564206279206c6f616e2063616c6c6261636b60381b604482015290519081900360640190fd5b505050509998505050505050505050565b6000818152600260208181526040808420909201548251639a6203e960e01b81526004810186905292516001600160a01b0390911692639a6203e9926024808301939192829003018186803b15801561207057600080fd5b505afa158015612084573d6000803e3d6000fd5b505050506040513d602081101561209a57600080fd5b505192915050565b60008061211886868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881529250889150879081908401838280828437600092019190915250613ea592505050565b50905061216086868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506038925060149150613e249050565b6001600160a01b03163314806121c257506121b686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506074925060149150613e249050565b6001600160a01b031633145b6121fd5760405162461bcd60e51b815260040180806020018281038252602c815260200180614fad602c913960400191505060405180910390fd5b600081815260036020908152604091829020805460ff191660011790558151338152915183927f029e3e789ef1a202e83e668d22e38205106d93105847601f49983c21efb8cfbe92908290030190a250600195945050505050565b60008181526002602081815260408084209092015482516366ec3a8760e11b81526004810186905292516001600160a01b039091169263cdd8750e926024808301939192829003018186803b15801561207057600080fd5b6000818152600260205260408120805460ff1661234457600054604080516302ef145760e51b81526004810186905290516001600160a01b0390921691635de28ae091602480820192602092909190829003018186803b15801561231357600080fd5b505afa158015612327573d6000803e3d6000fd5b505050506040513d602081101561233d57600080fd5b5051612347565b60005b9392505050565b604080516001600160801b031960808d901b1660208201526001600160601b031960608c811b821660308401528b811b821660448401528a811b82166058840152606c83018990526001600160c01b031960c089901b16608c84015286811b8216609484015289901b1660a88201528151609c81830301815260bc9091019091526000806123e08d8b888c8c8c61484d565b90506000809054906101000a90046001600160a01b03166001600160a01b031663f57ae7b9308e8e858a8a6040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505097505050505050505060206040518083038186803b1580156124bc57600080fd5b505afa1580156124d0573d6000803e3d6000fd5b505050506040513d60208110156124e657600080fd5b5051929d929c50919a5050505050505050505050565b600081815260026020526040812060058101546001600160a01b0316612562576040805162461bcd60e51b815260206004820152601660248201527514995c5d595cdd08191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b6040805161018081018252825460ff8082161515835261010080830490911615156020808501919091526201000083046001600160401b031684860152600160501b9092046001600160801b031660608401526001808601546001600160a01b039081166080860152600280880154821660a08701526003880154821660c08701526004880154821660e08701526005880154821684870152600688015490911661012086015260078701546101408601526008870180548751938116159094026000190190931604601f8101849004840282018401909552848152612347948693610160860193919083018282801561269d5780601f106126725761010080835404028352916020019161269d565b820191906000526020600020905b81548152906001019060200180831161268057829003601f168201915b5050505050815250506148ca565b6000908152600260205260409020600601546001600160a01b031690565b600081815260026020818152604092839020600801805484516001821615610100026000190190911693909304601f8101839004830284018301909452838352606093909183018282801561275f5780601f106127345761010080835404028352916020019161275f565b820191906000526020600020905b81548152906001019060200180831161274257829003601f168201915b50505050509050919050565b60008061277c8b8b8b89898961484d565b600054604051600160f91b6020808301918252606084811b6001600160601b031990811660218601523080831b60358701528f831b82166049870152918e901b16605d8501526071840186905288519596506002956001600160a01b039095169490938e938e9389938c93609101918401908083835b602083106128115780518252601f1990920191602091820191016127f2565b6001836020036101000a038019825116818451168082178552505050505050905001975050505050505050604051602081830303815290604052805190602001209150509998505050505050505050565b60008054604080516331a9108f60e11b81526004810185905290516001600160a01b0390921691636352211e91602480820192602092909190829003018186803b15801561207057600080fd5b600082815260026020526040812060018101546001600160a01b031661291c576040805162461bcd60e51b815260206004820152601960248201527f436f7369676e657220307830206973206e6f742076616c696400000000000000604482015290519081900360640190fd5b805442620100009091046001600160401b031611612976576040805162461bcd60e51b815260206004820152601260248201527114995c5d595cdd081a5cc8195e1c1a5c995960721b604482015290519081900360640190fd5b6001810154336002016001600160a01b039081169116146129d3576040805162461bcd60e51b815260206004820152601260248201527110dbdcda59db995c881b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6001810180546001600160a01b031916331790558215612b8a578281600701541015612a3f576040805162461bcd60e51b815260206004820152601660248201527510dbdcda59db995c8818dbdcdd08195e18d95959195960521b604482015290519081900360640190fd5b600154600054604080516331a9108f60e11b81526004810188905290516001600160a01b03938416936323b872dd931691636352211e916024808301926020929190829003018186803b158015612a9557600080fd5b505afa158015612aa9573d6000803e3d6000fd5b505050506040513d6020811015612abf57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152336024830152604482018790525160648083019260209291908290030181600087803b158015612b1557600080fd5b505af1158015612b29573d6000803e3d6000fd5b505050506040513d6020811015612b3f57600080fd5b5051612b8a576040805162461bcd60e51b815260206004820152601560248201527422b93937b9103830bcb4b7339031b7b9b4b3b732b960591b604482015290519081900360640190fd5b6040805133815260208101859052815186927f8a4448add099432884d9833a6b44c465104441b7659c2c00b037da123a54f9d2928290030190a260019150505b92915050565b6000908152600260205260409020600501546001600160a01b031690565b600081815260026020526040812060058101546001600160a01b03163314612c5d576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c7920626f72726f7765722063616e20617070726f766500000000000000604482015290519081900360640190fd5b8054610100900460ff16612ca457805461ff00191661010017815560405183907f6fb7fd1eda743aa3eb32c69f3b8cf14a5aeadf26db51057a7c5c78ba10eac8a490600090a25b50600192915050565b6000546001600160a01b031681565b6000838152600260205260408120600581015481546001600160a01b0390911690610100900460ff16612e4e57612cfb816001600160a01b0316613c45565b8015612d225750612d226001600160a01b0382166376ba600960e01b63ffffffff613c4b16565b15612d3857612d318682613cee565b9250612e4e565b604080516020808201899052731cda59db88185c1c1c9bdd99481c995c5d595cdd60621b82840152825160348184030181526054830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000607484015260908084018290528451808503909101815260b0840180865281519184019190912060d0601f8b01859004909402850184019095528881529093600093612dff939192918b918b918291018382808284376000920191909152506148f592505050565b9050806001600160a01b0316836001600160a01b03161415612e4b5760405188907fac4faa318b3929891fe5ee57344cce181e72bced7246f5aa4a788ab61e7bb5d290600090a2600194505b50505b828015612e6257508154610100900460ff16155b15612ea057815461ff00191661010017825560405186907f6fb7fd1eda743aa3eb32c69f3b8cf14a5aeadf26db51057a7c5c78ba10eac8a490600090a25b50509392505050565b6000908152600260205260409020600101546001600160a01b031690565b6002602081815260009283526040928390208054600180830154838601546003850154600486015460058701546006880154600789015460088a0180548e516101009a8216158b02600019019091169d909d04601f81018d90048d028e018d01909e528d8d5260ff808b169e998b04169c620100008b046001600160401b03169c600160501b909b046001600160801b03169b6001600160a01b03998a169b988a169a978a1699968716989587169796909416959294909290830182828015612fd15780601f10612fa657610100808354040283529160200191612fd1565b820191906000526020600020905b815481529060010190602001808311612fb457829003601f168201915b505050505090508c565b620493e081565b60036020526000908152604090205460ff1681565b6000818152600260205260408120805460ff166130455760405162461bcd60e51b815260040180806020018281038252602a815260200180614ef1602a913960400191505060405180910390fd5b60038101546001600160a01b031633148061306c575060058101546001600160a01b031633145b6130a75760405162461bcd60e51b815260040180806020018281038252602d815260200180614fd9602d913960400191505060405180910390fd5b6130b5600882016000614e8c565b6000838152600260208190526040822080546001600160d01b03191681556001810180546001600160a01b031990811690915591810180548316905560038101805483169055600481018054831690556005810180548316905560068101805490921690915560078101829055906131306008830182614e8c565b5050600083815260036020908152604091829020805460ff191660011790558151338152915185927f5f32c817b1de98e681044c3d78ca791e6018e4c3b4f230e4d85bbcc3815989f392908290030190a250600192915050565b6000908152600260205260409020546201000090046001600160401b031690565b6000818152600260205260408120600401546001600160a01b0316801561234457806001600160a01b031663e5a6b10f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561231357600080fd5b6000868152600260205260408120805460ff16613269576040805162461bcd60e51b815260206004820152601960248201527f52657175657374206973206e6f206c6f6e676572206f70656e00000000000000604482015290519081900360640190fd5b8054610100900460ff166132ae5760405162461bcd60e51b815260040180806020018281038252602b815260200180614f3e602b913960400191505060405180910390fd5b805442620100009091046001600160401b03161161330c576040805162461bcd60e51b8152602060048201526016602482015275151a19481c995c5d595cdd081a5cc8195e1c1a5c995960521b604482015290519081900360640190fd5b805460ff19168082556004820154600091613341916001600160a01b031690600160501b90046001600160801b03168a614985565b6001546005840154604080516323b872dd60e01b81523360048201526001600160a01b0392831660248201526044810185905290519394509116916323b872dd916064808201926020929091908290030181600087803b1580156133a457600080fd5b505af11580156133b8573d6000803e3d6000fd5b505050506040513d60208110156133ce57600080fd5b5051613421576040805162461bcd60e51b815260206004820181905260248201527f4572726f722073656e64696e6720746f6b656e7320746f20626f72726f776572604482015290519081900360640190fd5b604080513381526020810183905281518b927ff701a0be7203a591a078aa39b506b74dcf910d7a73b1f73a4dff4d0df3968361928290030190a2886000809054906101000a90046001600160a01b03166001600160a01b0316632ed042658460020160009054906101000a90046001600160a01b0316338660040160009054906101000a90046001600160a01b03166136e688604051806101800160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a90046001600160401b03166001600160401b03166001600160401b0316815260200160008201600a9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020016001820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016004820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016005820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016006820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160078201548152602001600882018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561269d5780601f106126725761010080835404028352916020019161269d565b6040516001600160e01b031960e087901b1681526001600160a01b0380861660048301908152858216602484015290841660448301526064820183905260a06084830190815260088c0180546002600019610100600184161502019091160460a48501819052909360c40190849080156137a15780601f10613776576101008083540402835291602001916137a1565b820191906000526020600020905b81548152906001019060200180831161378457829003601f168201915b50509650505050505050602060405180830381600087803b1580156137c557600080fd5b505af11580156137d9573d6000803e3d6000fd5b505050506040513d60208110156137ef57600080fd5b505114613843576040805162461bcd60e51b815260206004820152601760248201527f4572726f72206372656174696e67207468652064656274000000000000000000604482015290519081900360640190fd5b6001600160a01b03871615613aaf57600082600701549050876001600160a01b03166002018360010160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550868360070181905550876001600160a01b031663bb26d9d1308c60001c898d6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561391d578181015183820152602001613905565b50505050905090810190601f16801561394a5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561397d578181015183820152602001613965565b50505050905090810190601f1680156139aa5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156139cd57600080fd5b505af11580156139e1573d6000803e3d6000fd5b505050506040513d60208110156139f757600080fd5b5051613a4a576040805162461bcd60e51b815260206004820152601c60248201527f436f7369676e206d6574686f642072657475726e65642066616c736500000000604482015290519081900360640190fd5b60018301546001600160a01b03898116911614613aa9576040805162461bcd60e51b8152602060048201526018602482015277436f7369676e6572206469646e27742063616c6c6261636b60401b604482015290519081900360640190fd5b60078301555b60068201546001600160a01b03168015613c0b57806001600160a01b031663d911b43f620493e08c33896040518563ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613b43578181015183820152602001613b2b565b50505050905090810190601f168015613b705780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600088803b158015613b9157600080fd5b5087f1158015613ba5573d6000803e3d6000fd5b50505050506040513d6020811015613bbc57600080fd5b5051613c0b576040805162461bcd60e51b815260206004820152601960248201527852656a6563746564206279206c6f616e2063616c6c6261636b60381b604482015290519081900360640190fd5b5060019998505050505050505050565b6000613c2b87878787878761484d565b979650505050505050565b6001546001600160a01b031681565b3b151590565b60008080613c60856301ffc9a760e01b614ae8565b915091508160001480613c71575080155b15613c8157600092505050612bca565b613c93856001600160e01b0319614ae8565b9092509050811580613ca457508015155b15613cb457600092505050612bca565b613cbe8585614ae8565b9092509050600182148015613cd35750806001145b15613ce357600192505050612bca565b506000949350505050565b6040805160248082018590528251808303909101815260449091019091526020810180516001600160e01b03166376ba600960e01b1790526000907fdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a84189082908190613d5c908690614b1c565b91509150818015613d6c57508281145b93508315613da45760405186907fbcd1a053efeeac2159254030853620c82ddeffb174f76982dc0dd1083648ade390600090a2613e1b565b81613de45760408051828152905187917f04843e870d380c72a3ffb37e0afa8b10e7948a34dee4ef9c1d6754cc0699c3d3919081900360200190a2613e1b565b60408051828152905187917f7b550df26fb29cebc893b0071262bded4c36eb15da43317bf72c3f9f5aeb554a919081900360200190a25b50505092915050565b600081830184511015613e7e576040805162461bcd60e51b815260206004820152601b60248201527f52656164696e67206279746573206f7574206f6620626f756e64730000000000604482015290519081900360640190fd5b826020018401519050816020038015613e9d576008810260020a820491505b509392505050565b6000806000806000806000806000613ebc8b614bf1565b959c50939a509198509650945092509050613ee7878583613ee08f60886014613e24565b878761484d565b97506000809054906101000a90046001600160a01b03166001600160a01b031663f57ae7b93088888c8f6040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613fab578181015183820152602001613f93565b50505050905090810190601f168015613fd85780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b158015613ff957600080fd5b505afa15801561400d573d6000803e3d6000fd5b505050506040513d602081101561402357600080fd5b50519b979a509698505050505050505050565b60006123476140488460246014613e24565b6140558560006010613e24565b84614985565b600080546001600160a01b0316632ed0426561407a8660106014613e24565b336140888860246014613e24565b6040516001600160e01b031960e086901b1681526001600160a01b0380851660048301908152848216602484015290831660448301526064820189905260a0608483019081528a5160a48401528a518a938c93929160c490910190602085019080838360005b838110156141065781810151838201526020016140ee565b50505050905090810190601f1680156141335780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561415657600080fd5b505af115801561416a573d6000803e3d6000fd5b505050506040513d602081101561418057600080fd5b5051949350505050565b60008581526003602052604090205460ff16156141e4576040805162461bcd60e51b815260206004820152601360248201527214d95d1d1b19481dd85cc818d85b98d95b1959606a1b604482015290519081900360640190fd5b7fdfcb15a077f54a681c23131eacdfd6e12b5e099685b492d382c3fd8bfc1e9a2a851860006142168660386014613e24565b905060006142278760746014613e24565b9050600061423d6001600160a01b038416613c45565b156144025783836001600160a01b031663b700f67a8a8a60018e60001c6040518563ffffffff1660e01b815260040180806020018060200185151515158152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156142ba5781810151838201526020016142a2565b50505050905090810190601f1680156142e75780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b8381101561431a578181015183820152602001614302565b50505050905090810190601f1680156143475780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561436a57600080fd5b505af115801561437e573d6000803e3d6000fd5b505050506040513d602081101561439457600080fd5b5051146143d25760405162461bcd60e51b8152600401808060200182810382526023815260200180614f1b6023913960400191505060405180910390fd5b60405189907f168544dde877630d31a353bc62115efd38d8e072b48761461075d8421620e77290600090a261452a565b506040805160208082018b90527f7369676e20736574746c65206c656e6420617320626f72726f77657200000000828401528251603c818403018152605c830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000607c84015260988084018290528451808503909101815260b8909301909352815191012061449990866148f5565b6001600160a01b0316836001600160a01b0316146144fe576040805162461bcd60e51b815260206004820152601a60248201527f496e76616c696420626f72726f776572207369676e6174757265000000000000604482015290519081900360640190fd5b60405189907f04acecab035917c895d49033509a027f3fbb1913e978eec824926f605370653b90600090a25b816001600160a01b0316836001600160a01b03161461484257614555826001600160a01b0316613c45565b1561471a5783826001600160a01b031663b700f67a8a8a60008e60001c6040518563ffffffff1660e01b815260040180806020018060200185151515158152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b8381101561463257818101518382015260200161461a565b50505050905090810190601f16801561465f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561468257600080fd5b505af1158015614696573d6000803e3d6000fd5b505050506040513d60208110156146ac57600080fd5b5051146146ea5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f8b6022913960400191505060405180910390fd5b60405189907f025f21426e185fab3bf170a9374c750b17a510c3ed51549fa4ff068dbca6605790600090a2614842565b506040805160208082018b90527f7369676e20736574746c65206c656e642061732063726561746f720000000000828401528251603b818403018152605b830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000607b84015260978084018290528451808503909101815260b790930190935281519101206147b190876148f5565b6001600160a01b0316826001600160a01b031614614816576040805162461bcd60e51b815260206004820152601960248201527f496e76616c69642063726561746f72207369676e617475726500000000000000604482015290519081900360640190fd5b60405189907f3971d1c591487c96ba2561ab5f74f00001a6134408897ab8b0124c1673055dd290600090a25b505050505050505050565b6040805160809790971b6001600160801b031916602080890191909152606096871b6001600160601b031990811660308a015295871b861660448901529390951b9093166058860152606c85015260c09190911b6001600160c01b031916608c840152815180840360740181526094909301909152815191012090565b6000612bca82606001518361010001518460c00151856101200151866101400151876040015161484d565b602081015160408201516041830151600092919060ff16601b81101561491957601b015b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015614970573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006001600160a01b03841661499c575081612347565b600080856001600160a01b031663b077c09b856040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156149fb5781810151838201526020016149e3565b50505050905090810190601f168015614a285780820380516001836020036101000a031916815260200191505b50925050506040805180830381600087803b158015614a4657600080fd5b505af1158015614a5a573d6000803e3d6000fd5b505050506040513d6040811015614a7057600080fd5b508051602091820151604080516001600160a01b038b1681529384018390528381018290525191945092507f0b53fa0f90e4773f861d84b5da681ae7b3dd6b29358fdb4a38ba8dec13fc80f39181900360600190a180614ad6838763ffffffff614c7a16565b81614add57fe5b049695505050505050565b6040516301ffc9a760e01b8082526004820183905260009182919060208160248189617530fa905190969095509350505050565b6000806060846001600160a01b0316846040518082805190602001908083835b60208310614b5b5780518252601f199092019160209182019101614b3c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614bbd576040519150601f19603f3d011682016040523d82523d6000602084013e614bc2565b606091505b508051919450915015614be957808060200190516020811015614be457600080fd5b505191505b509250929050565b6000806000806000806000806000806000806000614c198e6010601480601460206008614cd9565b9550955095509550955095508560001c9c508460001c9b508360001c9a508260001c99508160001c98508060001c9750614c648e600860206014806014601001010101016014613e24565b60001c9650505050505050919395979092949650565b600082614c8957506000612bca565b82820282848281614c9657fe5b0414612347576040805162461bcd60e51b815260206004820152600d60248201526c4d756c74206f766572666c6f7760981b604482015290519081900360640190fd5b600080600080600080600060208e01805197508d6020038015614d02576008810260020a890498505b8e82019250825197508d60200390508015614d23576008810260020a880497505b50908c01805195509060208c90038015614d43576008810260020a870496505b50908b01805194509060208b90038015614d63576008810260020a860495505b50908a01805193509060208a90038015614d83576008810260020a850494505b50908901805192509060208990038015614da3576008810260020a840493505b508e51910390811115614dfd576040805162461bcd60e51b815260206004820152601b60248201527f52656164696e67206279746573206f7574206f6620626f756e64730000000000604482015290519081900360640190fd5b509750975097509750975097915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614e4f57805160ff1916838001178555614e7c565b82800160010185558215614e7c579182015b82811115614e7c578251825591602001919060010190614e61565b50614e88929150614ed3565b5090565b50805460018160011615610100020316600290046000825580601f10614eb25750614ed0565b601f016020900490600052602060002090810190614ed09190614ed3565b50565b614eed91905b80821115614e885760008155600101614ed9565b9056fe52657175657374206973206e6f206c6f6e676572206f70656e206f72206e6f7420726571756573746564426f72726f77657220636f6e74726163742072656a656374656420746865206c6f616e5468652072657175657374206973206e6f7420617070726f7665642062792074686520626f72726f77657254686520726571756573742073686f756c642068617665206120626f72726f77657243726561746f7220636f6e74726163742072656a656374656420746865206c6f616e4f6e6c7920626f72726f776572206f722063726561746f722063616e2063616e63656c206120736574746c654f6e6c7920626f72726f776572206f722063726561746f722063616e2063616e63656c20612072657175657374a265627a7a72315820636d7e7ae7f2447934281cf8ec9198f51a4e88c8f8d6452f62845a122b95226a64736f6c634300050b0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000080db22675dad70e44b64029510778583187faddb
-----Decoded View---------------
Arg [0] : _debtEngine (address): 0x80db22675DAd70e44b64029510778583187fadDb
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000080db22675dad70e44b64029510778583187faddb
Deployed Bytecode Sourcemap
68971:28203:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68971:28203:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72727:98;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72727:98:0;;:::i;:::-;;;;-1:-1:-1;;;;;72727:98:0;;;;;;;;;;;;;;71732:106;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71732:106:0;;:::i;:::-;;;;;;;;;;;;;;;;;;73252:96;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73252:96:0;;:::i;:::-;;;;;;;;;;;;;;;;71047:105;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71047:105:0;;:::i;76542:1980::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;76542:1980:0;;;;-1:-1:-1;;;;;76542:1980:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;76542:1980:0;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;76542:1980:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;76542:1980:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;76542:1980:0;;-1:-1:-1;76542:1980:0;-1:-1:-1;76542:1980:0;:::i;86438:3198::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;86438:3198:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;;;;;;;-1:-1:-1;86438:3198:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;-1:-1:-1;;;;;86438:3198:0;;;;;;;;;;;-1:-1:-1;86438:3198:0;-1:-1:-1;86438:3198:0;;;;-1:-1:-1;86438:3198:0;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;;;;;;;-1:-1:-1;86438:3198:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;;;;;;;-1:-1:-1;86438:3198:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;;;;;;;-1:-1:-1;86438:3198:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;;;;;;;-1:-1:-1;86438:3198:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;86438:3198:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86438:3198:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;86438:3198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;86438:3198:0;;-1:-1:-1;86438:3198:0;;-1:-1:-1;;;;;86438:3198:0:i;71987:157::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71987:157:0;;:::i;89644:575::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;89644:575:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;89644:575:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;89644:575:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;89644:575:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;89644:575:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;89644:575:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;89644:575:0;;-1:-1:-1;89644:575:0;-1:-1:-1;89644:575:0;:::i;71844:137::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71844:137:0;;:::i;72270:202::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72270:202:0;;:::i;85481:949::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;85481:949:0;;;;-1:-1:-1;;;;;85481:949:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;85481:949:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;85481:949:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;85481:949:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;85481:949:0;;-1:-1:-1;85481:949:0;-1:-1:-1;85481:949:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;85481:949:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75963:241;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75963:241:0;;:::i;74300:100::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;74300:100:0;;:::i;72150:114::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72150:114:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;72150:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74740:785;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;74740:785:0;;;;-1:-1:-1;;;;;74740:785:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74740:785:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;74740:785:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;74740:785:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;74740:785:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;74740:785:0;;-1:-1:-1;74740:785:0;;-1:-1:-1;;;;;74740:785:0:i;72478:111::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72478:111:0;;:::i;83862:712::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83862:712:0;;;;;;;:::i;72621:100::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72621:100:0;;:::i;79415:352::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;79415:352:0;;:::i;69181:28::-;;;:::i;79775:1352::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;79775:1352:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;79775:1352:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;79775:1352:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;79775:1352:0;;-1:-1:-1;79775:1352:0;-1:-1:-1;79775:1352:0;:::i;71158:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71158:109:0;;:::i;69244:43::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69244:43:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69244:43:0;;;;;;;;;-1:-1:-1;;;;;69244:43:0;;;;;;-1:-1:-1;;;;;69244:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;69244:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69127:45;;;:::i;69294:47::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69294:47:0;;:::i;83322:532::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83322:532:0;;:::i;73354:111::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73354:111:0;;:::i;71273:216::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71273:216:0;;:::i;81135:2179::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;81135:2179:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;81135:2179:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;81135:2179:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;81135:2179:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;81135:2179:0;;-1:-1:-1;;;;;81135:2179:0;;;;;;;;;;;-1:-1:-1;81135:2179:0;-1:-1:-1;81135:2179:0;;;;-1:-1:-1;81135:2179:0;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;81135:2179:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;81135:2179:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;81135:2179:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;81135:2179:0;;;;;;;;-1:-1:-1;81135:2179:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;81135:2179:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;81135:2179:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;81135:2179:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;81135:2179:0;;-1:-1:-1;81135:2179:0;;-1:-1:-1;;;;;81135:2179:0:i;75533:422::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;75533:422:0;;-1:-1:-1;;;;;75533:422:0;;;;;;-1:-1:-1;;;;;75533:422:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;75533:422:0;;:::i;69216:19::-;;;:::i;72727:98::-;72783:7;72801:13;;;:8;:13;;;;;:21;;;-1:-1:-1;;;;;72801:21:0;;72727:98::o;71732:106::-;71789:4;71804:22;;;:8;:22;;;;;:31;;;;;;;71732:106::o;73252:96::-;73307:7;73325:13;;;:8;:13;;;;;:20;-1:-1:-1;;;73325:20:0;;-1:-1:-1;;;;;73325:20:0;;73252:96::o;71047:105::-;71102:7;71120:22;;;:8;:22;;;;;:29;;;-1:-1:-1;;;;;71120:29:0;;71047:105::o;76542:1980::-;76809:10;-1:-1:-1;;;;;76840:23:0;;76832:70;;;;-1:-1:-1;;;76832:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76921:33;;-1:-1:-1;;;76921:33:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;76921:22:0;;;;;76944:9;;;;76921:33;;;;;76944:9;;;;76921:33;1::-1;99:1;81:16;;;74:27;76921:33:0;;137:4:-1;117:14;;;-1:-1;;113:30;157:16;;;;-1:-1;76921:33:0;;-1:-1:-1;76921:33:0;;-1:-1:-1;;;76921:33:0;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;76921:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76921:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76921:33:0;76913:72;;;;;-1:-1:-1;;;76913:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;77003:225;77024:7;77046:9;77070:10;77095:6;77116:7;77138:9;77162:5;77182:11;77208:9;;77003:225;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;77003:6:0;;-1:-1:-1;;;77003:225:0:i;:::-;77250:19;;;;:15;:19;;;;;;76998:230;;-1:-1:-1;77250:19:0;;77249:20;77241:54;;;;;-1:-1:-1;;;77241:54:0;;;;;;;;;;;;-1:-1:-1;;;77241:54:0;;;;;;;;;;;;;;;77349:1;77316:12;;;:8;:12;;;;;:21;;;-1:-1:-1;;;;;77316:21:0;:35;77308:69;;;;;-1:-1:-1;;;77308:69:0;;;;;;;;;;;;-1:-1:-1;;;77308:69:0;;;;;;;;;;;;;;;77390:13;77420:9;-1:-1:-1;;;;;77406:23:0;:10;-1:-1:-1;;;;;77406:23:0;;77390:39;;77457:401;;;;;;;;77486:4;77457:401;;;;;;77515:8;77457:401;;;;;;77835:11;-1:-1:-1;;;;;77457:401:0;;;;;77581:7;-1:-1:-1;;;;;77457:401:0;;;;;77556:1;-1:-1:-1;;;;;77457:401:0;;;;;77610:6;-1:-1:-1;;;;;77457:401:0;;;;;77640:10;-1:-1:-1;;;;;77457:401:0;;;;;77673:7;-1:-1:-1;;;;;77457:401:0;;;;;77705:9;-1:-1:-1;;;;;77457:401:0;;;;;77739:9;-1:-1:-1;;;;;77457:401:0;;;;;77769:5;77457:401;;;;77799:9;;77457:401;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;-1:-1;77457:401:0;;;;-1:-1:-1;;77442:12:0;;;:8;:12;;;;;;;;;:416;;;;;;;;;;;;;;;;-1:-1:-1;;77442:416:0;;;;;;;;;;-1:-1:-1;;77442:416:0;;;;;;;;-1:-1:-1;;77442:416:0;;-1:-1:-1;;;;;77442:416:0;;;;;;;;;;;-1:-1:-1;;;;;;;;77442:416:0;-1:-1:-1;;;;;;;;77442:416:0;;;;;;;;;;;;;;-1:-1:-1;77442:416:0;;;;-1:-1:-1;;;;;;77442:416:0;;;-1:-1:-1;;;;;77442:416:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:12;;-1:-1:-1;77442:416:0;;;;;;;;;;;;:::i;:::-;;;;;77900:2;77876:245;77917:7;77939:6;77960:10;77985:7;78007:9;78031;78055:5;78075:9;;78099:11;77876:245;;;;-1:-1:-1;;;;;77876:245:0;-1:-1:-1;;;;;77876:245:0;;;;;;-1:-1:-1;;;;;77876:245:0;-1:-1:-1;;;;;77876:245:0;;;;;;-1:-1:-1;;;;;77876:245:0;-1:-1:-1;;;;;77876:245:0;;;;;;-1:-1:-1;;;;;77876:245:0;-1:-1:-1;;;;;77876:245:0;;;;;;-1:-1:-1;;;;;77876:245:0;-1:-1:-1;;;;;77876:245:0;;;;;;-1:-1:-1;;;;;77876:245:0;-1:-1:-1;;;;;77876:245:0;;;;;;;;;;;;;;-1:-1:-1;;;;;77876:245:0;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;;74:27;77876:245:0;;137:4:-1;117:14;;;-1:-1;;113:30;157:16;;;77876:245:0;;;;-1:-1:-1;77876:245:0;;-1:-1:-1;;;;;;;;;;;;77876:245:0;78139:8;78134:311;;78233:22;:9;-1:-1:-1;;;;;78233:20:0;;:22::i;:::-;:64;;;;-1:-1:-1;78259:38:0;-1:-1:-1;;;;;78259:26:0;;-1:-1:-1;;;78259:38:0;:26;:38;:::i;:::-;78229:205;;;78329:38;78353:2;78357:9;78329:23;:38::i;:::-;78386:12;;;;:8;:12;;;;;:32;;-1:-1:-1;;78386:32:0;;;;;;;;;;-1:-1:-1;78229:205:0;78461:8;78457:58;;;78491:12;;78500:2;;78491:12;;;;;78457:58;76542:1980;;;;;;;;;;;;:::o;86438:3198::-;86793:10;86911:3;86861:46;86866:12;85179:15;85241:1;86861:4;:46::i;:::-;86853:61;86845:97;;;;;-1:-1:-1;;;86845:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;86974:17;87020:39;87035:12;87049:9;87020:14;:39::i;:::-;87113:1;87080:12;;;:8;:12;;;;;:21;;;87002:57;;-1:-1:-1;87002:57:0;-1:-1:-1;;;;;;87080:21:0;:35;87072:69;;;;;-1:-1:-1;;;87072:69:0;;;;;;;;;;;;-1:-1:-1;;;87072:69:0;;;;;;;;;;;;;;;87194:14;87211:43;87228:12;87242:11;87211:16;:43::i;:::-;87287:5;;87194:60;;-1:-1:-1;;;;;;87287:5:0;:18;87324:10;87369:42;87374:12;84959:19;84912:2;87369:4;:42::i;:::-;87287:166;;;-1:-1:-1;;;;;;87287:166:0;;;;;;;-1:-1:-1;;;;;87287:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87361:51;87287:166;;;;5:2:-1;;;;30:1;27;20:12;5:2;87287:166:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87287:166:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;87287:166:0;87265:248;;;;;-1:-1:-1;;;87265:248:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87695:2;87578:113;87608:12;87639:9;87667;87578:11;:113::i;:::-;:119;87556:197;;;;;-1:-1:-1;;;87556:197:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;87771:35;;;87787:10;87771:35;;;;;;;;;;87783:2;;87771:35;;;;;;;;87868:828;;;;;;;;-1:-1:-1;87868:828:0;;;;;;;;;;88636:46;88641:12;85179:15;85241:1;88636:4;:46::i;:::-;-1:-1:-1;;;;;87868:828:0;;;;;88004:38;88009:12;88628:55;84669:2;88004:4;:38::i;:::-;-1:-1:-1;;;;;87868:828:0;;;-1:-1:-1;;;;;87868:828:0;;;;;;;;88082:36;88087:12;84669:2;84807;88082:4;:36::i;:::-;-1:-1:-1;;;;;87868:828:0;;;;;88160:40;88165:12;85286:27;85023:2;88160:4;:40::i;:::-;-1:-1:-1;;;;;87868:828:0;;;;;88241:38;88246:12;84852:17;84807:2;88241:4;:38::i;:::-;-1:-1:-1;;;;;87868:828:0;;;;;88322:42;88327:12;84959:19;84912:2;88322:4;:42::i;:::-;-1:-1:-1;;;;;87868:828:0;;;;;88407:42;88412:12;85404:21;85357:2;88407:4;:42::i;:::-;-1:-1:-1;;;;;87868:828:0;;;;;;;;;;88472:23;;:88;;88525:34;88530:12;85066:23;85130:2;88525:4;:34::i;:::-;88472:88;;;88498:16;88472:88;87868:828;;;;;;;;;-1:-1:-1;87853:12:0;;;:8;:12;;;;;;;;:843;;;;;;;;;;;;;;;;-1:-1:-1;;87853:843:0;;;;;;;;;;-1:-1:-1;;87853:843:0;;;;;;;;-1:-1:-1;;87853:843:0;;-1:-1:-1;;;;;87853:843:0;;;;;;;;;;;-1:-1:-1;;;;;;;;87853:843:0;-1:-1:-1;;;;;;;;87853:843:0;;;;;;;;;;;;;;-1:-1:-1;87853:843:0;;;;-1:-1:-1;;;;;;87853:843:0;;;-1:-1:-1;;;;;87853:843:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:12;;:843;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;88709:23:0;88735:12;;;:8;:12;;;;;88792:81;88744:2;88822:12;88836:9;88847:11;88860:12;88792:25;:81::i;:::-;-1:-1:-1;;;;;88920:23:0;;;88916:405;;88995:9;-1:-1:-1;;;;;88987:18:0;89008:1;88987:22;88960:7;:16;;;:50;;;;;-1:-1:-1;;;;;88960:50:0;;;;;-1:-1:-1;;;;;88960:50:0;;;;;;89042:9;-1:-1:-1;;;;;89033:33:0;;89075:4;89090:2;89082:11;;89095:13;89110:11;89033:89;;;;;;;;;;;;;-1:-1:-1;;;;;89033:89:0;-1:-1:-1;;;;;89033:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;89033:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89033:89:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;89033:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;89033:89:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;89033:89:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;89033:89:0;89025:130;;;;;-1:-1:-1;;;89025:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;89178:16;;;;-1:-1:-1;;;;;89178:29:0;;;:16;;:29;89170:66;;;;;-1:-1:-1;;;89170:66:0;;;;;;;;;;;;-1:-1:-1;;;89170:66:0;;;;;;;;;;;;;;;89274:34;89279:12;85066:23;85130:2;89274:4;:34::i;:::-;89251:12;;;:58;88916:405;89368:16;89403:42;89408:12;85404:21;85357:2;89403:4;:42::i;:::-;89395:51;-1:-1:-1;;;;;;89462:22:0;;;89458:171;;89509:78;;-1:-1:-1;;;89509:78:0;;;;;;;;89561:10;89509:78;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;89509:29:0;;;;;69166:6;;89557:2;;89561:10;;89573:13;;89509:78;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;89509:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;89509:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;89509:78:0;;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;89509:78:0;89501:116;;;;;-1:-1:-1;;;89501:116:0;;;;;;;;;;;;-1:-1:-1;;;89501:116:0;;;;;;;;;;;;;;;86438:3198;;;;;;;;;;;;;;;:::o;71987:157::-;72053:7;72077:22;;;:8;:22;;;;;;;;:28;;;;72071:70;;-1:-1:-1;;;72071:70:0;;;;;;;;;;-1:-1:-1;;;;;72077:28:0;;;;72071:56;;:70;;;;;72077:22;;72071:70;;;;;72077:28;72071:70;;;5:2:-1;;;;30:1;27;20:12;5:2;72071:70:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72071:70:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72071:70:0;;71987:157;-1:-1:-1;;71987:157:0:o;89644:575::-;89764:4;89782:10;89798:39;89813:12;;89798:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;89798:39:0;;;;137:4:-1;89798:39:0;;;;;;;;;;;;;;;;;;-1:-1:-1;89827:9:0;;-1:-1:-1;89827:9:0;;;;89798:39;;89827:9;;;;89798:39;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;89798:14:0;;-1:-1:-1;;;89798:39:0:i;:::-;89781:56;;;89900:42;89905:12;;89900:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;84959:19:0;;-1:-1:-1;84912:2:0;;-1:-1:-1;89900:4:0;;-1:-1:-1;89900:42:0:i;:::-;-1:-1:-1;;;;;89870:74:0;:10;:74;;:163;;;89991:40;89996:12;;89991:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;85286:27:0;;-1:-1:-1;85023:2:0;;-1:-1:-1;89991:4:0;;-1:-1:-1;89991:40:0:i;:::-;-1:-1:-1;;;;;89961:72:0;:10;:72;89870:163;89848:257;;;;-1:-1:-1;;;89848:257:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90116:19;;;;:15;:19;;;;;;;;;:26;;-1:-1:-1;;90116:26:0;90138:4;90116:26;;;90158:29;;90176:10;90158:29;;;;90132:2;;90158:29;;;;;;;;;-1:-1:-1;90207:4:0;;89644:575;-1:-1:-1;;;;;89644:575:0:o;71844:137::-;71900:7;71924:22;;;:8;:22;;;;;;;;:28;;;;71918:60;;-1:-1:-1;;;71918:60:0;;;;;;;;;;-1:-1:-1;;;;;71924:28:0;;;;71918:46;;:60;;;;;71924:22;;71918:60;;;;;71924:28;71918:60;;;5:2:-1;;;;30:1;27;20:12;72270:202:0;72325:7;72371:22;;;:8;:22;;;;;72411:12;;;;:53;;72430:10;;:34;;;-1:-1:-1;;;72430:34:0;;;;;;;;;;-1:-1:-1;;;;;72430:10:0;;;;:20;;:34;;;;;;;;;;;;;;;:10;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;72430:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72430:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72430:34:0;72411:53;;;72426:1;72411:53;72404:60;72270:202;-1:-1:-1;;;72270:202:0:o;85481:949::-;85845:209;;;-1:-1:-1;;;;;;85845:209:0;;;;;;;;;-1:-1:-1;;;;;;85782:24:0;85845:209;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;85845:209:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;85845:209:0;;;;;;;85808:10;;86087:168;85876:7;85941:9;86011:8;86034:9;85965:5;85985:11;86087:18;:168::i;:::-;86067:188;;86273:10;;;;;;;;;-1:-1:-1;;;;;86273:10:0;-1:-1:-1;;;;;86273:19:0;;86315:4;86335:6;86356:7;86378:9;86402;;86273:149;;;;;;;;;;;;;-1:-1:-1;;;;;86273:149:0;-1:-1:-1;;;;;86273:149:0;;;;;;-1:-1:-1;;;;;86273:149:0;-1:-1:-1;;;;;86273:149:0;;;;;;-1:-1:-1;;;;;86273:149:0;-1:-1:-1;;;;;86273:149:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;86273:149:0;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;86273:149:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;86273:149:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;86273:149:0;85481:949;;86273:149;;-1:-1:-1;85481:949:0;;-1:-1:-1;;;;;;;;;;;85481:949:0:o;75963:241::-;76021:7;76067:13;;;:8;:13;;;;;76099:16;;;;-1:-1:-1;;;;;76099:16:0;76091:65;;;;;-1:-1:-1;;;76091:65:0;;;;;;;;;;;;-1:-1:-1;;;76091:65:0;;;;;;;;;;;;;;;76174:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;76174:22:0;;;;;-1:-1:-1;;;76174:22:0;;;-1:-1:-1;;;;;76174:22:0;;;;;;;;;;-1:-1:-1;;;;;76174:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;76174:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:22::i;74300:100::-;74357:7;74375:13;;;:8;:13;;;;;:22;;;-1:-1:-1;;;;;74375:22:0;;74300:100::o;72150:114::-;72230:22;;;;:8;:22;;;;;;;;;:31;;72223:38;;;;;;;;;;-1:-1:-1;;72223:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;72207:12;;72230:31;;72223:38;;72230:31;72223:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72150:114;;;:::o;74740:785::-;75026:7;75046:20;75069:168;75102:7;75124:9;75148:8;75171:9;75195:5;75215:11;75069:18;:168::i;:::-;75343:10;;75281:225;;-1:-1:-1;;;75281:225:0;;;;;;;;;;;-1:-1:-1;;;;;;75281:225:0;;;;;;;75380:4;75281:225;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75322:1:0;;-1:-1:-1;;;;;75343:10:0;;;;75380:4;;75281:225;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;75281:225:0;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;75281:225:0;;;75257:260;;;;;;75250:267;;;74740:785;;;;;;;;;;;:::o;72478:111::-;72531:7;72558:10;;:23;;;-1:-1:-1;;;72558:23:0;;;;;;;;;;-1:-1:-1;;;;;72558:10:0;;;;:18;;:23;;;;;;;;;;;;;;;:10;:23;;;5:2:-1;;;;30:1;27;20:12;83862:712:0;83924:4;83967:22;;;:8;:22;;;;;84008:16;;;;-1:-1:-1;;;;;84008:16:0;84000:68;;;;;-1:-1:-1;;;84000:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;84087:18;;84108:3;84087:18;;;;-1:-1:-1;;;;;84087:18:0;:24;84079:55;;;;;-1:-1:-1;;;84079:55:0;;;;;;;;;;;;-1:-1:-1;;;84079:55:0;;;;;;;;;;;;;;;84153:16;;;;84189:10;84203:1;84181:23;-1:-1:-1;;;;;84153:52:0;;;:16;;:52;84145:83;;;;;-1:-1:-1;;;84145:83:0;;;;;;;;;;;;-1:-1:-1;;;84145:83:0;;;;;;;;;;;;;;;84239:16;;;:29;;-1:-1:-1;;;;;;84239:29:0;84258:10;84239:29;;;84283:10;;84279:209;;84333:5;84317:7;:12;;;:21;;84309:56;;;;;-1:-1:-1;;;84309:56:0;;;;;;;;;;;;-1:-1:-1;;;84309:56:0;;;;;;;;;;;;;;;84388:5;;;84407:10;:23;;;-1:-1:-1;;;84407:23:0;;;;;;;;;;-1:-1:-1;;;;;84388:5:0;;;;:18;;84407:10;;:18;;:23;;;;;;;;;;;;;;:10;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;84407:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84407:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84407:23:0;84388:62;;;-1:-1:-1;;;;;;84388:62:0;;;;;;;-1:-1:-1;;;;;84388:62:0;;;;;;;84432:10;84388:62;;;;;;;;;;;;;;;;84407:23;;84388:62;;;;;;;-1:-1:-1;84388:62:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;84388:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84388:62:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84388:62:0;84380:96;;;;;-1:-1:-1;;;84380:96:0;;;;;;;;;;;;-1:-1:-1;;;84380:96:0;;;;;;;;;;;;;;;84503:41;;;84526:10;84503:41;;;;;;;;;;84520:3;;84503:41;;;;;;;;84562:4;84555:11;;;83862:712;;;;;:::o;72621:100::-;72678:7;72696:13;;;:8;:13;;;;;:22;;;-1:-1:-1;;;;;72696:22:0;;72621:100::o;79415:352::-;79486:4;79529:13;;;:8;:13;;;;;79575:16;;;;-1:-1:-1;;;;;79575:16:0;79561:10;:30;79553:68;;;;;-1:-1:-1;;;79553:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;79637:16;;;;;;;79632:106;;79670:23;;-1:-1:-1;;79670:23:0;;;;;79713:13;;79722:3;;79713:13;;79670:16;;79713:13;79632:106;-1:-1:-1;79755:4:0;;79415:352;-1:-1:-1;;79415:352:0:o;69181:28::-;;;-1:-1:-1;;;;;69181:28:0;;:::o;79775:1352::-;79890:13;79942;;;:8;:13;;;;;79985:16;;;;80019;;-1:-1:-1;;;;;79985:16:0;;;;;80019;;;;80014:907;;80056:21;:8;-1:-1:-1;;;;;80056:19:0;;:21::i;:::-;:62;;;;-1:-1:-1;80081:37:0;-1:-1:-1;;;;;80081:25:0;;-1:-1:-1;;;80081:37:0;:25;:37;:::i;:::-;80052:858;;;80150:38;80174:3;80179:8;80150:23;:38::i;:::-;80139:49;;80052:858;;;80277:118;;;;;;;;;;-1:-1:-1;;;80277:118:0;;;;;;22:32:-1;26:21;;;22:32;6:49;;80277:118:0;;;;;80245:169;;;;;;80521:144;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;80521:144:0;;;;;;80485:203;;;;;;;;;80452:288;;;;;;;;;;;;;;;;;;;;80245:169;;80229:13;;80452:288;;80485:203;;80521:144;80711:10;;;;;;80452:288;80711:10;;;;80452:288;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;80452:10:0;;-1:-1:-1;;;80452:288:0:i;:::-;80435:305;;80777:6;-1:-1:-1;;;;;80765:18:0;:8;-1:-1:-1;;;;;80765:18:0;;80761:134;;;80813:24;;80833:3;;80813:24;;;;;80871:4;80860:15;;80761:134;80052:858;;;81006:8;:29;;;;-1:-1:-1;81019:16:0;;;;;;;81018:17;81006:29;81002:118;;;81052:23;;-1:-1:-1;;81052:23:0;;;;;81095:13;;81104:3;;81095:13;;81052:16;;81095:13;81002:118;79775:1352;;;;;;;:::o;71158:109::-;71215:7;71233:22;;;:8;:22;;;;;:31;;;-1:-1:-1;;;;;71233:31:0;;71158:109::o;69244:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69244:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69244:43:0;;-1:-1:-1;;;69244:43:0;;;-1:-1:-1;;;;;69244:43:0;;-1:-1:-1;;;;;69244:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;69127:45::-;69166:6;69127:45;:::o;69294:47::-;;;;;;;;;;;;;;;:::o;83322:532::-;83369:4;83412:13;;;:8;:13;;;;;83446:12;;;;83438:67;;;;-1:-1:-1;;;83438:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83538:15;;;;-1:-1:-1;;;;;83538:15:0;83557:10;83538:29;;:63;;-1:-1:-1;83571:16:0;;;;-1:-1:-1;;;;;83571:16:0;83591:10;83571:30;83538:63;83516:158;;;;-1:-1:-1;;;83516:158:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83687:23;83694:16;;;;83687:23;:::i;:::-;83728:13;;;;:8;:13;;;;;;;83721:20;;-1:-1:-1;;;;;;83721:20:0;;;;;;;;-1:-1:-1;;;;;;83721:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83728:13;83721:20;;;;83728:13;83721:20;:::i;:::-;-1:-1:-1;;83752:20:0;;;;:15;:20;;;;;;;;;:27;;-1:-1:-1;;83752:27:0;83775:4;83752:27;;;83797:25;;83811:10;83797:25;;;;83768:3;;83797:25;;;;;;;;;-1:-1:-1;83842:4:0;;83322:532;-1:-1:-1;;83322:532:0:o;73354:111::-;73420:7;73438:13;;;:8;:13;;;;;:24;;;;-1:-1:-1;;;;;73438:24:0;;73354:111::o;71273:216::-;71330:7;71367:22;;;:8;:22;;;;;:29;;;-1:-1:-1;;;;;71367:29:0;71414:20;;:67;;71463:6;-1:-1:-1;;;;;71452:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;81135:2179:0;81364:4;81407:13;;;:8;:13;;;;;81439:12;;;;81431:50;;;;;-1:-1:-1;;;81431:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;81500:16;;;;;;;81492:72;;;;-1:-1:-1;;;81492:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81583:18;;81604:3;81583:18;;;;-1:-1:-1;;;;;81583:18:0;:24;81575:59;;;;;-1:-1:-1;;;81575:59:0;;;;;;;;;;;;-1:-1:-1;;;81575:59:0;;;;;;;;;;;;;;;81647:20;;-1:-1:-1;;81647:20:0;;;;81714:14;;;;-1:-1:-1;;81697:61:0;;-1:-1:-1;;;;;81714:14:0;;-1:-1:-1;;;81730:14:0;;-1:-1:-1;;;;;81730:14:0;81746:11;81697:16;:61::i;:::-;81791:5;;81857:16;;;;81791:122;;;-1:-1:-1;;;81791:122:0;;81828:10;81791:122;;;;-1:-1:-1;;;;;81857:16:0;;;81791:122;;;;;;;;;;;;81680:78;;-1:-1:-1;81791:5:0;;;:18;;:122;;;;;;;;;;;;;;;:5;;:122;;;5:2:-1;;;;30:1;27;20:12;5:2;81791:122:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81791:122:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81791:122:0;81769:204;;;;;-1:-1:-1;;;81769:204:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81991:29;;;82001:10;81991:29;;;;;;;;;;81996:3;;81991:29;;;;;;;;82299:3;82085:10;;;;;;;;;-1:-1:-1;;;;;82085:10:0;-1:-1:-1;;;;;82085:18:0;;82128:7;:13;;;;;;;;;;-1:-1:-1;;;;;82128:13:0;82161:10;82190:7;:14;;;;;;;;;;-1:-1:-1;;;;;82190:14:0;82223:22;82237:7;82223:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;-1:-1:-1;;;;;82223:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82085:210;;-1:-1:-1;;;;;;82085:210:0;;;;;;;-1:-1:-1;;;;;82085:210:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82264:16;;;82085:210;;;-1:-1:-1;;82085:210:0;;;;;;;;;;;;;;;;;82264:16;;82085:210;;;82264:16;;82085:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82085:210:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82085:210:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82085:210:0;:217;82063:290;;;;;-1:-1:-1;;;82063:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;82400:23:0;;;82396:622;;82440:15;82458:7;:12;;;82440:30;;82520:9;-1:-1:-1;;;;;82512:18:0;82533:1;82512:22;82485:7;:16;;;:50;;;;;-1:-1:-1;;;;;82485:50:0;;;;;-1:-1:-1;;;;;82485:50:0;;;;;;82565:14;82550:7;:12;;:29;;;;82640:9;-1:-1:-1;;;;;82631:33:0;;82695:4;82731:3;82723:12;;82758:13;82794:11;82631:193;;;;;;;;;;;;;-1:-1:-1;;;;;82631:193:0;-1:-1:-1;;;;;82631:193:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;82631:193:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82631:193:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;82631:193:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82631:193:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82631:193:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82631:193:0;82605:283;;;;;-1:-1:-1;;;82605:283:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;82911:16;;;;-1:-1:-1;;;;;82911:29:0;;;:16;;:29;82903:66;;;;;-1:-1:-1;;;82903:66:0;;;;;;;;;;;;-1:-1:-1;;;82903:66:0;;;;;;;;;;;;;;;82984:12;;;:22;82396:622;83084:16;;;;-1:-1:-1;;;;;83084:16:0;83115:22;;83111:172;;83175:8;-1:-1:-1;;;;;83162:29:0;;69166:6;83210:3;83215:10;83227:13;83162:79;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;83162:79:0;-1:-1:-1;;;;;83162:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;83162:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;83162:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83162:79:0;;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83162:79:0;83154:117;;;;;-1:-1:-1;;;83154:117:0;;;;;;;;;;;;-1:-1:-1;;;83154:117:0;;;;;;;;;;;;;;;-1:-1:-1;83302:4:0;;81135:2179;-1:-1:-1;;;;;;;;;81135:2179:0:o;75533:422::-;75752:7;75779:168;75812:7;75834:9;75858:8;75881:9;75905:5;75925:11;75779:18;:168::i;:::-;75772:175;75533:422;-1:-1:-1;;;;;;;75533:422:0:o;69216:19::-;;;-1:-1:-1;;;;;69216:19:0;;:::o;14364:167::-;14478:18;14515:8;;;14364:167::o;61210:602::-;61299:4;;;61352:39;61371:9;-1:-1:-1;;;61352:18:0;:39::i;:::-;61316:75;;;;61407:7;61416:1;61407:10;61406:25;;;-1:-1:-1;61421:9:0;;61406:25;61402:70;;;61455:5;61448:12;;;;;;61402:70;61504:40;61523:9;-1:-1:-1;;;;;;61504:18:0;:40::i;:::-;61484:60;;-1:-1:-1;61484:60:0;-1:-1:-1;61560:10:0;;;61559:25;;-1:-1:-1;61574:9:0;;;61559:25;61555:70;;;61608:5;61601:12;;;;;;61555:70;61657:43;61676:9;61687:12;61657:18;:43::i;:::-;61637:63;;-1:-1:-1;61637:63:0;-1:-1:-1;61725:1:0;61716:10;;61715:25;;;;;61730:6;61738:1;61730:9;61715:25;61711:69;;;61764:4;61757:11;;;;;;61711:69;-1:-1:-1;61799:5:0;;61210:602;-1:-1:-1;;;;61210:602:0:o;78530:877::-;78921:88;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;78921:88:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;78638:13:0;;78763:66;78757:72;;;78638:13;;;;78873:147;;78897:9;;78873;:147::i;:::-;78840:180;;;;79044:7;:29;;;;;79065:8;79055:6;:18;79044:29;79033:40;;79148:8;79144:256;;;79178:23;;79197:3;;79178:23;;;;;79144:256;;;79239:7;79234:155;;79272:26;;;;;;;;79286:3;;79272:26;;;;;;;;;;79234:155;;;79344:29;;;;;;;;79361:3;;79344:29;;;;;;;;;;79234:155;78530:877;;;;;;;:::o;63274:365::-;63362:9;63416:6;63407;:15;63392:4;:11;:30;;63384:70;;;;;-1:-1:-1;;;63384:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;63518:6;63514:2;63510:15;63504:4;63500:26;63494:33;63489:38;;63559:6;63555:2;63551:15;63583:2;63580;;;63615:1;63611:2;63607:10;63604:1;63600:18;63597:1;63593:26;63588:31;;63580:2;63474:158;;;;;;:::o;93337:824::-;93460:10;93472:17;93517:14;93546:13;93574:14;93603:16;93634:12;93661:17;93693:15;93722:27;93736:12;93722:13;:27::i;:::-;93502:247;;-1:-1:-1;93502:247:0;;-1:-1:-1;93502:247:0;;-1:-1:-1;93502:247:0;-1:-1:-1;93502:247:0;-1:-1:-1;93502:247:0;-1:-1:-1;93502:247:0;-1:-1:-1;93774:214:0;93502:247;;;93889:42;93894:12;85404:21;85357:2;93889:4;:42::i;:::-;93948:4;93967:10;93774:18;:214::i;:::-;93762:226;;94006:10;;;;;;;;;-1:-1:-1;;;;;94006:10:0;-1:-1:-1;;;;;94006:19:0;;94048:4;94068:5;94088:6;94109:9;94133;94006:147;;;;;;;;;;;;;-1:-1:-1;;;;;94006:147:0;-1:-1:-1;;;;;94006:147:0;;;;;;-1:-1:-1;;;;;94006:147:0;-1:-1:-1;;;;;94006:147:0;;;;;;-1:-1:-1;;;;;94006:147:0;-1:-1:-1;;;;;94006:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;94006:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;94006:147:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;94006:147:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;94006:147:0;;93337:824;;-1:-1:-1;93337:824:0;;-1:-1:-1;;;;;;;;;93337:824:0:o;92549:343::-;92671:7;92698:186;92745:38;92750:12;84852:17;84807:2;92745:4;:38::i;:::-;92808;92813:12;92737:47;84669:2;92808:4;:38::i;:::-;92862:11;92698:16;:186::i;92900:429::-;93044:7;93071:10;;-1:-1:-1;;;;;93071:10:0;:18;93126:36;93131:12;84669:2;84807;93126:4;:36::i;:::-;93180:10;93221:38;93226:12;84852:17;84807:2;93221:4;:38::i;:::-;93071:250;;-1:-1:-1;;;;;;93071:250:0;;;;;;;-1:-1:-1;;;;;93071:250:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93276:10;;93301:9;;93071:250;;;;;;;;;;;;;;93213:47;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;93071:250:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;93071:250:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;93071:250:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;93071:250:0;;92900:429;-1:-1:-1;;;;92900:429:0:o;90227:2314::-;90460:20;;;;:15;:20;;;;;;;;90459:21;90451:53;;;;;-1:-1:-1;;;90451:53:0;;;;;;;;;;;;-1:-1:-1;;;90451:53:0;;;;;;;;;;;;;;;90625:66;90619:72;;90600:16;90737:42;90742:12;84959:19;84912:2;90737:4;:42::i;:::-;90729:51;-1:-1:-1;90729:51:0;90826:40;90831:12;85286:27;85023:2;90826:4;:40::i;:::-;90818:49;-1:-1:-1;90818:49:0;90909:21;-1:-1:-1;;;;;90909:19:0;;;:21::i;:::-;90905:751;;;91065:8;90986;-1:-1:-1;;;;;90973:43:0;;91017:12;91031:9;91042:4;91056:3;91048:12;;90973:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;90973:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90973:88:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;90973:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;90973:88:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;90973:88:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;90973:88:0;:100;90947:197;;;;-1:-1:-1;;;90947:197:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91166:23;;91185:3;;91166:23;;;;;90905:751;;;-1:-1:-1;91258:114:0;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;91258:114:0;;;;;91230:157;;;;;;91461:59;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;91461:59:0;;;;;;;91451:70;;;;;91440:96;;91523:12;91440:10;:96::i;:::-;-1:-1:-1;;;;;91428:108:0;:8;-1:-1:-1;;;;;91428:108:0;;91402:196;;;;;-1:-1:-1;;;91402:196:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;91620:24;;91640:3;;91620:24;;;;;90905:751;91684:7;-1:-1:-1;;;;;91672:19:0;:8;-1:-1:-1;;;;;91672:19:0;;91668:866;;91712:20;:7;-1:-1:-1;;;;;91712:18:0;;:20::i;:::-;91708:815;;;91875:8;91796:7;-1:-1:-1;;;;;91783:42:0;;91826:12;91840:9;91851:5;91866:3;91858:12;;91783:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;91783:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91783:88:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;91783:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91783:88:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91783:88:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;91783:88:0;:100;91753:208;;;;-1:-1:-1;;;91753:208:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91987:22;;92005:3;;91987:22;;;;;91708:815;;;-1:-1:-1;92090:125:0;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;92090:125:0;;;;;92058:176;;;;;;92315:59;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;92315:59:0;;;;;;;92305:70;;;;;92294:95;;92377:11;92294:10;:95::i;:::-;-1:-1:-1;;;;;92283:106:0;:7;-1:-1:-1;;;;;92283:106:0;;92253:205;;;;;-1:-1:-1;;;92253:205:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;92484:23;;92503:3;;92484:23;;;;;91708:815;90227:2314;;;;;;;;;:::o;94169:553::-;94466:222;;;;;;;;-1:-1:-1;;;;;;94466:222:0;;;;;;;;;;;;;-1:-1:-1;;;;;;94466:222:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;94466:222:0;;;;;;;26:21:-1;;;22:32;;6:49;;94466:222:0;;;;;;;94438:265;;;;;;94169:553::o;76212:322::-;76283:7;76310:216;76343:8;:15;;;76373:8;:17;;;76405:8;:16;;;76436:8;:17;;;76468:8;:13;;;76496:8;:19;;;76310:18;:216::i;95637:415::-;95839:2;95829:13;;95823:20;95878:2;95868:13;;95862:20;95921:2;95911:13;;95905:20;95714:7;;95823:20;95862;95927:3;95901:30;95962:2;95958:6;;95954:46;;;95986:2;95981:7;95954:46;96019:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96019:25:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;96019:25:0;;-1:-1:-1;;96019:25:0;;;95637:415;-1:-1:-1;;;;;;;95637:415:0:o;96060:412::-;96198:7;-1:-1:-1;;;;;96222:21:0;;96218:41;;-1:-1:-1;96252:7:0;96245:14;;96218:41;96271:14;96287:18;96320:7;-1:-1:-1;;;;;96309:30:0;;96340:11;96309:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;96309:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;96309:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;96309:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;96309:43:0;;;;;;;;96370:41;;-1:-1:-1;;;;;96370:41:0;;;;;;;;;;;;;;;;;96309:43;;-1:-1:-1;96309:43:0;-1:-1:-1;96370:41:0;;;;;;;;;96454:10;96431:20;:6;96443:7;96431:20;:11;:20;:::i;:::-;:33;;;;;;;96060:412;-1:-1:-1;;;;;;96060:412:0:o;61820:1076::-;62055:4;62049:11;-1:-1:-1;;;62147:19:0;;;62257:4;62250:12;;62243:34;;;61935:15;;;;61997:8;62766:4;62049:11;62601:4;62049:11;62459:9;62400:5;62355:416;62835:8;;62344:427;;62835:8;;-1:-1:-1;62025:864:0;-1:-1:-1;;;;62025:864:0:o;96847:324::-;96948:12;96962:14;96989:23;97047:9;-1:-1:-1;;;;;97047:14:0;97062:5;97047:21;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;97047:21:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;97085:17:0;;97023:45;;-1:-1:-1;97023:45:0;-1:-1:-1;97085:21:0;97081:82;;97141:10;97130:33;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;97130:33:0;;-1:-1:-1;97081:82:0;96847:324;;;;;;:::o;94730:899::-;94822:14;94847:13;94871:14;94896:16;94923:12;94946:17;94974:15;95023;95053:14;95082:15;95112:17;95144:13;95172:19;95205:76;95212:5;84669:2;84807;84912;85023;85130;85241:1;95205:6;:76::i;:::-;95008:273;;;;;;;;;;;;95319:7;95311:16;;95294:34;;95363:6;95355:15;;95339:32;;95407:7;95399:16;;95382:34;;95454:9;95446:18;;95427:38;;95491:5;95483:14;;95476:21;;95536:11;95528:20;;95508:41;;95586:33;95591:5;85241:1;85130:2;85023;84912;84807;84669;84852:17;84959:19;85066:23;85179:15;85286:27;85357:2;95586:4;:33::i;:::-;95578:42;;95560:61;;94730:899;;;;;;;;;;;;;;;:::o;14953:227::-;15012:7;15036:6;15032:47;;-1:-1:-1;15066:1:0;15059:8;;15032:47;15103:5;;;15107:1;15103;:5;:1;15127:3;;;;;:8;15119:34;;;;;-1:-1:-1;;;15119:34:0;;;;;;;;;;;;-1:-1:-1;;;15119:34:0;;;;;;;;;;;;;;67492:1370;67709:10;67730;67751;67772;67793;67814;67843:9;67907:2;67900:5;67896:14;67936:1;67930:8;67924:14;;67969:3;67965:2;67961:12;67990:1;67987:2;;;68022:1;68019;68015:9;68012:1;68008:17;68004:2;68000:26;67994:32;;67987:2;68054:3;68051:1;68047:11;68042:16;;68084:1;68078:8;68072:14;;68113:3;68109:2;68105:12;68100:17;;68134:1;68131:2;;;68166:1;68163;68159:9;68156:1;68152:17;68148:2;68144:26;68138:32;;68131:2;-1:-1:-1;68191:11:0;;;68222:8;;;-1:-1:-1;68191:11:0;68253:2;68249:12;;;68275:2;;;;68310:1;68307;68303:9;68300:1;68296:17;68292:2;68288:26;68282:32;;68275:2;-1:-1:-1;68335:11:0;;;68366:8;;;-1:-1:-1;68335:11:0;68397:2;68393:12;;;68419:2;;;;68454:1;68451;68447:9;68444:1;68440:17;68436:2;68432:26;68426:32;;68419:2;-1:-1:-1;68479:11:0;;;68510:8;;;-1:-1:-1;68479:11:0;68541:2;68537:12;;;68563:2;;;;68598:1;68595;68591:9;68588:1;68584:17;68580:2;68576:26;68570:32;;68563:2;-1:-1:-1;68623:11:0;;;68654:8;;;-1:-1:-1;68623:11:0;68685:2;68681:12;;;68707:2;;;;68742:1;68739;68735:9;68732:1;68728:17;68724:2;68720:26;68714:32;;68707:2;-1:-1:-1;68805:12:0;;68767:9;;;68805:17;-1:-1:-1;68805:17:0;68797:57;;;;;-1:-1:-1;;;68797:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;67492:1370;;;;;;;;;;;;;;;:::o;68971:28203::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68971:28203:0;;;-1:-1:-1;68971:28203:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
bzzr://636d7e7ae7f2447934281cf8ec9198f51a4e88c8f8d6452f62845a122b95226a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.