Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract contains unverified libraries: SetTokenLibrary
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ExchangeIssuanceModule
Compiler Version
v0.5.7+commit.6da8b019
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-04-13 */ /** *Submitted for verification at Etherscan.io on 2020-04-13 */ // File: openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol pragma solidity ^0.5.2; pragma experimental "ABIEncoderV2"; /** * @title Helps contracts guard against reentrancy attacks. * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]> * @dev If you mark a function `nonReentrant`, you should also * mark it `external`. */ contract ReentrancyGuard { /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; constructor () internal { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter); } } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.2; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: contracts/lib/CommonMath.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; library CommonMath { using SafeMath for uint256; uint256 public constant SCALE_FACTOR = 10 ** 18; uint256 public constant MAX_UINT_256 = 2 ** 256 - 1; /** * Returns scale factor equal to 10 ** 18 * * @return 10 ** 18 */ function scaleFactor() internal pure returns (uint256) { return SCALE_FACTOR; } /** * Calculates and returns the maximum value for a uint256 * * @return The maximum value for uint256 */ function maxUInt256() internal pure returns (uint256) { return MAX_UINT_256; } /** * Increases a value by the scale factor to allow for additional precision * during mathematical operations */ function scale( uint256 a ) internal pure returns (uint256) { return a.mul(SCALE_FACTOR); } /** * Divides a value by the scale factor to allow for additional precision * during mathematical operations */ function deScale( uint256 a ) internal pure returns (uint256) { return a.div(SCALE_FACTOR); } /** * @dev Performs the power on a specified value, reverts on overflow. */ function safePower( uint256 a, uint256 pow ) internal pure returns (uint256) { require(a > 0); uint256 result = 1; for (uint256 i = 0; i < pow; i++){ uint256 previousResult = result; // Using safemath multiplication prevents overflows result = previousResult.mul(a); } return result; } /** * @dev Performs division where if there is a modulo, the value is rounded up */ function divCeil(uint256 a, uint256 b) internal pure returns(uint256) { return a.mod(b) > 0 ? a.div(b).add(1) : a.div(b); } /** * Checks for rounding errors and returns value of potential partial amounts of a principal * * @param _principal Number fractional amount is derived from * @param _numerator Numerator of fraction * @param _denominator Denominator of fraction * @return uint256 Fractional amount of principal calculated */ function getPartialAmount( uint256 _principal, uint256 _numerator, uint256 _denominator ) internal pure returns (uint256) { // Get remainder of partial amount (if 0 not a partial amount) uint256 remainder = mulmod(_principal, _numerator, _denominator); // Return if not a partial amount if (remainder == 0) { return _principal.mul(_numerator).div(_denominator); } // Calculate error percentage uint256 errPercentageTimes1000000 = remainder.mul(1000000).div(_numerator.mul(_principal)); // Require error percentage is less than 0.1%. require( errPercentageTimes1000000 < 1000, "CommonMath.getPartialAmount: Rounding error exceeds bounds" ); return _principal.mul(_numerator).div(_denominator); } /* * Gets the rounded up log10 of passed value * * @param _value Value to calculate ceil(log()) on * @return uint256 Output value */ function ceilLog10( uint256 _value ) internal pure returns (uint256) { // Make sure passed value is greater than 0 require ( _value > 0, "CommonMath.ceilLog10: Value must be greater than zero." ); // Since log10(1) = 0, if _value = 1 return 0 if (_value == 1) return 0; // Calcualte ceil(log10()) uint256 x = _value - 1; uint256 result = 0; if (x >= 10 ** 64) { x /= 10 ** 64; result += 64; } if (x >= 10 ** 32) { x /= 10 ** 32; result += 32; } if (x >= 10 ** 16) { x /= 10 ** 16; result += 16; } if (x >= 10 ** 8) { x /= 10 ** 8; result += 8; } if (x >= 10 ** 4) { x /= 10 ** 4; result += 4; } if (x >= 100) { x /= 100; result += 2; } if (x >= 10) { result += 1; } return result + 1; } } // File: contracts/external/0x/LibBytes.sol /* Copyright 2018 ZeroEx Intl. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; library LibBytes { using LibBytes for bytes; /// @dev Gets the memory address for the contents of a byte array. /// @param input Byte array to lookup. /// @return memoryAddress Memory address of the contents of the byte array. function contentAddress(bytes memory input) internal pure returns (uint256 memoryAddress) { assembly { memoryAddress := add(input, 32) } return memoryAddress; } /// @dev Reads an unpadded bytes4 value from a position in a byte array. /// @param b Byte array containing a bytes4 value. /// @param index Index in byte array of bytes4 value. /// @return bytes4 value from byte array. function readBytes4( bytes memory b, uint256 index) internal pure returns (bytes4 result) { require( b.length >= index + 4, "GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED" ); assembly { result := mload(add(b, 32)) // Solidity does not require us to clean the trailing bytes. // We do it anyway result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000) } return result; } /// @dev Reads a bytes32 value from a position in a byte array. /// @param b Byte array containing a bytes32 value. /// @param index Index in byte array of bytes32 value. /// @return bytes32 value from byte array. function readBytes32( bytes memory b, uint256 index ) internal pure returns (bytes32 result) { require( b.length >= index + 32, "GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED" ); // Arrays are prefixed by a 256 bit length parameter index += 32; // Read the bytes32 from array memory assembly { result := mload(add(b, index)) } return result; } /// @dev Copies `length` bytes from memory location `source` to `dest`. /// @param dest memory address to copy bytes to. /// @param source memory address to copy bytes from. /// @param length number of bytes to copy. function memCopy( uint256 dest, uint256 source, uint256 length ) internal pure { if (length < 32) { // Handle a partial word by reading destination and masking // off the bits we are interested in. // This correctly handles overlap, zero lengths and source == dest assembly { let mask := sub(exp(256, sub(32, length)), 1) let s := and(mload(source), not(mask)) let d := and(mload(dest), mask) mstore(dest, or(s, d)) } } else { // Skip the O(length) loop when source == dest. if (source == dest) { return; } // For large copies we copy whole words at a time. The final // word is aligned to the end of the range (instead of after the // previous) to handle partial words. So a copy will look like this: // // #### // #### // #### // #### // // We handle overlap in the source and destination range by // changing the copying direction. This prevents us from // overwriting parts of source that we still need to copy. // // This correctly handles source == dest // if (source > dest) { assembly { // We subtract 32 from `sEnd` and `dEnd` because it // is easier to compare with in the loop, and these // are also the addresses we need for copying the // last bytes. length := sub(length, 32) let sEnd := add(source, length) let dEnd := add(dest, length) // Remember the last 32 bytes of source // This needs to be done here and not after the loop // because we may have overwritten the last bytes in // source already due to overlap. let last := mload(sEnd) // Copy whole words front to back // Note: the first check is always true, // this could have been a do-while loop. for {} lt(source, sEnd) {} { mstore(dest, mload(source)) source := add(source, 32) dest := add(dest, 32) } // Write the last 32 bytes mstore(dEnd, last) } } else { assembly { // We subtract 32 from `sEnd` and `dEnd` because those // are the starting points when copying a word at the end. length := sub(length, 32) let sEnd := add(source, length) let dEnd := add(dest, length) // Remember the first 32 bytes of source // This needs to be done here and not after the loop // because we may have overwritten the first bytes in // source already due to overlap. let first := mload(source) // Copy whole words back to front // We use a signed comparisson here to allow dEnd to become // negative (happens when source and dest < 32). Valid // addresses in local memory will never be larger than // 2**255, so they can be safely re-interpreted as signed. // Note: the first check is always true, // this could have been a do-while loop. for {} slt(dest, dEnd) {} { mstore(dEnd, mload(sEnd)) sEnd := sub(sEnd, 32) dEnd := sub(dEnd, 32) } // Write the first 32 bytes mstore(dest, first) } } } } /// @dev Returns a slices from a byte array. /// @param b The byte array to take a slice from. /// @param from The starting index for the slice (inclusive). /// @param to The final index for the slice (exclusive). /// @return result The slice containing bytes at indices [from, to) function slice(bytes memory b, uint256 from, uint256 to) internal pure returns (bytes memory result) { require( from <= to, "FROM_LESS_THAN_TO_REQUIRED" ); require( // NOTE: Set Protocol changed from `to < b.length` so that the last byte can be sliced off to <= b.length, "TO_LESS_THAN_LENGTH_REQUIRED" ); // Create a new bytes structure and copy contents result = new bytes(to - from); memCopy( result.contentAddress(), b.contentAddress() + from, result.length); return result; } } // File: contracts/core/lib/ExchangeHeaderLibrary.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ExchangeHeaderLibrary * @author Set Protocol * * This library contains functions and structs to assist with parsing exchange orders data */ library ExchangeHeaderLibrary { using LibBytes for bytes; using SafeMath for uint256; // ============ Structs ============ struct ExchangeHeader { uint8 exchange; uint8 orderCount; uint256 orderDataBytesLength; } function EXCHANGE_HEADER_LENGTH() internal pure returns (uint256) { return uint256(96); } // ============ Internal Functions ============ /** * Function to convert bytes into ExchangeHeader * * @param _orderData Bytes representing the order body information * @param _offset Bytes to offset orderData by * @return ExchangeHeader Struct containing data for a batch of exchange orders */ function parseExchangeHeader( bytes memory _orderData, uint256 _offset ) internal pure returns (ExchangeHeader memory) { ExchangeHeader memory header; uint256 headerDataStart = _orderData.contentAddress().add(_offset); assembly { mstore(header, mload(headerDataStart)) // exchange mstore(add(header, 32), mload(add(headerDataStart, 32))) // orderCount mstore(add(header, 64), mload(add(headerDataStart, 64))) // orderDataBytesLength } return header; } /** * Function to extract the exchange body from the order data * * @param _orderData Bytes representing the exchange order information * @param _scannedBytes Number representing the number of bytes already processed * @param _exchangeDataLength Length of the exchange data from the exchange data header * @return ExchangeBody Bytes representing the exchange body */ function sliceBodyData( bytes memory _orderData, uint256 _scannedBytes, uint256 _exchangeDataLength ) internal pure returns (bytes memory) { bytes memory bodyData = LibBytes.slice( _orderData, _scannedBytes.add(EXCHANGE_HEADER_LENGTH()), _scannedBytes.add(_exchangeDataLength) ); return bodyData; } } // File: contracts/lib/AddressArrayUtils.sol // Pulled in from Cryptofin Solidity package in order to control Solidity compiler version // https://github.com/cryptofinlabs/cryptofin-solidity/blob/master/contracts/array-utils/AddressArrayUtils.sol pragma solidity 0.5.7; library AddressArrayUtils { /** * Finds the index of the first occurrence of the given element. * @param A The input array to search * @param a The value to find * @return Returns (index and isIn) for the first occurrence starting from index 0 */ function indexOf(address[] memory A, address a) internal pure returns (uint256, bool) { uint256 length = A.length; for (uint256 i = 0; i < length; i++) { if (A[i] == a) { return (i, true); } } return (0, false); } /** * Returns true if the value is present in the list. Uses indexOf internally. * @param A The input array to search * @param a The value to find * @return Returns isIn for the first occurrence starting from index 0 */ function contains(address[] memory A, address a) internal pure returns (bool) { bool isIn; (, isIn) = indexOf(A, a); return isIn; } /** * Returns the combination of the two arrays * @param A The first array * @param B The second array * @return Returns A extended by B */ function extend(address[] memory A, address[] memory B) internal pure returns (address[] memory) { uint256 aLength = A.length; uint256 bLength = B.length; address[] memory newAddresses = new address[](aLength + bLength); for (uint256 i = 0; i < aLength; i++) { newAddresses[i] = A[i]; } for (uint256 j = 0; j < bLength; j++) { newAddresses[aLength + j] = B[j]; } return newAddresses; } /** * Returns the array with a appended to A. * @param A The first array * @param a The value to append * @return Returns A appended by a */ function append(address[] memory A, address a) internal pure returns (address[] memory) { address[] memory newAddresses = new address[](A.length + 1); for (uint256 i = 0; i < A.length; i++) { newAddresses[i] = A[i]; } newAddresses[A.length] = a; return newAddresses; } /** * Returns the intersection of two arrays. Arrays are treated as collections, so duplicates are kept. * @param A The first array * @param B The second array * @return The intersection of the two arrays */ function intersect(address[] memory A, address[] memory B) internal pure returns (address[] memory) { uint256 length = A.length; bool[] memory includeMap = new bool[](length); uint256 newLength = 0; for (uint256 i = 0; i < length; i++) { if (contains(B, A[i])) { includeMap[i] = true; newLength++; } } address[] memory newAddresses = new address[](newLength); uint256 j = 0; for (uint256 k = 0; k < length; k++) { if (includeMap[k]) { newAddresses[j] = A[k]; j++; } } return newAddresses; } /** * Returns the union of the two arrays. Order is not guaranteed. * @param A The first array * @param B The second array * @return The union of the two arrays */ function union(address[] memory A, address[] memory B) internal pure returns (address[] memory) { address[] memory leftDifference = difference(A, B); address[] memory rightDifference = difference(B, A); address[] memory intersection = intersect(A, B); return extend(leftDifference, extend(intersection, rightDifference)); } /** * Computes the difference of two arrays. Assumes there are no duplicates. * @param A The first array * @param B The second array * @return The difference of the two arrays */ function difference(address[] memory A, address[] memory B) internal pure returns (address[] memory) { uint256 length = A.length; bool[] memory includeMap = new bool[](length); uint256 count = 0; // First count the new length because can't push for in-memory arrays for (uint256 i = 0; i < length; i++) { address e = A[i]; if (!contains(B, e)) { includeMap[i] = true; count++; } } address[] memory newAddresses = new address[](count); uint256 j = 0; for (uint256 k = 0; k < length; k++) { if (includeMap[k]) { newAddresses[j] = A[k]; j++; } } return newAddresses; } /** * Removes specified index from array * Resulting ordering is not guaranteed * @return Returns the new array and the removed entry */ function pop(address[] memory A, uint256 index) internal pure returns (address[] memory, address) { uint256 length = A.length; address[] memory newAddresses = new address[](length - 1); for (uint256 i = 0; i < index; i++) { newAddresses[i] = A[i]; } for (uint256 j = index + 1; j < length; j++) { newAddresses[j - 1] = A[j]; } return (newAddresses, A[index]); } /** * @return Returns the new array */ function remove(address[] memory A, address a) internal pure returns (address[] memory) { (uint256 index, bool isIn) = indexOf(A, a); if (!isIn) { revert(); } else { (address[] memory _A,) = pop(A, index); return _A; } } /** * Returns whether or not there's a duplicate. Runs in O(n^2). * @param A Array to search * @return Returns true if duplicate, false otherwise */ function hasDuplicate(address[] memory A) internal pure returns (bool) { if (A.length == 0) { return false; } for (uint256 i = 0; i < A.length - 1; i++) { for (uint256 j = i + 1; j < A.length; j++) { if (A[i] == A[j]) { return true; } } } return false; } /** * Returns whether the two arrays are equal. * @param A The first array * @param B The second array * @return True is the arrays are equal, false if not. */ function isEqual(address[] memory A, address[] memory B) internal pure returns (bool) { if (A.length != B.length) { return false; } for (uint256 i = 0; i < A.length; i++) { if (A[i] != B[i]) { return false; } } return true; } } // File: contracts/core/interfaces/ICore.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ICore * @author Set Protocol * * The ICore Contract defines all the functions exposed in the Core through its * various extensions and is a light weight way to interact with the contract. */ interface ICore { /** * Return transferProxy address. * * @return address transferProxy address */ function transferProxy() external view returns (address); /** * Return vault address. * * @return address vault address */ function vault() external view returns (address); /** * Return address belonging to given exchangeId. * * @param _exchangeId ExchangeId number * @return address Address belonging to given exchangeId */ function exchangeIds( uint8 _exchangeId ) external view returns (address); /* * Returns if valid set * * @return bool Returns true if Set created through Core and isn't disabled */ function validSets(address) external view returns (bool); /* * Returns if valid module * * @return bool Returns true if valid module */ function validModules(address) external view returns (bool); /** * Return boolean indicating if address is a valid Rebalancing Price Library. * * @param _priceLibrary Price library address * @return bool Boolean indicating if valid Price Library */ function validPriceLibraries( address _priceLibrary ) external view returns (bool); /** * Exchanges components for Set Tokens * * @param _set Address of set to issue * @param _quantity Quantity of set to issue */ function issue( address _set, uint256 _quantity ) external; /** * Issues a specified Set for a specified quantity to the recipient * using the caller's components from the wallet and vault. * * @param _recipient Address to issue to * @param _set Address of the Set to issue * @param _quantity Number of tokens to issue */ function issueTo( address _recipient, address _set, uint256 _quantity ) external; /** * Converts user's components into Set Tokens held directly in Vault instead of user's account * * @param _set Address of the Set * @param _quantity Number of tokens to redeem */ function issueInVault( address _set, uint256 _quantity ) external; /** * Function to convert Set Tokens into underlying components * * @param _set The address of the Set token * @param _quantity The number of tokens to redeem. Should be multiple of natural unit. */ function redeem( address _set, uint256 _quantity ) external; /** * Redeem Set token and return components to specified recipient. The components * are left in the vault * * @param _recipient Recipient of Set being issued * @param _set Address of the Set * @param _quantity Number of tokens to redeem */ function redeemTo( address _recipient, address _set, uint256 _quantity ) external; /** * Function to convert Set Tokens held in vault into underlying components * * @param _set The address of the Set token * @param _quantity The number of tokens to redeem. Should be multiple of natural unit. */ function redeemInVault( address _set, uint256 _quantity ) external; /** * Composite method to redeem and withdraw with a single transaction * * Normally, you should expect to be able to withdraw all of the tokens. * However, some have central abilities to freeze transfers (e.g. EOS). _toExclude * allows you to optionally specify which component tokens to exclude when * redeeming. They will remain in the vault under the users' addresses. * * @param _set Address of the Set * @param _to Address to withdraw or attribute tokens to * @param _quantity Number of tokens to redeem * @param _toExclude Mask of indexes of tokens to exclude from withdrawing */ function redeemAndWithdrawTo( address _set, address _to, uint256 _quantity, uint256 _toExclude ) external; /** * Deposit multiple tokens to the vault. Quantities should be in the * order of the addresses of the tokens being deposited. * * @param _tokens Array of the addresses of the ERC20 tokens * @param _quantities Array of the number of tokens to deposit */ function batchDeposit( address[] calldata _tokens, uint256[] calldata _quantities ) external; /** * Withdraw multiple tokens from the vault. Quantities should be in the * order of the addresses of the tokens being withdrawn. * * @param _tokens Array of the addresses of the ERC20 tokens * @param _quantities Array of the number of tokens to withdraw */ function batchWithdraw( address[] calldata _tokens, uint256[] calldata _quantities ) external; /** * Deposit any quantity of tokens into the vault. * * @param _token The address of the ERC20 token * @param _quantity The number of tokens to deposit */ function deposit( address _token, uint256 _quantity ) external; /** * Withdraw a quantity of tokens from the vault. * * @param _token The address of the ERC20 token * @param _quantity The number of tokens to withdraw */ function withdraw( address _token, uint256 _quantity ) external; /** * Transfer tokens associated with the sender's account in vault to another user's * account in vault. * * @param _token Address of token being transferred * @param _to Address of user receiving tokens * @param _quantity Amount of tokens being transferred */ function internalTransfer( address _token, address _to, uint256 _quantity ) external; /** * Deploys a new Set Token and adds it to the valid list of SetTokens * * @param _factory The address of the Factory to create from * @param _components The address of component tokens * @param _units The units of each component token * @param _naturalUnit The minimum unit to be issued or redeemed * @param _name The bytes32 encoded name of the new Set * @param _symbol The bytes32 encoded symbol of the new Set * @param _callData Byte string containing additional call parameters * @return setTokenAddress The address of the new Set */ function createSet( address _factory, address[] calldata _components, uint256[] calldata _units, uint256 _naturalUnit, bytes32 _name, bytes32 _symbol, bytes calldata _callData ) external returns (address); /** * Exposes internal function that deposits a quantity of tokens to the vault and attributes * the tokens respectively, to system modules. * * @param _from Address to transfer tokens from * @param _to Address to credit for deposit * @param _token Address of token being deposited * @param _quantity Amount of tokens to deposit */ function depositModule( address _from, address _to, address _token, uint256 _quantity ) external; /** * Exposes internal function that withdraws a quantity of tokens from the vault and * deattributes the tokens respectively, to system modules. * * @param _from Address to decredit for withdraw * @param _to Address to transfer tokens to * @param _token Address of token being withdrawn * @param _quantity Amount of tokens to withdraw */ function withdrawModule( address _from, address _to, address _token, uint256 _quantity ) external; /** * Exposes internal function that deposits multiple tokens to the vault, to system * modules. Quantities should be in the order of the addresses of the tokens being * deposited. * * @param _from Address to transfer tokens from * @param _to Address to credit for deposits * @param _tokens Array of the addresses of the tokens being deposited * @param _quantities Array of the amounts of tokens to deposit */ function batchDepositModule( address _from, address _to, address[] calldata _tokens, uint256[] calldata _quantities ) external; /** * Exposes internal function that withdraws multiple tokens from the vault, to system * modules. Quantities should be in the order of the addresses of the tokens being withdrawn. * * @param _from Address to decredit for withdrawals * @param _to Address to transfer tokens to * @param _tokens Array of the addresses of the tokens being withdrawn * @param _quantities Array of the amounts of tokens to withdraw */ function batchWithdrawModule( address _from, address _to, address[] calldata _tokens, uint256[] calldata _quantities ) external; /** * Expose internal function that exchanges components for Set tokens, * accepting any owner, to system modules * * @param _owner Address to use tokens from * @param _recipient Address to issue Set to * @param _set Address of the Set to issue * @param _quantity Number of tokens to issue */ function issueModule( address _owner, address _recipient, address _set, uint256 _quantity ) external; /** * Expose internal function that exchanges Set tokens for components, * accepting any owner, to system modules * * @param _burnAddress Address to burn token from * @param _incrementAddress Address to increment component tokens to * @param _set Address of the Set to redeem * @param _quantity Number of tokens to redeem */ function redeemModule( address _burnAddress, address _incrementAddress, address _set, uint256 _quantity ) external; /** * Expose vault function that increments user's balance in the vault. * Available to system modules * * @param _tokens The addresses of the ERC20 tokens * @param _owner The address of the token owner * @param _quantities The numbers of tokens to attribute to owner */ function batchIncrementTokenOwnerModule( address[] calldata _tokens, address _owner, uint256[] calldata _quantities ) external; /** * Expose vault function that decrement user's balance in the vault * Only available to system modules. * * @param _tokens The addresses of the ERC20 tokens * @param _owner The address of the token owner * @param _quantities The numbers of tokens to attribute to owner */ function batchDecrementTokenOwnerModule( address[] calldata _tokens, address _owner, uint256[] calldata _quantities ) external; /** * Expose vault function that transfer vault balances between users * Only available to system modules. * * @param _tokens Addresses of tokens being transferred * @param _from Address tokens being transferred from * @param _to Address tokens being transferred to * @param _quantities Amounts of tokens being transferred */ function batchTransferBalanceModule( address[] calldata _tokens, address _from, address _to, uint256[] calldata _quantities ) external; /** * Transfers token from one address to another using the transfer proxy. * Only available to system modules. * * @param _token The address of the ERC20 token * @param _quantity The number of tokens to transfer * @param _from The address to transfer from * @param _to The address to transfer to */ function transferModule( address _token, uint256 _quantity, address _from, address _to ) external; /** * Expose transfer proxy function to transfer tokens from one address to another * Only available to system modules. * * @param _tokens The addresses of the ERC20 token * @param _quantities The numbers of tokens to transfer * @param _from The address to transfer from * @param _to The address to transfer to */ function batchTransferModule( address[] calldata _tokens, uint256[] calldata _quantities, address _from, address _to ) external; } // File: contracts/core/interfaces/ISetToken.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ISetToken * @author Set Protocol * * The ISetToken interface provides a light-weight, structured way to interact with the * SetToken contract from another contract. */ interface ISetToken { /* ============ External Functions ============ */ /* * Get natural unit of Set * * @return uint256 Natural unit of Set */ function naturalUnit() external view returns (uint256); /* * Get addresses of all components in the Set * * @return componentAddresses Array of component tokens */ function getComponents() external view returns (address[] memory); /* * Get units of all tokens in Set * * @return units Array of component units */ function getUnits() external view returns (uint256[] memory); /* * Checks to make sure token is component of Set * * @param _tokenAddress Address of token being checked * @return bool True if token is component of Set */ function tokenIsComponent( address _tokenAddress ) external view returns (bool); /* * Mint set token for given address. * Can only be called by authorized contracts. * * @param _issuer The address of the issuing account * @param _quantity The number of sets to attribute to issuer */ function mint( address _issuer, uint256 _quantity ) external; /* * Burn set token for given address * Can only be called by authorized contracts * * @param _from The address of the redeeming account * @param _quantity The number of sets to burn from redeemer */ function burn( address _from, uint256 _quantity ) external; /** * Transfer token for a specified address * * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer( address to, uint256 value ) external; } // File: contracts/core/interfaces/IVault.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title IVault * @author Set Protocol * * The IVault interface provides a light-weight, structured way to interact with the Vault * contract from another contract. */ interface IVault { /* * Withdraws user's unassociated tokens to user account. Can only be * called by authorized core contracts. * * @param _token The address of the ERC20 token * @param _to The address to transfer token to * @param _quantity The number of tokens to transfer */ function withdrawTo( address _token, address _to, uint256 _quantity ) external; /* * Increment quantity owned of a token for a given address. Can * only be called by authorized core contracts. * * @param _token The address of the ERC20 token * @param _owner The address of the token owner * @param _quantity The number of tokens to attribute to owner */ function incrementTokenOwner( address _token, address _owner, uint256 _quantity ) external; /* * Decrement quantity owned of a token for a given address. Can only * be called by authorized core contracts. * * @param _token The address of the ERC20 token * @param _owner The address of the token owner * @param _quantity The number of tokens to deattribute to owner */ function decrementTokenOwner( address _token, address _owner, uint256 _quantity ) external; /** * Transfers tokens associated with one account to another account in the vault * * @param _token Address of token being transferred * @param _from Address token being transferred from * @param _to Address token being transferred to * @param _quantity Amount of tokens being transferred */ function transferBalance( address _token, address _from, address _to, uint256 _quantity ) external; /* * Withdraws user's unassociated tokens to user account. Can only be * called by authorized core contracts. * * @param _tokens The addresses of the ERC20 tokens * @param _owner The address of the token owner * @param _quantities The numbers of tokens to attribute to owner */ function batchWithdrawTo( address[] calldata _tokens, address _to, uint256[] calldata _quantities ) external; /* * Increment quantites owned of a collection of tokens for a given address. Can * only be called by authorized core contracts. * * @param _tokens The addresses of the ERC20 tokens * @param _owner The address of the token owner * @param _quantities The numbers of tokens to attribute to owner */ function batchIncrementTokenOwner( address[] calldata _tokens, address _owner, uint256[] calldata _quantities ) external; /* * Decrements quantites owned of a collection of tokens for a given address. Can * only be called by authorized core contracts. * * @param _tokens The addresses of the ERC20 tokens * @param _owner The address of the token owner * @param _quantities The numbers of tokens to attribute to owner */ function batchDecrementTokenOwner( address[] calldata _tokens, address _owner, uint256[] calldata _quantities ) external; /** * Transfers tokens associated with one account to another account in the vault * * @param _tokens Addresses of tokens being transferred * @param _from Address tokens being transferred from * @param _to Address tokens being transferred to * @param _quantities Amounts of tokens being transferred */ function batchTransferBalance( address[] calldata _tokens, address _from, address _to, uint256[] calldata _quantities ) external; /* * Get balance of particular contract for owner. * * @param _token The address of the ERC20 token * @param _owner The address of the token owner */ function getOwnerBalance( address _token, address _owner ) external view returns (uint256); } // File: contracts/core/modules/lib/ExchangeIssuanceLibrary.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ExchangeIssuanceLibrary * @author Set Protocol * * The ExchangeIssuanceLibrary contains functions for validating exchange order data */ library ExchangeIssuanceLibrary { using SafeMath for uint256; using AddressArrayUtils for address[]; // ============ Structs ============ struct ExchangeIssuanceParams { address setAddress; uint256 quantity; uint8[] sendTokenExchangeIds; address[] sendTokens; uint256[] sendTokenAmounts; address[] receiveTokens; uint256[] receiveTokenAmounts; } /** * Validates that the quantity to issue is positive and a multiple of the Set natural unit. * * @param _set The address of the Set * @param _quantity The quantity of Sets to issue or redeem */ function validateQuantity( address _set, uint256 _quantity ) internal view { // Make sure quantity to issue is greater than 0 require( _quantity > 0, "ExchangeIssuanceLibrary.validateQuantity: Quantity must be positive" ); // Make sure Issue quantity is multiple of the Set natural unit require( _quantity.mod(ISetToken(_set).naturalUnit()) == 0, "ExchangeIssuanceLibrary.validateQuantity: Quantity must be multiple of natural unit" ); } /** * Validates that the required Components and amounts are valid components and positive. * Duplicate receive token values are not allowed * * @param _receiveTokens The addresses of components required for issuance * @param _receiveTokenAmounts The quantities of components required for issuance */ function validateReceiveTokens( address[] memory _receiveTokens, uint256[] memory _receiveTokenAmounts ) internal view { uint256 receiveTokensCount = _receiveTokens.length; // Make sure required components array is non-empty require( receiveTokensCount > 0, "ExchangeIssuanceLibrary.validateReceiveTokens: Receive tokens must not be empty" ); // Ensure the receive tokens has no duplicates require( !_receiveTokens.hasDuplicate(), "ExchangeIssuanceLibrary.validateReceiveTokens: Receive tokens must not have duplicates" ); // Make sure required components and required component amounts are equal length require( receiveTokensCount == _receiveTokenAmounts.length, "ExchangeIssuanceLibrary.validateReceiveTokens: Receive tokens and amounts must be equal length" ); for (uint256 i = 0; i < receiveTokensCount; i++) { // Make sure all required component amounts are non-zero require( _receiveTokenAmounts[i] > 0, "ExchangeIssuanceLibrary.validateReceiveTokens: Component amounts must be positive" ); } } /** * Validates that the tokens received exceeds what we expect * * @param _vault The address of the Vault * @param _receiveTokens The addresses of components required for issuance * @param _requiredBalances The quantities of components required for issuance * @param _userToCheck The address of the user */ function validatePostExchangeReceiveTokenBalances( address _vault, address[] memory _receiveTokens, uint256[] memory _requiredBalances, address _userToCheck ) internal view { // Get vault instance IVault vault = IVault(_vault); // Check that caller's receive tokens in Vault have been incremented correctly for (uint256 i = 0; i < _receiveTokens.length; i++) { uint256 currentBal = vault.getOwnerBalance( _receiveTokens[i], _userToCheck ); require( currentBal >= _requiredBalances[i], "ExchangeIssuanceLibrary.validatePostExchangeReceiveTokenBalances: Insufficient receive token acquired" ); } } /** * Validates that the send tokens inputs are valid. Since tokens are sent to various exchanges, * duplicate send tokens are valid * * @param _core The address of Core * @param _sendTokenExchangeIds List of exchange wrapper enumerations corresponding to * the wrapper that will handle the component * @param _sendTokens The address of the send tokens * @param _sendTokenAmounts The quantities of send tokens */ function validateSendTokenParams( address _core, uint8[] memory _sendTokenExchangeIds, address[] memory _sendTokens, uint256[] memory _sendTokenAmounts ) internal view { require( _sendTokens.length > 0, "ExchangeIssuanceLibrary.validateSendTokenParams: Send token inputs must not be empty" ); require( _sendTokenExchangeIds.length == _sendTokens.length && _sendTokens.length == _sendTokenAmounts.length, "ExchangeIssuanceLibrary.validateSendTokenParams: Send token inputs must be of the same length" ); ICore core = ICore(_core); for (uint256 i = 0; i < _sendTokenExchangeIds.length; i++) { // Make sure all exchanges are valid require( core.exchangeIds(_sendTokenExchangeIds[i]) != address(0), "ExchangeIssuanceLibrary.validateSendTokenParams: Must be valid exchange" ); // Make sure all send token amounts are non-zero require( _sendTokenAmounts[i] > 0, "ExchangeIssuanceLibrary.validateSendTokenParams: Send amounts must be positive" ); } } } // File: contracts/lib/IERC20.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title IERC20 * @author Set Protocol * * Interface for using ERC20 Tokens. This interface is needed to interact with tokens that are not * fully ERC20 compliant and return something other than true on successful transfers. */ interface IERC20 { function balanceOf( address _owner ) external view returns (uint256); function allowance( address _owner, address _spender ) external view returns (uint256); function transfer( address _to, uint256 _quantity ) external; function transferFrom( address _from, address _to, uint256 _quantity ) external; function approve( address _spender, uint256 _quantity ) external returns (bool); function totalSupply() external returns (uint256); } // File: contracts/lib/ERC20Wrapper.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ERC20Wrapper * @author Set Protocol * * This library contains functions for interacting wtih ERC20 tokens, even those not fully compliant. * For all functions we will only accept tokens that return a null or true value, any other values will * cause the operation to revert. */ library ERC20Wrapper { // ============ Internal Functions ============ /** * Check balance owner's balance of ERC20 token * * @param _token The address of the ERC20 token * @param _owner The owner who's balance is being checked * @return uint256 The _owner's amount of tokens */ function balanceOf( address _token, address _owner ) external view returns (uint256) { return IERC20(_token).balanceOf(_owner); } /** * Checks spender's allowance to use token's on owner's behalf. * * @param _token The address of the ERC20 token * @param _owner The token owner address * @param _spender The address the allowance is being checked on * @return uint256 The spender's allowance on behalf of owner */ function allowance( address _token, address _owner, address _spender ) internal view returns (uint256) { return IERC20(_token).allowance(_owner, _spender); } /** * Transfers tokens from an address. Handle's tokens that return true or null. * If other value returned, reverts. * * @param _token The address of the ERC20 token * @param _to The address to transfer to * @param _quantity The amount of tokens to transfer */ function transfer( address _token, address _to, uint256 _quantity ) external { IERC20(_token).transfer(_to, _quantity); // Check that transfer returns true or null require( checkSuccess(), "ERC20Wrapper.transfer: Bad return value" ); } /** * Transfers tokens from an address (that has set allowance on the proxy). * Handle's tokens that return true or null. If other value returned, reverts. * * @param _token The address of the ERC20 token * @param _from The address to transfer from * @param _to The address to transfer to * @param _quantity The number of tokens to transfer */ function transferFrom( address _token, address _from, address _to, uint256 _quantity ) external { IERC20(_token).transferFrom(_from, _to, _quantity); // Check that transferFrom returns true or null require( checkSuccess(), "ERC20Wrapper.transferFrom: Bad return value" ); } /** * Grants spender ability to spend on owner's behalf. * Handle's tokens that return true or null. If other value returned, reverts. * * @param _token The address of the ERC20 token * @param _spender The address to approve for transfer * @param _quantity The amount of tokens to approve spender for */ function approve( address _token, address _spender, uint256 _quantity ) internal { IERC20(_token).approve(_spender, _quantity); // Check that approve returns true or null require( checkSuccess(), "ERC20Wrapper.approve: Bad return value" ); } /** * Ensure's the owner has granted enough allowance for system to * transfer tokens. * * @param _token The address of the ERC20 token * @param _owner The address of the token owner * @param _spender The address to grant/check allowance for * @param _quantity The amount to see if allowed for */ function ensureAllowance( address _token, address _owner, address _spender, uint256 _quantity ) internal { uint256 currentAllowance = allowance(_token, _owner, _spender); if (currentAllowance < _quantity) { approve( _token, _spender, CommonMath.maxUInt256() ); } } // ============ Private Functions ============ /** * Checks the return value of the previous function up to 32 bytes. Returns true if the previous * function returned 0 bytes or 1. */ function checkSuccess( ) private pure returns (bool) { // default to failure uint256 returnValue = 0; assembly { // check number of bytes returned from last function call switch returndatasize // no bytes returned: assume success case 0x0 { returnValue := 1 } // 32 bytes returned case 0x20 { // copy 32 bytes into scratch space returndatacopy(0x0, 0x0, 0x20) // load those bytes into returnValue returnValue := mload(0x0) } // not sure what was returned: dont mark as success default { } } // check if returned value is one or nothing return returnValue == 1; } } // File: contracts/core/lib/ExchangeWrapperLibraryV2.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ExchangeWrapperLibrary * @author Set Protocol * * This library contains structs and functions to assist executing orders on third party exchanges * * CHANGELOG * - Removes functions that result in circular dependencies when trying to flatten. * - Functions using this library mainly use it for the structs */ library ExchangeWrapperLibraryV2 { // ============ Structs ============ /** * caller Original user initiating transaction * orderCount Expected number of orders to execute */ struct ExchangeData { address caller; uint256 orderCount; } /** * components A list of the acquired components from exchange wrapper * componentQuantities A list of the component quantities acquired */ struct ExchangeResults { address[] receiveTokens; uint256[] receiveTokenAmounts; } } // File: contracts/core/interfaces/IExchangeWrapper.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title IExchangeWrapper * @author Set Protocol * * Interface for executing an order with an exchange wrapper */ interface IExchangeWrapper { /* ============ External Functions ============ */ /** * Exchange some amount of makerToken for takerToken. * * maker Issuance order maker * taker Issuance order taker * makerToken Address of maker token used in exchange orders * makerAssetAmount Amount of issuance order maker token to use on this exchange * orderCount Expected number of orders to execute * fillQuantity Quantity of Set to be filled * attemptedFillQuantity Quantity of Set taker attempted to fill * * @param _orderData Arbitrary bytes data for any information to pass to the exchange */ function exchange( ExchangeWrapperLibraryV2.ExchangeData calldata _exchangeData, bytes calldata _orderData ) external returns (ExchangeWrapperLibraryV2.ExchangeResults memory); } // File: contracts/core/lib/ExchangeWrapperLibrary.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ExchangeWrapperLibrary * @author Set Protocol * * This library contains structs and functions to assist executing orders on third party exchanges */ library ExchangeWrapperLibrary { // ============ Structs ============ /** * caller Original user initiating transaction * orderCount Expected number of orders to execute */ struct ExchangeData { address caller; uint256 orderCount; } /** * receiveTokens A list of the acquired components from exchange wrapper * receiveTokenAmounts A list of the component quantities acquired */ struct ExchangeResults { address[] receiveTokens; uint256[] receiveTokenAmounts; } /** * Checks if any send tokens leftover and transfers to caller * @param _sendTokens The addresses of send tokens * @param _caller The address of the original transaction caller */ function returnLeftoverSendTokens( address[] memory _sendTokens, address _caller ) internal { for (uint256 i = 0; i < _sendTokens.length; i++) { // Transfer any unused or remainder send token back to the caller uint256 remainderSendToken = ERC20Wrapper.balanceOf(_sendTokens[i], address(this)); if (remainderSendToken > 0) { ERC20Wrapper.transfer( _sendTokens[i], _caller, remainderSendToken ); } } } /** * Calls exchange to execute trades and deposits fills into Vault for issuanceOrder maker. * * * @param _core Address of Core * @param _exchangeData Standard exchange wrapper interface object containing exchange metadata * @param _exchangeWrapper Address of exchange wrapper being called * @param _bodyData Arbitrary bytes data for orders to be executed on exchange */ function callExchange( address _core, ExchangeWrapperLibraryV2.ExchangeData memory _exchangeData, address _exchangeWrapper, bytes memory _bodyData ) internal { // Call Exchange ExchangeWrapperLibraryV2.ExchangeResults memory exchangeResults = IExchangeWrapper(_exchangeWrapper).exchange( _exchangeData, _bodyData ); // Transfer receiveToken tokens from wrapper to vault ICore(_core).batchDepositModule( _exchangeWrapper, _exchangeData.caller, exchangeResults.receiveTokens, exchangeResults.receiveTokenAmounts ); } } // File: contracts/core/interfaces/ITransferProxy.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ITransferProxy * @author Set Protocol * * The ITransferProxy interface provides a light-weight, structured way to interact with the * TransferProxy contract from another contract. */ interface ITransferProxy { /* ============ External Functions ============ */ /** * Transfers tokens from an address (that has set allowance on the proxy). * Can only be called by authorized core contracts. * * @param _token The address of the ERC20 token * @param _quantity The number of tokens to transfer * @param _from The address to transfer from * @param _to The address to transfer to */ function transfer( address _token, uint256 _quantity, address _from, address _to ) external; /** * Transfers tokens from an address (that has set allowance on the proxy). * Can only be called by authorized core contracts. * * @param _tokens The addresses of the ERC20 token * @param _quantities The numbers of tokens to transfer * @param _from The address to transfer from * @param _to The address to transfer to */ function batchTransfer( address[] calldata _tokens, uint256[] calldata _quantities, address _from, address _to ) external; } // File: contracts/core/modules/lib/ModuleCoreState.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ModuleCoreState * @author Set Protocol * * The ModuleCoreState library maintains Core-related state for modules */ contract ModuleCoreState { /* ============ State Variables ============ */ // Address of core contract address public core; // Address of vault contract address public vault; // Instance of core contract ICore public coreInstance; // Instance of vault contract IVault public vaultInstance; /* ============ Public Getters ============ */ /** * Constructor function for ModuleCoreState * * @param _core The address of Core * @param _vault The address of Vault */ constructor( address _core, address _vault ) public { // Commit passed address to core state variable core = _core; // Commit passed address to coreInstance state variable coreInstance = ICore(_core); // Commit passed address to vault state variable vault = _vault; // Commit passed address to vaultInstance state variable vaultInstance = IVault(_vault); } } // File: contracts/core/modules/lib/ExchangeExecution.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ExchangeExecution * @author Set Protocol * * The ExchangeExecution contract exposes functions that allow validation and execution of exchange orders. */ contract ExchangeExecution is ModuleCoreState { using SafeMath for uint256; /* ============ Private Functions ============ */ /** * Execute the exchange orders by parsing the order data and facilitating the transfers. Each * header represents a batch of orders for a particular exchange (0x, Kyber) * * @param _orderData Bytes array containing the exchange orders to execute */ function executeExchangeOrders( bytes memory _orderData ) internal { // Bitmask integer of called exchanges. Acts as a lock so that duplicate exchange headers are not passed in. uint256 calledExchanges = 0; uint256 scannedBytes = 0; while (scannedBytes < _orderData.length) { // Parse exchange header based on scannedBytes ExchangeHeaderLibrary.ExchangeHeader memory header = ExchangeHeaderLibrary.parseExchangeHeader( _orderData, scannedBytes ); // Get exchange address from state mapping based on header exchange info address exchangeWrapper = coreInstance.exchangeIds(header.exchange); // Verify exchange address is registered require( exchangeWrapper != address(0), "ExchangeExecution.executeExchangeOrders: Invalid or disabled Exchange address" ); // Verify exchange has not already been called uint256 exchangeBitIndex = CommonMath.safePower(2, header.exchange); require( (calledExchanges & exchangeBitIndex) == 0, "ExchangeExecution.executeExchangeOrders: Exchange already called" ); // Calculate the exchange data length uint256 exchangeDataLength = header.orderDataBytesLength.add( ExchangeHeaderLibrary.EXCHANGE_HEADER_LENGTH() ); // Read the order body based on order data length info in header plus the length of the header bytes memory bodyData = ExchangeHeaderLibrary.sliceBodyData( _orderData, scannedBytes, exchangeDataLength ); // Construct the Exchange Data struct for callExchange interface ExchangeWrapperLibraryV2.ExchangeData memory exchangeData = ExchangeWrapperLibraryV2.ExchangeData({ caller: msg.sender, orderCount: header.orderCount }); // Execute orders using the appropriate exchange wrappers ExchangeWrapperLibrary.callExchange( core, exchangeData, exchangeWrapper, bodyData ); // Update scanned bytes with header and body lengths scannedBytes = scannedBytes.add(exchangeDataLength); // Increment bit of current exchange to ensure non-duplicate entries calledExchanges = calledExchanges.add(exchangeBitIndex); } } /** * Calculates the user's balance of tokens required after exchange orders have been executed * * @param _exchangeIssuanceParams A Struct containing exchange issuance metadata * @return uint256[] Expected token balances after order execution */ function calculateReceiveTokenBalances( ExchangeIssuanceLibrary.ExchangeIssuanceParams memory _exchangeIssuanceParams ) internal view returns (uint256[] memory) { // Calculate amount of receive tokens required uint256[] memory requiredBalances = new uint256[](_exchangeIssuanceParams.receiveTokens.length); for (uint256 i = 0; i < _exchangeIssuanceParams.receiveTokens.length; i++) { // Get the user's current vault balances uint256 tokenBalance = vaultInstance.getOwnerBalance( _exchangeIssuanceParams.receiveTokens[i], msg.sender ); // Amount of receive tokens to be added to Vault uint256 requiredAddition = _exchangeIssuanceParams.receiveTokenAmounts[i]; // Required vault balances after exchange order execution requiredBalances[i] = tokenBalance.add(requiredAddition); } return requiredBalances; } /** * Validates exchangeIssueParam inputs * * @param _exchangeIssuanceParams A Struct containing exchange issuance metadata */ function validateExchangeIssuanceParams( ExchangeIssuanceLibrary.ExchangeIssuanceParams memory _exchangeIssuanceParams ) internal view { // Verify Set was created by Core and is enabled require( coreInstance.validSets(_exchangeIssuanceParams.setAddress), "ExchangeExecution.validateExchangeIssuanceParams: Invalid or disabled SetToken address" ); // Validate the issuance quantity ExchangeIssuanceLibrary.validateQuantity( _exchangeIssuanceParams.setAddress, _exchangeIssuanceParams.quantity ); // Validate send token data ExchangeIssuanceLibrary.validateSendTokenParams( core, _exchangeIssuanceParams.sendTokenExchangeIds, _exchangeIssuanceParams.sendTokens, _exchangeIssuanceParams.sendTokenAmounts ); // Validate receive token inputs ExchangeIssuanceLibrary.validateReceiveTokens( _exchangeIssuanceParams.receiveTokens, _exchangeIssuanceParams.receiveTokenAmounts ); } } // File: contracts/core/lib/SetTokenLibrary.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; library SetTokenLibrary { using SafeMath for uint256; struct SetDetails { uint256 naturalUnit; address[] components; uint256[] units; } /** * Validates that passed in tokens are all components of the Set * * @param _set Address of the Set * @param _tokens List of tokens to check */ function validateTokensAreComponents( address _set, address[] calldata _tokens ) external view { for (uint256 i = 0; i < _tokens.length; i++) { // Make sure all tokens are members of the Set require( ISetToken(_set).tokenIsComponent(_tokens[i]), "SetTokenLibrary.validateTokensAreComponents: Component must be a member of Set" ); } } /** * Validates that passed in quantity is a multiple of the natural unit of the Set. * * @param _set Address of the Set * @param _quantity Quantity to validate */ function isMultipleOfSetNaturalUnit( address _set, uint256 _quantity ) external view { require( _quantity.mod(ISetToken(_set).naturalUnit()) == 0, "SetTokenLibrary.isMultipleOfSetNaturalUnit: Quantity is not a multiple of nat unit" ); } /** * Validates that passed in quantity is a multiple of the natural unit of the Set. * * @param _core Address of Core * @param _set Address of the Set */ function requireValidSet( ICore _core, address _set ) internal view { require( _core.validSets(_set), "SetTokenLibrary: Must be an approved SetToken address" ); } /** * Retrieves the Set's natural unit, components, and units. * * @param _set Address of the Set * @return SetDetails Struct containing the natural unit, components, and units */ function getSetDetails( address _set ) internal view returns (SetDetails memory) { // Declare interface variables ISetToken setToken = ISetToken(_set); // Fetch set token properties uint256 naturalUnit = setToken.naturalUnit(); address[] memory components = setToken.getComponents(); uint256[] memory units = setToken.getUnits(); return SetDetails({ naturalUnit: naturalUnit, components: components, units: units }); } } // File: contracts/core/modules/ExchangeIssuanceModule.sol /* Copyright 2018 Set Labs Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity 0.5.7; /** * @title ExchangeIssuanceModule * @author Set Protocol * * The ExchangeIssuanceModule facilitates the exchangeIssue and exchangeRedeem functions which allows * the issuance and redemption Sets using exchange orders */ contract ExchangeIssuanceModule is ModuleCoreState, ExchangeExecution, ReentrancyGuard { using SafeMath for uint256; /* ============ Events ============ */ event LogExchangeIssue( address setAddress, address indexed callerAddress, uint256 quantity, address[] sendTokens, uint256[] sendTokenAmounts ); event LogExchangeRedeem( address setAddress, address indexed callerAddress, uint256 quantity, address[] receiveTokens, uint256[] receiveTokenAmounts ); /* ============ Constructor ============ */ /** * Constructor function for ExchangeIssuanceModule * * @param _core The address of Core * @param _vault The address of Vault */ constructor( address _core, address _vault ) public ModuleCoreState( _core, _vault ) {} /* ============ Public Functions ============ */ /** * Performs trades via exchange wrappers to acquire components and issues a Set to the caller * * @param _exchangeIssuanceParams A Struct containing exchange issuance metadata * @param _orderData Bytes array containing the exchange orders to execute */ function exchangeIssue( ExchangeIssuanceLibrary.ExchangeIssuanceParams memory _exchangeIssuanceParams, bytes memory _orderData ) public nonReentrant { // Ensures validity of exchangeIssuanceParams validateExchangeIssuanceParams(_exchangeIssuanceParams); // Validate that all receiveTokens are components of the SEt SetTokenLibrary.validateTokensAreComponents( _exchangeIssuanceParams.setAddress, _exchangeIssuanceParams.receiveTokens ); // Transfer the send tokens to the appropriate exchanges transferSendTokensToExchangeWrappers( _exchangeIssuanceParams.sendTokenExchangeIds, _exchangeIssuanceParams.sendTokens, _exchangeIssuanceParams.sendTokenAmounts ); // Execute the exchange orders using the encoded order data executeOrders(_exchangeIssuanceParams, _orderData); // Issue Set to the caller coreInstance.issueModule( msg.sender, msg.sender, _exchangeIssuanceParams.setAddress, _exchangeIssuanceParams.quantity ); emit LogExchangeIssue( _exchangeIssuanceParams.setAddress, msg.sender, _exchangeIssuanceParams.quantity, _exchangeIssuanceParams.sendTokens, _exchangeIssuanceParams.sendTokenAmounts ); } /** * Redeems a Set and performs trades via exchange wrappers for specified receive tokens. The receive * tokens are attributed to the caller. * * @param _exchangeIssuanceParams A Struct containing exchange issuance metadata * @param _orderData Bytes array containing the exchange orders to execute */ function exchangeRedeem( ExchangeIssuanceLibrary.ExchangeIssuanceParams memory _exchangeIssuanceParams, bytes memory _orderData ) public nonReentrant { // Validate exchangeIssuanceParams validateExchangeIssuanceParams(_exchangeIssuanceParams); // Validate that all sendTokens are components of the Set SetTokenLibrary.validateTokensAreComponents( _exchangeIssuanceParams.setAddress, _exchangeIssuanceParams.sendTokens ); // Redeem Set into the vault, attributing components to this contract coreInstance.redeemModule( msg.sender, address(this), _exchangeIssuanceParams.setAddress, _exchangeIssuanceParams.quantity ); // Transfer the send tokens to the appropriate exchanges withdrawSendTokensFromVaultToExchangeWrappers( _exchangeIssuanceParams.sendTokenExchangeIds, _exchangeIssuanceParams.sendTokens, _exchangeIssuanceParams.sendTokenAmounts ); // Executes the orders, depositing tokens into the Vault to the user executeOrders(_exchangeIssuanceParams, _orderData); // Withdraw receive tokens from the Vault to the user coreInstance.batchWithdrawModule( msg.sender, msg.sender, _exchangeIssuanceParams.receiveTokens, _exchangeIssuanceParams.receiveTokenAmounts ); // Withdraw any remaining non-exchanged components to the user withdrawRemainingComponentsToUser(_exchangeIssuanceParams.setAddress); emit LogExchangeRedeem( _exchangeIssuanceParams.setAddress, msg.sender, _exchangeIssuanceParams.quantity, _exchangeIssuanceParams.receiveTokens, _exchangeIssuanceParams.receiveTokenAmounts ); } /* ============ Private Functions ============ */ /** * Calculates required tokens to receive, executes orders, and checks post-exchange receive balances. * * @param _exchangeIssuanceParams A Struct containing exchange issuance metadata * @param _orderData Bytes array containing the exchange orders to execute */ function executeOrders( ExchangeIssuanceLibrary.ExchangeIssuanceParams memory _exchangeIssuanceParams, bytes memory _orderData ) private { // Calculate expected receive token balances after exchange orders executed uint256[] memory requiredBalances = calculateReceiveTokenBalances( _exchangeIssuanceParams ); // Execute exchange orders executeExchangeOrders(_orderData); // Check that sender's receive tokens in Vault have been incremented correctly ExchangeIssuanceLibrary.validatePostExchangeReceiveTokenBalances( vault, _exchangeIssuanceParams.receiveTokens, requiredBalances, msg.sender ); } /** * Transfers send tokens from the user to the appropriate exchange wrapper. Used in exchange * issue. * * @param _sendTokenExchangeIds List of exchange wrapper enumerations corresponding to * the wrapper that will handle the component * @param _sendTokens Array of addresses of the payment tokens * @param _sendTokenAmounts Array of amounts of payment Tokens */ function transferSendTokensToExchangeWrappers( uint8[] memory _sendTokenExchangeIds, address[] memory _sendTokens, uint256[] memory _sendTokenAmounts ) private { for (uint256 i = 0; i < _sendTokens.length; i++) { // Get exchange wrapper address from state mapping based on enumeration address exchangeWrapper = coreInstance.exchangeIds(_sendTokenExchangeIds[i]); // Transfer send tokens to the appropriate exchange wrapper coreInstance.transferModule( _sendTokens[i], _sendTokenAmounts[i], msg.sender, exchangeWrapper ); } } /** * Transfers send tokens from the Vault to the appropriate exchange wrappers. Used in * exchange redeem. * * @param _sendTokenExchangeIds List of exchange wrapper enumerations corresponding to * the wrapper that will handle the component * @param _sendTokens Array of addresses of the payment tokens * @param _sendTokenAmounts Array of amounts of payment Tokens */ function withdrawSendTokensFromVaultToExchangeWrappers( uint8[] memory _sendTokenExchangeIds, address[] memory _sendTokens, uint256[] memory _sendTokenAmounts ) private { for (uint256 i = 0; i < _sendTokens.length; i++) { // Get exchange address from state mapping based on header exchange info address exchangeWrapper = coreInstance.exchangeIds(_sendTokenExchangeIds[i]); // Withdraw send tokens from vault (owned by this contract) to the appropriate exchange wrapper coreInstance.withdrawModule( address(this), exchangeWrapper, _sendTokens[i], _sendTokenAmounts[i] ); } } /** * Withdraws any remaining un-exchanged components from the Vault in the posession of this contract * to the caller * * @param _setAddress Address of the Base Set */ function withdrawRemainingComponentsToUser( address _setAddress ) private { address[] memory baseSetComponents = ISetToken(_setAddress).getComponents(); uint256[] memory baseSetWithdrawQuantities = new uint256[](baseSetComponents.length); for (uint256 i = 0; i < baseSetComponents.length; i++) { uint256 withdrawQuantity = vaultInstance.getOwnerBalance(baseSetComponents[i], address(this)); if (withdrawQuantity > 0) { baseSetWithdrawQuantities[i] = withdrawQuantity; } } // Return the unexchanged components to the user coreInstance.batchWithdrawModule( address(this), msg.sender, baseSetComponents, baseSetWithdrawQuantities ); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":false,"inputs":[{"components":[{"name":"setAddress","type":"address"},{"name":"quantity","type":"uint256"},{"name":"sendTokenExchangeIds","type":"uint8[]"},{"name":"sendTokens","type":"address[]"},{"name":"sendTokenAmounts","type":"uint256[]"},{"name":"receiveTokens","type":"address[]"},{"name":"receiveTokenAmounts","type":"uint256[]"}],"name":"_exchangeIssuanceParams","type":"tuple"},{"name":"_orderData","type":"bytes"}],"name":"exchangeRedeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"setAddress","type":"address"},{"name":"quantity","type":"uint256"},{"name":"sendTokenExchangeIds","type":"uint8[]"},{"name":"sendTokens","type":"address[]"},{"name":"sendTokenAmounts","type":"uint256[]"},{"name":"receiveTokens","type":"address[]"},{"name":"receiveTokenAmounts","type":"uint256[]"}],"name":"_exchangeIssuanceParams","type":"tuple"},{"name":"_orderData","type":"bytes"}],"name":"exchangeIssue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vaultInstance","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreInstance","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"core","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_core","type":"address"},{"name":"_vault","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"setAddress","type":"address"},{"indexed":true,"name":"callerAddress","type":"address"},{"indexed":false,"name":"quantity","type":"uint256"},{"indexed":false,"name":"sendTokens","type":"address[]"},{"indexed":false,"name":"sendTokenAmounts","type":"uint256[]"}],"name":"LogExchangeIssue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"setAddress","type":"address"},{"indexed":true,"name":"callerAddress","type":"address"},{"indexed":false,"name":"quantity","type":"uint256"},{"indexed":false,"name":"receiveTokens","type":"address[]"},{"indexed":false,"name":"receiveTokenAmounts","type":"uint256[]"}],"name":"LogExchangeRedeem","type":"event"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405160408062002a7d833981018060405262000033919081019062000099565b60008054600160a060020a03938416600160a060020a0319918216811790925560028054821690921790915560018054939092169281168317825560038054909116909217909155600455620000f7565b6000620000928251620000d8565b9392505050565b60008060408385031215620000ad57600080fd5b6000620000bb858562000084565b9250506020620000ce8582860162000084565b9150509250929050565b6000620000e582620000eb565b92915050565b600160a060020a031690565b61297680620001076000396000f3fe608060405234801561001057600080fd5b50600436106100655760e060020a6000350463188eec69811461006a5780633d0419d91461007f57806363dc4f9514610092578063a05cb755146100b0578063f2f4eb26146100b8578063fbfa77cf146100cd575b600080fd5b61007d610078366004611b5d565b6100d5565b005b61007d61008d366004611b5d565b61030b565b61009a610490565b6040516100a791906126f0565b60405180910390f35b61009a61049f565b6100c06104ae565b6040516100a79190612537565b6100c06104bd565b60048054600101908190556100e9836104cc565b825160608401516040517f03cd887000000000000000000000000000000000000000000000000000000000815273dc733ec262f32882f7c05525cc2d09f2c04d86ac926303cd88709261013e92600401612680565b60006040518083038186803b15801561015657600080fd5b505af415801561016a573d6000803e3d6000fd5b5050600254855160208701516040517f5990ca08000000000000000000000000000000000000000000000000000000008152600160a060020a039093169450635990ca0893506101c2923392309290916004016125c5565b600060405180830381600087803b1580156101dc57600080fd5b505af11580156101f0573d6000803e3d6000fd5b5050505061020b8360400151846060015185608001516105db565b610215838361072d565b60025460a084015160c08501516040517ffe93620e000000000000000000000000000000000000000000000000000000008152600160a060020a039093169263fe93620e9261026c9233928392919060040161257a565b600060405180830381600087803b15801561028657600080fd5b505af115801561029a573d6000803e3d6000fd5b505050506102ab8360000151610760565b8251602084015160a085015160c086015160405133947f06c4316d43c46a4ded573b4dee3cf64d66b87d192f4f6bd88b830ae18b29c7c0946102f094919390926126d5565b60405180910390a2600454811461030657600080fd5b505050565b600480546001019081905561031f836104cc565b825160a08401516040517f03cd887000000000000000000000000000000000000000000000000000000000815273dc733ec262f32882f7c05525cc2d09f2c04d86ac926303cd88709261037492600401612680565b60006040518083038186803b15801561038c57600080fd5b505af41580156103a0573d6000803e3d6000fd5b505050506103bb836040015184606001518560800151610967565b6103c5838361072d565b600254835160208501516040517f7c68561f000000000000000000000000000000000000000000000000000000008152600160a060020a0390931692637c68561f9261041992339283929190600401612545565b600060405180830381600087803b15801561043357600080fd5b505af1158015610447573d6000803e3d6000fd5b505084516020860151606087015160808801516040513396507fc7fce5271a7dcbf20bd48128dcbf6f2df01bceda67919e43870de3be7f1b069095506102f094939291906126d5565b600354600160a060020a031681565b600254600160a060020a031681565b600054600160a060020a031681565b600154600160a060020a031681565b60025481516040517ffef3ee73000000000000000000000000000000000000000000000000000000008152600160a060020a039092169163fef3ee739161051591600401612537565b60206040518083038186803b15801561052d57600080fd5b505afa158015610541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105659190810190611b3f565b61058d5760405160e560020a62461bcd0281526004016105849061278e565b60405180910390fd5b61059f81600001518260200151610ab1565b6000546040820151606083015160808401516105c693600160a060020a0316929190610b7c565b6105d88160a001518260c00151610ceb565b50565b60005b8251811015610727576002548451600091600160a060020a0316906356fe27849087908590811061060b57fe5b60200260200101516040518263ffffffff1660e060020a028152600401610632919061281e565b60206040518083038186803b15801561064a57600080fd5b505afa15801561065e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106829190810190611ae4565b6002548551919250600160a060020a031690630e1fd33490309084908890879081106106aa57fe5b60200260200101518787815181106106be57fe5b60200260200101516040518563ffffffff1660e060020a0281526004016106e89493929190612657565b600060405180830381600087803b15801561070257600080fd5b505af1158015610716573d6000803e3d6000fd5b5050600190930192506105de915050565b50505050565b606061073883610da2565b905061074382610ee2565b60015460a084015161030691600160a060020a031690833361109d565b606081600160a060020a03166399d50d5d6040518163ffffffff1660e060020a02815260040160006040518083038186803b15801561079e57600080fd5b505afa1580156107b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107da9190810190611b0a565b905060608151604051908082528060200260200182016040528015610809578160200160208202803883390190505b50905060005b82518110156108e0576003548351600091600160a060020a031690631f98ade39086908590811061083c57fe5b6020026020010151306040518363ffffffff1660e060020a0281526004016108659291906125e0565b60206040518083038186803b15801561087d57600080fd5b505afa158015610891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108b59190810190611bfb565b905080156108d757808383815181106108ca57fe5b6020026020010181815250505b5060010161080f565b506002546040517ffe93620e000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063fe93620e90610930903090339087908790600401612616565b600060405180830381600087803b15801561094a57600080fd5b505af115801561095e573d6000803e3d6000fd5b50505050505050565b60005b8251811015610727576002548451600091600160a060020a0316906356fe27849087908590811061099757fe5b60200260200101516040518263ffffffff1660e060020a0281526004016109be919061281e565b60206040518083038186803b1580156109d657600080fd5b505afa1580156109ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a0e9190810190611ae4565b6002548551919250600160a060020a03169063fd496ebf90869085908110610a3257fe5b6020026020010151858581518110610a4657fe5b602002602001015133856040518563ffffffff1660e060020a028152600401610a7294939291906126a0565b600060405180830381600087803b158015610a8c57600080fd5b505af1158015610aa0573d6000803e3d6000fd5b50506001909301925061096a915050565b60008111610ad45760405160e560020a62461bcd028152600401610584906127be565b610b5882600160a060020a03166342a7cfd56040518163ffffffff1660e060020a02815260040160206040518083038186803b158015610b1357600080fd5b505afa158015610b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b4b9190810190611bfb565b829063ffffffff61118116565b15610b785760405160e560020a62461bcd0281526004016105849061279e565b5050565b6000825111610ba05760405160e560020a62461bcd0281526004016105849061273e565b81518351148015610bb2575080518251145b610bd15760405160e560020a62461bcd028152600401610584906127ce565b8360005b8451811015610ce3576000600160a060020a031682600160a060020a03166356fe2784878481518110610c0457fe5b60200260200101516040518263ffffffff1660e060020a028152600401610c2b919061281e565b60206040518083038186803b158015610c4357600080fd5b505afa158015610c57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c7b9190810190611ae4565b600160a060020a03161415610ca55760405160e560020a62461bcd0281526004016105849061274e565b6000838281518110610cb357fe5b602002602001015111610cdb5760405160e560020a62461bcd028152600401610584906127de565b600101610bd5565b505050505050565b815180610d0d5760405160e560020a62461bcd0281526004016105849061276e565b610d16836111a0565b15610d365760405160e560020a62461bcd0281526004016105849061277e565b81518114610d595760405160e560020a62461bcd0281526004016105849061275e565b60005b81811015610727576000838281518110610d7257fe5b602002602001015111610d9a5760405160e560020a62461bcd028152600401610584906127ae565b600101610d5c565b6060808260a0015151604051908082528060200260200182016040528015610dd4578160200160208202803883390190505b50905060005b8360a0015151811015610ed95760035460a08501518051600092600160a060020a031691631f98ade39185908110610e0e57fe5b6020026020010151336040518363ffffffff1660e060020a028152600401610e379291906125fb565b60206040518083038186803b158015610e4f57600080fd5b505afa158015610e63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e879190810190611bfb565b905060008560c001518381518110610e9b57fe5b60200260200101519050610eb8818361123690919063ffffffff16565b848481518110610ec457fe5b60209081029190910101525050600101610dda565b5090505b919050565b6000805b825181101561030657610ef76115b3565b610f01848361124f565b60025481516040517f56fe2784000000000000000000000000000000000000000000000000000000008152929350600092600160a060020a03909216916356fe278491610f509160040161281e565b60206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fa09190810190611ae4565b9050600160a060020a038116610fcb5760405160e560020a62461bcd028152600401610584906126fe565b6000610fdf6002846000015160ff1661129a565b9050848116156110045760405160e560020a62461bcd028152600401610584906127ee565b60006110226110116112d9565b60408601519063ffffffff61123616565b905060606110318887846112de565b905061103b6115d3565b506040805180820190915233815260208681015160ff169082015260005461106e90600160a060020a031682878561131b565b61107e878463ffffffff61123616565b9650611090888563ffffffff61123616565b9750505050505050610ee6565b8360005b8451811015610ce357600082600160a060020a0316631f98ade38784815181106110c757fe5b6020026020010151866040518363ffffffff1660e060020a0281526004016110f09291906125e0565b60206040518083038186803b15801561110857600080fd5b505afa15801561111c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111409190810190611bfb565b905084828151811061114e57fe5b60200260200101518110156111785760405160e560020a62461bcd0281526004016105849061270e565b506001016110a1565b60008161118d57600080fd5b81838161119657fe5b0690505b92915050565b60008151600014156111b457506000610edd565b60005b600183510381101561122d57600181015b8351811015611224578381815181106111dd57fe5b6020026020010151600160a060020a03168483815181106111fa57fe5b6020026020010151600160a060020a0316141561121c57600192505050610edd565b6001016111c8565b506001016111b7565b50600092915050565b60008282018381101561124857600080fd5b9392505050565b6112576115b3565b61125f6115b3565b600061127a8461126e8761144f565b9063ffffffff61123616565b805183526020808201519084015260409081015190830152509392505050565b60008083116112a857600080fd5b600160005b838110156112d157816112c6818763ffffffff61145516565b9250506001016112ad565b509392505050565b606090565b606080611312856112fd6112f06112d9565b879063ffffffff61123616565b61130d878763ffffffff61123616565b61147c565b95945050505050565b6113236115ea565b6040517fc58c1db8000000000000000000000000000000000000000000000000000000008152600160a060020a0384169063c58c1db89061136a90879086906004016127fe565b600060405180830381600087803b15801561138457600080fd5b505af1158015611398573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113c09190810190611bc6565b8451815160208301516040517fcaaa3ada000000000000000000000000000000000000000000000000000000008152939450600160a060020a0389169363caaa3ada936114169389939192909190600401612665565b600060405180830381600087803b15801561143057600080fd5b505af1158015611444573d6000803e3d6000fd5b505050505050505050565b60200190565b6000826114645750600061119a565b8282028284828161147157fe5b041461124857600080fd5b6060818311156114a15760405160e560020a62461bcd0281526004016105849061271e565b83518211156114c55760405160e560020a62461bcd0281526004016105849061272e565b8282036040519080825280601f01601f1916602001820160405280156114f2576020820181803883390190505b5090506112486115018261144f565b8461150b8761144f565b0183516020811015611538576001816020036101000a038019835116818551168082178652505050610306565b8282141561154557610306565b8282111561157f5760208103905080820181840181515b8285101561157757845186526020958601959094019361155c565b905250610306565b60208103905080820181840183515b818612156115aa5782518252601f19928301929091019061158e565b85525050505050565b604080516060810182526000808252602082018190529181019190915290565b604080518082019091526000808252602082015290565b604051806040016040528060608152602001606081525090565b600061124882356128a9565b600061124882516128a9565b600082601f83011261162d57600080fd5b813561164061163b82612853565b61282c565b9150818183526020840193506020810190508385602084028201111561166557600080fd5b60005b83811015611691578161167b8882611604565b8452506020928301929190910190600101611668565b5050505092915050565b600082601f8301126116ac57600080fd5b81516116ba61163b82612853565b915081818352602084019350602081019050838560208402820111156116df57600080fd5b60005b8381101561169157816116f58882611610565b84525060209283019291909101906001016116e2565b600082601f83011261171c57600080fd5b815161172a61163b82612853565b9150818183526020840193506020810190508385602084028201111561174f57600080fd5b60005b8381101561169157816117658882611610565b8452506020928301929190910190600101611752565b600082601f83011261178c57600080fd5b813561179a61163b82612853565b915081818352602084019350602081019050838560208402820111156117bf57600080fd5b60005b8381101561169157816117d58882611ac0565b84525060209283019291909101906001016117c2565b600082601f8301126117fc57600080fd5b815161180a61163b82612853565b9150818183526020840193506020810190508385602084028201111561182f57600080fd5b60005b8381101561169157816118458882611acc565b8452506020928301929190910190600101611832565b600082601f83011261186c57600080fd5b813561187a61163b82612853565b9150818183526020840193506020810190508385602084028201111561189f57600080fd5b60005b8381101561169157816118b58882611ad8565b84525060209283019291909101906001016118a2565b600061124882516128c3565b600082601f8301126118e857600080fd5b81356118f661163b82612874565b9150808252602083016020830185838301111561191257600080fd5b61191d8382846128da565b50505092915050565b600060e0828403121561193857600080fd5b61194260e061282c565b905060006119508484611604565b825250602061196184848301611ac0565b602083015250604082013567ffffffffffffffff81111561198157600080fd5b61198d8482850161185b565b604083015250606082013567ffffffffffffffff8111156119ad57600080fd5b6119b98482850161161c565b606083015250608082013567ffffffffffffffff8111156119d957600080fd5b6119e58482850161177b565b60808301525060a082013567ffffffffffffffff811115611a0557600080fd5b611a118482850161161c565b60a08301525060c082013567ffffffffffffffff811115611a3157600080fd5b611a3d8482850161177b565b60c08301525092915050565b600060408284031215611a5b57600080fd5b611a65604061282c565b825190915067ffffffffffffffff811115611a7f57600080fd5b611a8b8482850161169b565b825250602082015167ffffffffffffffff811115611aa857600080fd5b611ab4848285016117eb565b60208301525092915050565b600061124882356128ba565b600061124882516128ba565b600061124882356128bd565b600060208284031215611af657600080fd5b6000611b028484611610565b949350505050565b600060208284031215611b1c57600080fd5b815167ffffffffffffffff811115611b3357600080fd5b611b028482850161170b565b600060208284031215611b5157600080fd5b6000611b0284846118cb565b60008060408385031215611b7057600080fd5b823567ffffffffffffffff811115611b8757600080fd5b611b9385828601611926565b925050602083013567ffffffffffffffff811115611bb057600080fd5b611bbc858286016118d7565b9150509250929050565b600060208284031215611bd857600080fd5b815167ffffffffffffffff811115611bef57600080fd5b611b0284828501611a49565b600060208284031215611c0d57600080fd5b6000611b028484611acc565b6000611c258383611c48565b505060200190565b6000611c258383612525565b611c42816128c8565b82525050565b611c42816128a9565b6000611c5c8261289c565b611c6681856128a0565b9350611c718361144f565b60005b82811015611c9c57611c87868351611c19565b9550611c928261144f565b9150600101611c74565b5093949350505050565b6000611cb18261289c565b611cbb81856128a0565b9350611cc68361144f565b60005b82811015611c9c57611cdc868351611c19565b9550611ce78261144f565b9150600101611cc9565b6000611cfc8261289c565b611d0681856128a0565b9350611d118361144f565b60005b82811015611c9c57611d27868351611c19565b9550611d328261144f565b9150600101611d14565b6000611d478261289c565b611d5181856128a0565b9350611d5c8361144f565b60005b82811015611c9c57611d72868351611c2d565b9550611d7d8261144f565b9150600101611d5f565b6000611d928261289c565b611d9c81856128a0565b9350611da78361144f565b60005b82811015611c9c57611dbd868351611c2d565b9550611dc88261144f565b9150600101611daa565b6000611ddd8261289c565b611de781856128a0565b9350611df78185602086016128e6565b611e0081612912565b9093019392505050565b611c42816128cf565b6000611e20604d836128a0565b7f45786368616e6765457865637574696f6e2e6578656375746545786368616e6781527f654f72646572733a20496e76616c6964206f722064697361626c65642045786360208201527f68616e6765206164647265737300000000000000000000000000000000000000604082015260600192915050565b6000611ea56065836128a0565b60008051602061291d83398151915281527f506f737445786368616e676552656365697665546f6b656e42616c616e63657360208201527f3a20496e73756666696369656e74207265636569766520746f6b656e2061637160408201527f7569726564000000000000000000000000000000000000000000000000000000606082015260800192915050565b6000611f3e601a836128a0565b7f46524f4d5f4c4553535f5448414e5f544f5f5245515549524544000000000000815260200192915050565b6000611f77601c836128a0565b7f544f5f4c4553535f5448414e5f4c454e4754485f524551554952454400000000815260200192915050565b6000611fb06054836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a2053656e6420746f6b656e20696e707560208201527f7473206d757374206e6f7420626520656d707479000000000000000000000000604082015260600192915050565b60006120236047836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a204d7573742062652076616c6964206560208201527f786368616e676500000000000000000000000000000000000000000000000000604082015260600192915050565b6000612096605e836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a205265636569766520746f6b656e7320616e60208201527f6420616d6f756e7473206d75737420626520657175616c206c656e6774680000604082015260600192915050565b6000612109604f836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a205265636569766520746f6b656e73206d7560208201527f7374206e6f7420626520656d7074790000000000000000000000000000000000604082015260600192915050565b600061217c6056836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a205265636569766520746f6b656e73206d7560208201527f7374206e6f742068617665206475706c69636174657300000000000000000000604082015260600192915050565b60006121ef6056836128a0565b7f45786368616e6765457865637574696f6e2e76616c696461746545786368616e81527f676549737375616e6365506172616d733a20496e76616c6964206f722064697360208201527f61626c656420536574546f6b656e206164647265737300000000000000000000604082015260600192915050565b60006122746053836128a0565b60008051602061291d83398151915281527f5175616e746974793a205175616e74697479206d757374206265206d756c746960208201527f706c65206f66206e61747572616c20756e697400000000000000000000000000604082015260600192915050565b60006122e76051836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a20436f6d706f6e656e7420616d6f756e747360208201527f206d75737420626520706f736974697665000000000000000000000000000000604082015260600192915050565b600061235a6043836128a0565b60008051602061291d83398151915281527f5175616e746974793a205175616e74697479206d75737420626520706f73697460208201527f6976650000000000000000000000000000000000000000000000000000000000604082015260600192915050565b60006123cd605d836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a2053656e6420746f6b656e20696e707560208201527f7473206d757374206265206f66207468652073616d65206c656e677468000000604082015260600192915050565b6000612440604e836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a2053656e6420616d6f756e7473206d7560208201527f737420626520706f736974697665000000000000000000000000000000000000604082015260600192915050565b60006124b36040836128a0565b7f45786368616e6765457865637574696f6e2e6578656375746545786368616e6781527f654f72646572733a2045786368616e676520616c72656164792063616c6c6564602082015260400192915050565b805160408301906125168482611c48565b50602082015161072760208501825b611c42816128ba565b611c42816128bd565b6020810161119a8284611c48565b608081016125538287611c39565b6125606020830186611c39565b61256d6040830185611c48565b6113126060830184612525565b608081016125888287611c39565b6125956020830186611c39565b81810360408301526125a78185611ca6565b905081810360608301526125bb8184611d87565b9695505050505050565b608081016125d38287611c39565b6125606020830186611c48565b604081016125ee8285611c48565b6112486020830184611c48565b604081016126098285611c48565b6112486020830184611c39565b608081016126248287611c48565b6126316020830186611c39565b81810360408301526126438185611c51565b905081810360608301526125bb8184611d3c565b608081016125d38287611c48565b608081016126738287611c48565b6125956020830186611c48565b6040810161268e8285611c48565b8181036020830152611b028184611cf1565b608081016126ae8287611c48565b6126bb6020830186612525565b6126c86040830185611c39565b6113126060830184611c48565b608081016126e38287611c48565b6125956020830186612525565b6020810161119a8284611e0a565b6020808252810161119a81611e13565b6020808252810161119a81611e98565b6020808252810161119a81611f31565b6020808252810161119a81611f6a565b6020808252810161119a81611fa3565b6020808252810161119a81612016565b6020808252810161119a81612089565b6020808252810161119a816120fc565b6020808252810161119a8161216f565b6020808252810161119a816121e2565b6020808252810161119a81612267565b6020808252810161119a816122da565b6020808252810161119a8161234d565b6020808252810161119a816123c0565b6020808252810161119a81612433565b6020808252810161119a816124a6565b6060810161280c8285612505565b8181036040830152611b028184611dd2565b6020810161119a828461252e565b60405181810167ffffffffffffffff8111828210171561284b57600080fd5b604052919050565b600067ffffffffffffffff82111561286a57600080fd5b5060209081020190565b600067ffffffffffffffff82111561288b57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b6000600160a060020a03821661119a565b90565b60ff1690565b151590565b600061119a825b600061119a826128a9565b82818337506000910152565b60005b838110156129015781810151838201526020016128e9565b838111156107275750506000910152565b601f01601f19169056fe45786368616e676549737375616e63654c6962726172792e76616c6964617465a265627a7a723058203be3bbc9bd418298498d2c846169e588e21fd0ba0c65c80f21a0c3d5adebf4466c6578706572696d656e74616cf50037000000000000000000000000f55186cc537e7067ea616f2aae007b4427a120c80000000000000000000000005b67871c3a857de81a1ca0f9f7945e5670d986dc
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100655760e060020a6000350463188eec69811461006a5780633d0419d91461007f57806363dc4f9514610092578063a05cb755146100b0578063f2f4eb26146100b8578063fbfa77cf146100cd575b600080fd5b61007d610078366004611b5d565b6100d5565b005b61007d61008d366004611b5d565b61030b565b61009a610490565b6040516100a791906126f0565b60405180910390f35b61009a61049f565b6100c06104ae565b6040516100a79190612537565b6100c06104bd565b60048054600101908190556100e9836104cc565b825160608401516040517f03cd887000000000000000000000000000000000000000000000000000000000815273dc733ec262f32882f7c05525cc2d09f2c04d86ac926303cd88709261013e92600401612680565b60006040518083038186803b15801561015657600080fd5b505af415801561016a573d6000803e3d6000fd5b5050600254855160208701516040517f5990ca08000000000000000000000000000000000000000000000000000000008152600160a060020a039093169450635990ca0893506101c2923392309290916004016125c5565b600060405180830381600087803b1580156101dc57600080fd5b505af11580156101f0573d6000803e3d6000fd5b5050505061020b8360400151846060015185608001516105db565b610215838361072d565b60025460a084015160c08501516040517ffe93620e000000000000000000000000000000000000000000000000000000008152600160a060020a039093169263fe93620e9261026c9233928392919060040161257a565b600060405180830381600087803b15801561028657600080fd5b505af115801561029a573d6000803e3d6000fd5b505050506102ab8360000151610760565b8251602084015160a085015160c086015160405133947f06c4316d43c46a4ded573b4dee3cf64d66b87d192f4f6bd88b830ae18b29c7c0946102f094919390926126d5565b60405180910390a2600454811461030657600080fd5b505050565b600480546001019081905561031f836104cc565b825160a08401516040517f03cd887000000000000000000000000000000000000000000000000000000000815273dc733ec262f32882f7c05525cc2d09f2c04d86ac926303cd88709261037492600401612680565b60006040518083038186803b15801561038c57600080fd5b505af41580156103a0573d6000803e3d6000fd5b505050506103bb836040015184606001518560800151610967565b6103c5838361072d565b600254835160208501516040517f7c68561f000000000000000000000000000000000000000000000000000000008152600160a060020a0390931692637c68561f9261041992339283929190600401612545565b600060405180830381600087803b15801561043357600080fd5b505af1158015610447573d6000803e3d6000fd5b505084516020860151606087015160808801516040513396507fc7fce5271a7dcbf20bd48128dcbf6f2df01bceda67919e43870de3be7f1b069095506102f094939291906126d5565b600354600160a060020a031681565b600254600160a060020a031681565b600054600160a060020a031681565b600154600160a060020a031681565b60025481516040517ffef3ee73000000000000000000000000000000000000000000000000000000008152600160a060020a039092169163fef3ee739161051591600401612537565b60206040518083038186803b15801561052d57600080fd5b505afa158015610541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105659190810190611b3f565b61058d5760405160e560020a62461bcd0281526004016105849061278e565b60405180910390fd5b61059f81600001518260200151610ab1565b6000546040820151606083015160808401516105c693600160a060020a0316929190610b7c565b6105d88160a001518260c00151610ceb565b50565b60005b8251811015610727576002548451600091600160a060020a0316906356fe27849087908590811061060b57fe5b60200260200101516040518263ffffffff1660e060020a028152600401610632919061281e565b60206040518083038186803b15801561064a57600080fd5b505afa15801561065e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106829190810190611ae4565b6002548551919250600160a060020a031690630e1fd33490309084908890879081106106aa57fe5b60200260200101518787815181106106be57fe5b60200260200101516040518563ffffffff1660e060020a0281526004016106e89493929190612657565b600060405180830381600087803b15801561070257600080fd5b505af1158015610716573d6000803e3d6000fd5b5050600190930192506105de915050565b50505050565b606061073883610da2565b905061074382610ee2565b60015460a084015161030691600160a060020a031690833361109d565b606081600160a060020a03166399d50d5d6040518163ffffffff1660e060020a02815260040160006040518083038186803b15801561079e57600080fd5b505afa1580156107b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107da9190810190611b0a565b905060608151604051908082528060200260200182016040528015610809578160200160208202803883390190505b50905060005b82518110156108e0576003548351600091600160a060020a031690631f98ade39086908590811061083c57fe5b6020026020010151306040518363ffffffff1660e060020a0281526004016108659291906125e0565b60206040518083038186803b15801561087d57600080fd5b505afa158015610891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108b59190810190611bfb565b905080156108d757808383815181106108ca57fe5b6020026020010181815250505b5060010161080f565b506002546040517ffe93620e000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063fe93620e90610930903090339087908790600401612616565b600060405180830381600087803b15801561094a57600080fd5b505af115801561095e573d6000803e3d6000fd5b50505050505050565b60005b8251811015610727576002548451600091600160a060020a0316906356fe27849087908590811061099757fe5b60200260200101516040518263ffffffff1660e060020a0281526004016109be919061281e565b60206040518083038186803b1580156109d657600080fd5b505afa1580156109ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a0e9190810190611ae4565b6002548551919250600160a060020a03169063fd496ebf90869085908110610a3257fe5b6020026020010151858581518110610a4657fe5b602002602001015133856040518563ffffffff1660e060020a028152600401610a7294939291906126a0565b600060405180830381600087803b158015610a8c57600080fd5b505af1158015610aa0573d6000803e3d6000fd5b50506001909301925061096a915050565b60008111610ad45760405160e560020a62461bcd028152600401610584906127be565b610b5882600160a060020a03166342a7cfd56040518163ffffffff1660e060020a02815260040160206040518083038186803b158015610b1357600080fd5b505afa158015610b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b4b9190810190611bfb565b829063ffffffff61118116565b15610b785760405160e560020a62461bcd0281526004016105849061279e565b5050565b6000825111610ba05760405160e560020a62461bcd0281526004016105849061273e565b81518351148015610bb2575080518251145b610bd15760405160e560020a62461bcd028152600401610584906127ce565b8360005b8451811015610ce3576000600160a060020a031682600160a060020a03166356fe2784878481518110610c0457fe5b60200260200101516040518263ffffffff1660e060020a028152600401610c2b919061281e565b60206040518083038186803b158015610c4357600080fd5b505afa158015610c57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c7b9190810190611ae4565b600160a060020a03161415610ca55760405160e560020a62461bcd0281526004016105849061274e565b6000838281518110610cb357fe5b602002602001015111610cdb5760405160e560020a62461bcd028152600401610584906127de565b600101610bd5565b505050505050565b815180610d0d5760405160e560020a62461bcd0281526004016105849061276e565b610d16836111a0565b15610d365760405160e560020a62461bcd0281526004016105849061277e565b81518114610d595760405160e560020a62461bcd0281526004016105849061275e565b60005b81811015610727576000838281518110610d7257fe5b602002602001015111610d9a5760405160e560020a62461bcd028152600401610584906127ae565b600101610d5c565b6060808260a0015151604051908082528060200260200182016040528015610dd4578160200160208202803883390190505b50905060005b8360a0015151811015610ed95760035460a08501518051600092600160a060020a031691631f98ade39185908110610e0e57fe5b6020026020010151336040518363ffffffff1660e060020a028152600401610e379291906125fb565b60206040518083038186803b158015610e4f57600080fd5b505afa158015610e63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e879190810190611bfb565b905060008560c001518381518110610e9b57fe5b60200260200101519050610eb8818361123690919063ffffffff16565b848481518110610ec457fe5b60209081029190910101525050600101610dda565b5090505b919050565b6000805b825181101561030657610ef76115b3565b610f01848361124f565b60025481516040517f56fe2784000000000000000000000000000000000000000000000000000000008152929350600092600160a060020a03909216916356fe278491610f509160040161281e565b60206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fa09190810190611ae4565b9050600160a060020a038116610fcb5760405160e560020a62461bcd028152600401610584906126fe565b6000610fdf6002846000015160ff1661129a565b9050848116156110045760405160e560020a62461bcd028152600401610584906127ee565b60006110226110116112d9565b60408601519063ffffffff61123616565b905060606110318887846112de565b905061103b6115d3565b506040805180820190915233815260208681015160ff169082015260005461106e90600160a060020a031682878561131b565b61107e878463ffffffff61123616565b9650611090888563ffffffff61123616565b9750505050505050610ee6565b8360005b8451811015610ce357600082600160a060020a0316631f98ade38784815181106110c757fe5b6020026020010151866040518363ffffffff1660e060020a0281526004016110f09291906125e0565b60206040518083038186803b15801561110857600080fd5b505afa15801561111c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111409190810190611bfb565b905084828151811061114e57fe5b60200260200101518110156111785760405160e560020a62461bcd0281526004016105849061270e565b506001016110a1565b60008161118d57600080fd5b81838161119657fe5b0690505b92915050565b60008151600014156111b457506000610edd565b60005b600183510381101561122d57600181015b8351811015611224578381815181106111dd57fe5b6020026020010151600160a060020a03168483815181106111fa57fe5b6020026020010151600160a060020a0316141561121c57600192505050610edd565b6001016111c8565b506001016111b7565b50600092915050565b60008282018381101561124857600080fd5b9392505050565b6112576115b3565b61125f6115b3565b600061127a8461126e8761144f565b9063ffffffff61123616565b805183526020808201519084015260409081015190830152509392505050565b60008083116112a857600080fd5b600160005b838110156112d157816112c6818763ffffffff61145516565b9250506001016112ad565b509392505050565b606090565b606080611312856112fd6112f06112d9565b879063ffffffff61123616565b61130d878763ffffffff61123616565b61147c565b95945050505050565b6113236115ea565b6040517fc58c1db8000000000000000000000000000000000000000000000000000000008152600160a060020a0384169063c58c1db89061136a90879086906004016127fe565b600060405180830381600087803b15801561138457600080fd5b505af1158015611398573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113c09190810190611bc6565b8451815160208301516040517fcaaa3ada000000000000000000000000000000000000000000000000000000008152939450600160a060020a0389169363caaa3ada936114169389939192909190600401612665565b600060405180830381600087803b15801561143057600080fd5b505af1158015611444573d6000803e3d6000fd5b505050505050505050565b60200190565b6000826114645750600061119a565b8282028284828161147157fe5b041461124857600080fd5b6060818311156114a15760405160e560020a62461bcd0281526004016105849061271e565b83518211156114c55760405160e560020a62461bcd0281526004016105849061272e565b8282036040519080825280601f01601f1916602001820160405280156114f2576020820181803883390190505b5090506112486115018261144f565b8461150b8761144f565b0183516020811015611538576001816020036101000a038019835116818551168082178652505050610306565b8282141561154557610306565b8282111561157f5760208103905080820181840181515b8285101561157757845186526020958601959094019361155c565b905250610306565b60208103905080820181840183515b818612156115aa5782518252601f19928301929091019061158e565b85525050505050565b604080516060810182526000808252602082018190529181019190915290565b604080518082019091526000808252602082015290565b604051806040016040528060608152602001606081525090565b600061124882356128a9565b600061124882516128a9565b600082601f83011261162d57600080fd5b813561164061163b82612853565b61282c565b9150818183526020840193506020810190508385602084028201111561166557600080fd5b60005b83811015611691578161167b8882611604565b8452506020928301929190910190600101611668565b5050505092915050565b600082601f8301126116ac57600080fd5b81516116ba61163b82612853565b915081818352602084019350602081019050838560208402820111156116df57600080fd5b60005b8381101561169157816116f58882611610565b84525060209283019291909101906001016116e2565b600082601f83011261171c57600080fd5b815161172a61163b82612853565b9150818183526020840193506020810190508385602084028201111561174f57600080fd5b60005b8381101561169157816117658882611610565b8452506020928301929190910190600101611752565b600082601f83011261178c57600080fd5b813561179a61163b82612853565b915081818352602084019350602081019050838560208402820111156117bf57600080fd5b60005b8381101561169157816117d58882611ac0565b84525060209283019291909101906001016117c2565b600082601f8301126117fc57600080fd5b815161180a61163b82612853565b9150818183526020840193506020810190508385602084028201111561182f57600080fd5b60005b8381101561169157816118458882611acc565b8452506020928301929190910190600101611832565b600082601f83011261186c57600080fd5b813561187a61163b82612853565b9150818183526020840193506020810190508385602084028201111561189f57600080fd5b60005b8381101561169157816118b58882611ad8565b84525060209283019291909101906001016118a2565b600061124882516128c3565b600082601f8301126118e857600080fd5b81356118f661163b82612874565b9150808252602083016020830185838301111561191257600080fd5b61191d8382846128da565b50505092915050565b600060e0828403121561193857600080fd5b61194260e061282c565b905060006119508484611604565b825250602061196184848301611ac0565b602083015250604082013567ffffffffffffffff81111561198157600080fd5b61198d8482850161185b565b604083015250606082013567ffffffffffffffff8111156119ad57600080fd5b6119b98482850161161c565b606083015250608082013567ffffffffffffffff8111156119d957600080fd5b6119e58482850161177b565b60808301525060a082013567ffffffffffffffff811115611a0557600080fd5b611a118482850161161c565b60a08301525060c082013567ffffffffffffffff811115611a3157600080fd5b611a3d8482850161177b565b60c08301525092915050565b600060408284031215611a5b57600080fd5b611a65604061282c565b825190915067ffffffffffffffff811115611a7f57600080fd5b611a8b8482850161169b565b825250602082015167ffffffffffffffff811115611aa857600080fd5b611ab4848285016117eb565b60208301525092915050565b600061124882356128ba565b600061124882516128ba565b600061124882356128bd565b600060208284031215611af657600080fd5b6000611b028484611610565b949350505050565b600060208284031215611b1c57600080fd5b815167ffffffffffffffff811115611b3357600080fd5b611b028482850161170b565b600060208284031215611b5157600080fd5b6000611b0284846118cb565b60008060408385031215611b7057600080fd5b823567ffffffffffffffff811115611b8757600080fd5b611b9385828601611926565b925050602083013567ffffffffffffffff811115611bb057600080fd5b611bbc858286016118d7565b9150509250929050565b600060208284031215611bd857600080fd5b815167ffffffffffffffff811115611bef57600080fd5b611b0284828501611a49565b600060208284031215611c0d57600080fd5b6000611b028484611acc565b6000611c258383611c48565b505060200190565b6000611c258383612525565b611c42816128c8565b82525050565b611c42816128a9565b6000611c5c8261289c565b611c6681856128a0565b9350611c718361144f565b60005b82811015611c9c57611c87868351611c19565b9550611c928261144f565b9150600101611c74565b5093949350505050565b6000611cb18261289c565b611cbb81856128a0565b9350611cc68361144f565b60005b82811015611c9c57611cdc868351611c19565b9550611ce78261144f565b9150600101611cc9565b6000611cfc8261289c565b611d0681856128a0565b9350611d118361144f565b60005b82811015611c9c57611d27868351611c19565b9550611d328261144f565b9150600101611d14565b6000611d478261289c565b611d5181856128a0565b9350611d5c8361144f565b60005b82811015611c9c57611d72868351611c2d565b9550611d7d8261144f565b9150600101611d5f565b6000611d928261289c565b611d9c81856128a0565b9350611da78361144f565b60005b82811015611c9c57611dbd868351611c2d565b9550611dc88261144f565b9150600101611daa565b6000611ddd8261289c565b611de781856128a0565b9350611df78185602086016128e6565b611e0081612912565b9093019392505050565b611c42816128cf565b6000611e20604d836128a0565b7f45786368616e6765457865637574696f6e2e6578656375746545786368616e6781527f654f72646572733a20496e76616c6964206f722064697361626c65642045786360208201527f68616e6765206164647265737300000000000000000000000000000000000000604082015260600192915050565b6000611ea56065836128a0565b60008051602061291d83398151915281527f506f737445786368616e676552656365697665546f6b656e42616c616e63657360208201527f3a20496e73756666696369656e74207265636569766520746f6b656e2061637160408201527f7569726564000000000000000000000000000000000000000000000000000000606082015260800192915050565b6000611f3e601a836128a0565b7f46524f4d5f4c4553535f5448414e5f544f5f5245515549524544000000000000815260200192915050565b6000611f77601c836128a0565b7f544f5f4c4553535f5448414e5f4c454e4754485f524551554952454400000000815260200192915050565b6000611fb06054836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a2053656e6420746f6b656e20696e707560208201527f7473206d757374206e6f7420626520656d707479000000000000000000000000604082015260600192915050565b60006120236047836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a204d7573742062652076616c6964206560208201527f786368616e676500000000000000000000000000000000000000000000000000604082015260600192915050565b6000612096605e836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a205265636569766520746f6b656e7320616e60208201527f6420616d6f756e7473206d75737420626520657175616c206c656e6774680000604082015260600192915050565b6000612109604f836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a205265636569766520746f6b656e73206d7560208201527f7374206e6f7420626520656d7074790000000000000000000000000000000000604082015260600192915050565b600061217c6056836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a205265636569766520746f6b656e73206d7560208201527f7374206e6f742068617665206475706c69636174657300000000000000000000604082015260600192915050565b60006121ef6056836128a0565b7f45786368616e6765457865637574696f6e2e76616c696461746545786368616e81527f676549737375616e6365506172616d733a20496e76616c6964206f722064697360208201527f61626c656420536574546f6b656e206164647265737300000000000000000000604082015260600192915050565b60006122746053836128a0565b60008051602061291d83398151915281527f5175616e746974793a205175616e74697479206d757374206265206d756c746960208201527f706c65206f66206e61747572616c20756e697400000000000000000000000000604082015260600192915050565b60006122e76051836128a0565b60008051602061291d83398151915281527f52656365697665546f6b656e733a20436f6d706f6e656e7420616d6f756e747360208201527f206d75737420626520706f736974697665000000000000000000000000000000604082015260600192915050565b600061235a6043836128a0565b60008051602061291d83398151915281527f5175616e746974793a205175616e74697479206d75737420626520706f73697460208201527f6976650000000000000000000000000000000000000000000000000000000000604082015260600192915050565b60006123cd605d836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a2053656e6420746f6b656e20696e707560208201527f7473206d757374206265206f66207468652073616d65206c656e677468000000604082015260600192915050565b6000612440604e836128a0565b60008051602061291d83398151915281527f53656e64546f6b656e506172616d733a2053656e6420616d6f756e7473206d7560208201527f737420626520706f736974697665000000000000000000000000000000000000604082015260600192915050565b60006124b36040836128a0565b7f45786368616e6765457865637574696f6e2e6578656375746545786368616e6781527f654f72646572733a2045786368616e676520616c72656164792063616c6c6564602082015260400192915050565b805160408301906125168482611c48565b50602082015161072760208501825b611c42816128ba565b611c42816128bd565b6020810161119a8284611c48565b608081016125538287611c39565b6125606020830186611c39565b61256d6040830185611c48565b6113126060830184612525565b608081016125888287611c39565b6125956020830186611c39565b81810360408301526125a78185611ca6565b905081810360608301526125bb8184611d87565b9695505050505050565b608081016125d38287611c39565b6125606020830186611c48565b604081016125ee8285611c48565b6112486020830184611c48565b604081016126098285611c48565b6112486020830184611c39565b608081016126248287611c48565b6126316020830186611c39565b81810360408301526126438185611c51565b905081810360608301526125bb8184611d3c565b608081016125d38287611c48565b608081016126738287611c48565b6125956020830186611c48565b6040810161268e8285611c48565b8181036020830152611b028184611cf1565b608081016126ae8287611c48565b6126bb6020830186612525565b6126c86040830185611c39565b6113126060830184611c48565b608081016126e38287611c48565b6125956020830186612525565b6020810161119a8284611e0a565b6020808252810161119a81611e13565b6020808252810161119a81611e98565b6020808252810161119a81611f31565b6020808252810161119a81611f6a565b6020808252810161119a81611fa3565b6020808252810161119a81612016565b6020808252810161119a81612089565b6020808252810161119a816120fc565b6020808252810161119a8161216f565b6020808252810161119a816121e2565b6020808252810161119a81612267565b6020808252810161119a816122da565b6020808252810161119a8161234d565b6020808252810161119a816123c0565b6020808252810161119a81612433565b6020808252810161119a816124a6565b6060810161280c8285612505565b8181036040830152611b028184611dd2565b6020810161119a828461252e565b60405181810167ffffffffffffffff8111828210171561284b57600080fd5b604052919050565b600067ffffffffffffffff82111561286a57600080fd5b5060209081020190565b600067ffffffffffffffff82111561288b57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b6000600160a060020a03821661119a565b90565b60ff1690565b151590565b600061119a825b600061119a826128a9565b82818337506000910152565b60005b838110156129015781810151838201526020016128e9565b838111156107275750506000910152565b601f01601f19169056fe45786368616e676549737375616e63654c6962726172792e76616c6964617465a265627a7a723058203be3bbc9bd418298498d2c846169e588e21fd0ba0c65c80f21a0c3d5adebf4466c6578706572696d656e74616cf50037
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f55186cc537e7067ea616f2aae007b4427a120c80000000000000000000000005b67871c3a857de81a1ca0f9f7945e5670d986dc
-----Decoded View---------------
Arg [0] : _core (address): 0xf55186CC537E7067EA616F2aaE007b4427a120C8
Arg [1] : _vault (address): 0x5B67871C3a857dE81A1ca0f9F7945e5670D986Dc
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000f55186cc537e7067ea616f2aae007b4427a120c8
Arg [1] : 0000000000000000000000005b67871c3a857de81a1ca0f9f7945e5670d986dc
Deployed Bytecode Sourcemap
88211:10035:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;88211:10035:0;;;;;;-1:-1:-1;;;88211:10035:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91494:1972;;;;;;;;;:::i;:::-;;89621:1483;;;;;;;;;:::i;76288:27::-;;;:::i;:::-;;;;;;;;;;;;;;;;76219:25;;;:::i;76094:19::-;;;:::i;:::-;;;;;;;;76156:20;;;:::i;91494:1972::-;1197:13;:18;;1214:1;1197:18;;;;;91745:55;91776:23;91745:30;:55::i;:::-;91938:34;;91987;;;;91880:152;;;;;:15;;:43;;:152;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91880:152:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;92124:12:0;;92217:34;;92266:32;;;;92124:185;;;;;-1:-1:-1;;;;;92124:12:0;;;;-1:-1:-1;92124:25:0;;-1:-1:-1;92124:185:0;;92164:10;;92197:4;;92217:34;;92124:185;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;92124:185:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92124:185:0;;;;92388:219;92448:23;:44;;;92507:23;:34;;;92556:23;:40;;;92388:45;:219::i;:::-;92698:50;92712:23;92737:10;92698:13;:50::i;:::-;92824:12;;92921:37;;;;92973:43;;;;92824:203;;;;;-1:-1:-1;;;;;92824:12:0;;;;:32;;:203;;92871:10;;;;92921:37;92973:43;92824:203;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;92824:203:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92824:203:0;;;;93112:69;93146:23;:34;;;93112:33;:69::i;:::-;93231:34;;93305:32;;;;93352:37;;;;93404:43;;;;93199:259;;93280:10;;93199:259;;;;93231:34;;93305:32;;93199:259;;;;;;;;;;1309:13;;1293:12;:29;1285:38;;;;;;91494:1972;;;:::o;89621:1483::-;1197:13;:18;;1214:1;1197:18;;;;;89882:55;89913:23;89882:30;:55::i;:::-;90078:34;;90127:37;;;;90020:155;;;;;:15;;:43;;:155;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;90020:155:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;90020:155:0;;;;90254:210;90305:23;:44;;;90364:23;:34;;;90413:23;:40;;;90254:36;:210::i;:::-;90546:50;90560:23;90585:10;90546:13;:50::i;:::-;90645:12;;90734:34;;90783:32;;;;90645:181;;;;;-1:-1:-1;;;;;90645:12:0;;;;:24;;:181;;90684:10;;;;90734:34;90783:32;90645:181;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;90645:181:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;90875:34:0;;90949:32;;;;90996:34;;;;91045:40;;;;90844:252;;90924:10;;-1:-1:-1;90844:252:0;;-1:-1:-1;90844:252:0;;90875:34;90949:32;90996:34;91045:40;90844:252;;76288:27;;;-1:-1:-1;;;;;76288:27:0;;:::o;76219:25::-;;;-1:-1:-1;;;;;76219:25:0;;:::o;76094:19::-;;;-1:-1:-1;;;;;76094:19:0;;:::o;76156:20::-;;;-1:-1:-1;;;;;76156:20:0;;:::o;82592:1157::-;82855:12;;82878:34;;82855:58;;;;;-1:-1:-1;;;;;82855:12:0;;;;:22;;:58;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82855:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82855:58:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;82855:58:0;;;;;;;;;82833:194;;;;-1:-1:-1;;;;;82833:194:0;;;;;;;;;;;;;;;;;83083:147;83138:23;:34;;;83187:23;:32;;;83083:40;:147::i;:::-;83342:4;;83361:44;;;;83420:34;;;;83469:40;;;;83280:240;;-1:-1:-1;;;;;83342:4:0;;83361:44;83420:34;83280:47;:240::i;:::-;83575:166;83635:23;:37;;;83687:23;:43;;;83575:45;:166::i;:::-;82592:1157;:::o;96414:777::-;96645:9;96640:544;96664:11;:18;96660:1;:22;96640:544;;;96816:12;;96841:24;;96790:23;;-1:-1:-1;;;;;96816:12:0;;:24;;96841:21;;96863:1;;96841:24;;;;;;;;;;;;96816:50;;;;;-1:-1:-1;;;96816:50:0;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;96816:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;96816:50:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;96816:50:0;;;;;;;;;96992:12;;97104:14;;96790:76;;-1:-1:-1;;;;;;96992:12:0;;:27;;97046:4;;96790:76;;97104:11;;97116:1;;97104:14;;;;;;;;;;;;97137:17;97155:1;97137:20;;;;;;;;;;;;;;96992:180;;;;;-1:-1:-1;;;96992:180:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;96992:180:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;96684:3:0;;;;;-1:-1:-1;96640:544:0;;-1:-1:-1;;96640:544:0;;;96414:777;;;:::o;93869:778::-;94139:33;94175:78;94219:23;94175:29;:78::i;:::-;94139:114;;94302:33;94324:10;94302:21;:33::i;:::-;94515:5;;94535:37;;;;94436:203;;-1:-1:-1;;;;;94515:5:0;;94587:16;94618:10;94436:64;:203::i;97406:837::-;97519:34;97566:11;-1:-1:-1;;;;;97556:36:0;;:38;;;;;-1:-1:-1;;;97556:38:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;97556:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;97556:38:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;97556:38:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;97556:38:0;;;;;;;;;97519:75;;97605:42;97664:17;:24;97650:39;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;97650:39:0;-1:-1:-1;97605:84:0;-1:-1:-1;97705:9:0;97700:297;97724:17;:24;97720:1;:28;97700:297;;;97797:13;;97827:20;;97770:24;;-1:-1:-1;;;;;97797:13:0;;:29;;97827:17;;97845:1;;97827:20;;;;;;;;;;;;97857:4;97797:66;;;;;-1:-1:-1;;;97797:66:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;97797:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;97797:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;97797:66:0;;;;;;;;;97770:93;-1:-1:-1;97882:20:0;;97878:108;;97954:16;97923:25;97949:1;97923:28;;;;;;;;;;;;;:47;;;;;97878:108;-1:-1:-1;97750:3:0;;97700:297;;;-1:-1:-1;98067:12:0;;:168;;;;;-1:-1:-1;;;;;98067:12:0;;;;:32;;:168;;98122:4;;98142:10;;98167:17;;98199:25;;98067:168;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;98067:168:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;98067:168:0;;;;97406:837;;;:::o;95165:728::-;95387:9;95382:504;95406:11;:18;95402:1;:22;95382:504;;;95557:12;;95582:24;;95531:23;;-1:-1:-1;;;;;95557:12:0;;:24;;95582:21;;95604:1;;95582:24;;;;;;;;;;;;95557:50;;;;;-1:-1:-1;;;95557:50:0;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;95557:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;95557:50:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;95557:50:0;;;;;;;;;95697:12;;95743:14;;95531:76;;-1:-1:-1;;;;;;95697:12:0;;:27;;95743:11;;95755:1;;95743:14;;;;;;;;;;;;95776:17;95794:1;95776:20;;;;;;;;;;;;;;95815:10;95844:15;95697:177;;;;;-1:-1:-1;;;95697:177:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;95697:177:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;95426:3:0;;;;;-1:-1:-1;95382:504:0;;-1:-1:-1;;95382:504:0;52353:596;52577:1;52565:9;:13;52543:130;;;;-1:-1:-1;;;;;52543:130:0;;;;;;;;;52781:44;52805:4;-1:-1:-1;;;;;52795:27:0;;:29;;;;;-1:-1:-1;;;52795:29:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52795:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52795:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52795:29:0;;;;;;;;;52781:9;;:44;:13;:44;:::i;:::-;:49;52759:182;;;;-1:-1:-1;;;;;52759:182:0;;;;;;;;;52353:596;;:::o;56477:1294::-;56763:1;56742:11;:18;:22;56720:156;;;;-1:-1:-1;;;;;56720:156:0;;;;;;;;;56943:11;:18;56911:21;:28;:50;:113;;;;;57000:17;:24;56978:11;:18;:46;56911:113;56889:256;;;;-1:-1:-1;;;;;56889:256:0;;;;;;;;;57177:5;57158:10;57196:568;57220:21;:28;57216:1;:32;57196:568;;;57400:1;-1:-1:-1;;;;;57346:56:0;:4;-1:-1:-1;;;;;57346:16:0;;57363:21;57385:1;57363:24;;;;;;;;;;;;;;57346:42;;;;;-1:-1:-1;;;57346:42:0;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57346:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57346:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57346:42:0;;;;;;;;;-1:-1:-1;;;;;57346:56:0;;;57320:189;;;;-1:-1:-1;;;;;57320:189:0;;;;;;;;;57637:1;57614:17;57632:1;57614:20;;;;;;;;;;;;;;:24;57588:164;;;;-1:-1:-1;;;;;57588:164:0;;;;;;;;;57250:3;;57196:568;;;;56477:1294;;;;;:::o;53313:1318::-;53518:21;;53635:22;53613:151;;;;-1:-1:-1;;;;;53613:151:0;;;;;;;;;53856:29;:14;:27;:29::i;:::-;53855:30;53833:166;;;;-1:-1:-1;;;;;53833:166:0;;;;;;;;;54146:20;:27;54124:18;:49;54102:193;;;;-1:-1:-1;;;;;54102:193:0;;;;;;;;;54313:9;54308:316;54332:18;54328:1;:22;54308:316;;;54494:1;54468:20;54489:1;54468:23;;;;;;;;;;;;;;:27;54442:170;;;;-1:-1:-1;;;;;54442:170:0;;;;;;;;;54352:3;;54308:316;;81391:1030;81575:16;81665:33;81715:23;:37;;;:44;81701:59;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;81701:59:0;-1:-1:-1;81665:95:0;-1:-1:-1;81776:9:0;81771:607;81795:23;:37;;;:44;81791:1;:48;81771:607;;;81938:13;;81986:37;;;;:40;;81915:20;;-1:-1:-1;;;;;81938:13:0;;:29;;82024:1;;81986:40;;;;;;;;;;;;82045:10;81938:132;;;;;-1:-1:-1;;;81938:132:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;81938:132:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81938:132:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;81938:132:0;;;;;;;;;81915:155;;82149:24;82176:23;:43;;;82220:1;82176:46;;;;;;;;;;;;;;82149:73;;82332:34;82349:16;82332:12;:16;;:34;;;;:::i;:::-;82310:16;82327:1;82310:19;;;;;;;;;;;;;;;;;:56;-1:-1:-1;;81841:3:0;;81771:607;;;-1:-1:-1;82397:16:0;-1:-1:-1;81391:1030:0;;;;:::o;78397:2677::-;78621:23;;78696:2371;78718:10;:17;78703:12;:32;78696:2371;;;78812:50;;:::i;:::-;78865:116;78925:10;78954:12;78865:41;:116::i;:::-;79110:12;;79135:15;;79110:41;;;;;78812:169;;-1:-1:-1;79084:23:0;;-1:-1:-1;;;;;79110:12:0;;;;:24;;:41;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;79110:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;79110:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;79110:41:0;;;;;;;;;79084:67;-1:-1:-1;;;;;;79248:29:0;;79222:168;;;;-1:-1:-1;;;;;79222:168:0;;;;;;;;;79467:24;79494:40;79515:1;79518:6;:15;;;79494:40;;:20;:40::i;:::-;79467:67;-1:-1:-1;79576:34:0;;;79575:41;79549:167;;;;-1:-1:-1;;;;;79549:167:0;;;;;;;;;79784:26;79813:111;79863:46;:44;:46::i;:::-;79813:27;;;;;:111;:31;:111;:::i;:::-;79784:140;;80049:21;80073:147;80127:10;80156:12;80187:18;80073:35;:147::i;:::-;80049:171;;80315:57;;:::i;:::-;-1:-1:-1;80375:139:0;;;;;;;;;80440:10;80375:139;;;80481:17;;;;80375:139;;;;;;-1:-1:-1;80656:4:0;80602:165;;-1:-1:-1;;;;;80656:4:0;80375:139;80710:15;80744:8;80602:35;:165::i;:::-;80865:36;:12;80882:18;80865:36;:16;:36;:::i;:::-;80850:51;-1:-1:-1;81018:37:0;:15;81038:16;81018:37;:19;:37;:::i;:::-;81000:55;;78696:2371;;;;;;;;55061:833;55362:6;55340:12;55470:417;55494:14;:21;55490:1;:25;55470:417;;;55537:18;55558:5;-1:-1:-1;;;;;55558:21:0;;55598:14;55613:1;55598:17;;;;;;;;;;;;;;55634:12;55558:103;;;;;-1:-1:-1;;;55558:103:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55558:103:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55558:103:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;55558:103:0;;;;;;;;;55537:124;;55718:17;55736:1;55718:20;;;;;;;;;;;;;;55704:10;:34;;55678:197;;;;-1:-1:-1;;;;;55678:197:0;;;;;;;;;-1:-1:-1;55517:3:0;;55470:417;;3199:124;3257:7;3285:6;3277:15;;;;;;3314:1;3310;:5;;;;;;3303:12;;3199:124;;;;;:::o;26424:398::-;26489:4;26510:1;:8;26522:1;26510:13;26506:58;;;-1:-1:-1;26547:5:0;26540:12;;26506:58;26579:9;26574:218;26609:1;26598;:8;:12;26594:1;:16;26574:218;;;26653:1;26649:5;;26632:149;26660:1;:8;26656:1;:12;26632:149;;;26706:1;26708;26706:4;;;;;;;;;;;;;;-1:-1:-1;;;;;26698:12:0;:1;26700;26698:4;;;;;;;;;;;;;;-1:-1:-1;;;;;26698:12:0;;26694:72;;;26742:4;26735:11;;;;;;26694:72;26670:3;;26632:149;;;-1:-1:-1;26612:3:0;;26574:218;;;-1:-1:-1;26809:5:0;;26424:398;-1:-1:-1;;26424:398:0:o;2888:150::-;2946:7;2978:5;;;3002:6;;;;2994:15;;;;;;3029:1;2888:150;-1:-1:-1;;;2888:150:0:o;18636:625::-;18782:21;;:::i;:::-;18821:28;;:::i;:::-;18862:23;18888:40;18920:7;18888:27;:10;:25;:27::i;:::-;:31;:40;:31;:40;:::i;:::-;18989:22;;18965:47;;19100:2;19079:24;;;19073:31;19056:15;;;19049:56;19186:2;19165:24;;;19159:31;19142:15;;;19135:56;-1:-1:-1;18965:47:0;18636:625;-1:-1:-1;;;18636:625:0:o;5371:435::-;5489:7;5526:1;5522;:5;5514:14;;;;;;5558:1;5541:14;5570:203;5594:3;5590:1;:7;5570:203;;;5643:6;5740:21;5643:6;5759:1;5740:21;:18;:21;:::i;:::-;5731:30;-1:-1:-1;;5599:3:0;;5570:203;;;-1:-1:-1;5792:6:0;5371:435;-1:-1:-1;;;5371:435:0:o;18130:135::-;18254:2;18130:135;:::o;19717:435::-;19901:12;19931:21;19955:161;19984:10;20009:43;20027:24;:22;:24::i;:::-;20009:13;;:43;:17;:43;:::i;:::-;20067:38;:13;20085:19;20067:38;:17;:38;:::i;:::-;19955:14;:161::i;:::-;19931:185;19717:435;-1:-1:-1;;;;;19717:435:0:o;72261:708::-;72511:63;;:::i;:::-;72577:106;;;;;-1:-1:-1;;;;;72577:43:0;;;;;:106;;72635:13;;72663:9;;72577:106;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72577:106:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72577:106:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;72577:106:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;72577:106:0;;;;;;;;;72836:20;;72871:29;;72915:35;;;;72759:202;;;;;72511:172;;-1:-1:-1;;;;;;72759:31:0;;;;;:202;;72805:16;;72836:20;;72871:29;;72915:35;72759:202;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72759:202:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72759:202:0;;;;72261:708;;;;;:::o;9648:237::-;9833:2;9822:14;;9648:237::o;1641:433::-;1699:7;1943:6;1939:47;;-1:-1:-1;1973:1:0;1966:8;;1939:47;2010:5;;;2014:1;2010;:5;:1;2034:5;;;;;:10;2026:19;;;;;16286:695;16393:19;16460:2;16452:4;:10;;16430:86;;;;-1:-1:-1;;;;;16430:86:0;;;;;;;;;16659:1;:8;16653:2;:14;;16527:196;;;;-1:-1:-1;;;;;16527:196:0;;;;;;;;;16819:4;16814:2;:9;16804:20;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;16804:20:0;87:34:-1;135:17;;-1:-1;16804:20:0;;16795:29;;16835:114;16857:23;:6;:21;:23::i;:::-;16916:4;16895:18;:1;:16;:18::i;:::-;:25;16935:6;:13;11863:2;11854:6;:11;11850:4114;;;12157:1;12147:6;12143:2;12139:15;12134:3;12130:25;12126:33;12209:4;12205:9;12196:6;12190:13;12186:29;12259:4;12252;12246:11;12242:22;12301:1;12298;12295:8;12289:4;12282:22;12095:224;;;;;;12426:4;12416:6;:14;12412:61;;;12451:7;;12412:61;13179:4;13170:6;:13;13166:2787;;;13511:2;13503:6;13499:15;13489:25;;13560:6;13552;13548:19;13611:6;13605:4;13601:17;13924:4;13918:11;14132:202;14150:4;14142:6;14139:16;14132:202;;;14199:13;;14186:27;;14261:2;14298:13;;;;14249:15;;;;14132:202;;;14406:18;;-1:-1:-1;13213:1230:0;;;14693:2;14685:6;14681:15;14671:25;;14742:6;14734;14730:19;14793:6;14787:4;14783:17;15109:6;15103:13;15632:195;15649:4;15643;15639:15;15632:195;;;15698:11;;15685:25;;-1:-1:-1;;15744:13:0;;;;15791;;;;15632:195;;;15900:19;;-1:-1:-1;;11705:4266:0;;;:::o;88211:10035::-;;;;;;;;;-1:-1:-1;88211:10035:0;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;88211:10035:0;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;130:122;;208:39;239:6;233:13;208:39;;277:699;;390:3;383:4;375:6;371:17;367:27;357:2;;408:1;405;398:12;357:2;445:6;432:20;467:76;482:60;535:6;482:60;;;467:76;;;458:85;;560:5;585:6;578:5;571:21;615:4;607:6;603:17;593:27;;637:4;632:3;628:14;621:21;;690:6;737:3;729:4;721:6;717:17;712:3;708:27;705:36;702:2;;;754:1;751;744:12;702:2;779:1;764:206;789:6;786:1;783:13;764:206;;;847:3;869:37;902:3;890:10;869:37;;;857:50;;-1:-1;930:4;921:14;;;;949;;;;;811:1;804:9;764:206;;;768:14;350:626;;;;;;;;1002:714;;1126:3;1119:4;1111:6;1107:17;1103:27;1093:2;;1144:1;1141;1134:12;1093:2;1174:6;1168:13;1196:76;1211:60;1264:6;1211:60;;1196:76;1187:85;;1289:5;1314:6;1307:5;1300:21;1344:4;1336:6;1332:17;1322:27;;1366:4;1361:3;1357:14;1350:21;;1419:6;1466:3;1458:4;1450:6;1446:17;1441:3;1437:27;1434:36;1431:2;;;1483:1;1480;1473:12;1431:2;1508:1;1493:217;1518:6;1515:1;1512:13;1493:217;;;1576:3;1598:48;1642:3;1630:10;1598:48;;;1586:61;;-1:-1;1670:4;1661:14;;;;1689;;;;;1540:1;1533:9;1493:217;;1742:722;;1870:3;1863:4;1855:6;1851:17;1847:27;1837:2;;1888:1;1885;1878:12;1837:2;1918:6;1912:13;1940:80;1955:64;2012:6;1955:64;;1940:80;1931:89;;2037:5;2062:6;2055:5;2048:21;2092:4;2084:6;2080:17;2070:27;;2114:4;2109:3;2105:14;2098:21;;2167:6;2214:3;2206:4;2198:6;2194:17;2189:3;2185:27;2182:36;2179:2;;;2231:1;2228;2221:12;2179:2;2256:1;2241:217;2266:6;2263:1;2260:13;2241:217;;;2324:3;2346:48;2390:3;2378:10;2346:48;;;2334:61;;-1:-1;2418:4;2409:14;;;;2437;;;;;2288:1;2281:9;2241:217;;2490:699;;2603:3;2596:4;2588:6;2584:17;2580:27;2570:2;;2621:1;2618;2611:12;2570:2;2658:6;2645:20;2680:76;2695:60;2748:6;2695:60;;2680:76;2671:85;;2773:5;2798:6;2791:5;2784:21;2828:4;2820:6;2816:17;2806:27;;2850:4;2845:3;2841:14;2834:21;;2903:6;2950:3;2942:4;2934:6;2930:17;2925:3;2921:27;2918:36;2915:2;;;2967:1;2964;2957:12;2915:2;2992:1;2977:206;3002:6;2999:1;2996:13;2977:206;;;3060:3;3082:37;3115:3;3103:10;3082:37;;;3070:50;;-1:-1;3143:4;3134:14;;;;3162;;;;;3024:1;3017:9;2977:206;;3215:714;;3339:3;3332:4;3324:6;3320:17;3316:27;3306:2;;3357:1;3354;3347:12;3306:2;3387:6;3381:13;3409:76;3424:60;3477:6;3424:60;;3409:76;3400:85;;3502:5;3527:6;3520:5;3513:21;3557:4;3549:6;3545:17;3535:27;;3579:4;3574:3;3570:14;3563:21;;3632:6;3679:3;3671:4;3663:6;3659:17;3654:3;3650:27;3647:36;3644:2;;;3696:1;3693;3686:12;3644:2;3721:1;3706:217;3731:6;3728:1;3725:13;3706:217;;;3789:3;3811:48;3855:3;3843:10;3811:48;;;3799:61;;-1:-1;3883:4;3874:14;;;;3902;;;;;3753:1;3746:9;3706:217;;3953:693;;4064:3;4057:4;4049:6;4045:17;4041:27;4031:2;;4082:1;4079;4072:12;4031:2;4119:6;4106:20;4141:74;4156:58;4207:6;4156:58;;4141:74;4132:83;;4232:5;4257:6;4250:5;4243:21;4287:4;4279:6;4275:17;4265:27;;4309:4;4304:3;4300:14;4293:21;;4362:6;4409:3;4401:4;4393:6;4389:17;4384:3;4380:27;4377:36;4374:2;;;4426:1;4423;4416:12;4374:2;4451:1;4436:204;4461:6;4458:1;4455:13;4436:204;;;4519:3;4541:35;4572:3;4560:10;4541:35;;;4529:48;;-1:-1;4600:4;4591:14;;;;4619;;;;;4483:1;4476:9;4436:204;;4654:116;;4729:36;4757:6;4751:13;4729:36;;4778:440;;4879:3;4872:4;4864:6;4860:17;4856:27;4846:2;;4897:1;4894;4887:12;4846:2;4934:6;4921:20;4956:64;4971:48;5012:6;4971:48;;4956:64;4947:73;;5040:6;5033:5;5026:21;5076:4;5068:6;5064:17;5109:4;5102:5;5098:16;5144:3;5135:6;5130:3;5126:16;5123:25;5120:2;;;5161:1;5158;5151:12;5120:2;5171:41;5205:6;5200:3;5195;5171:41;;;4839:379;;;;;;;;5286:1805;;5415:4;5403:9;5398:3;5394:19;5390:30;5387:2;;;5433:1;5430;5423:12;5387:2;5451:20;5466:4;5451:20;;;5442:29;-1:-1;5527:1;5558:49;5603:3;5583:9;5558:49;;;5534:74;;-1:-1;5673:2;5706:49;5751:3;5727:22;;;5706:49;;;5699:4;5692:5;5688:16;5681:75;5629:138;5861:2;5850:9;5846:18;5833:32;5885:18;5877:6;5874:30;5871:2;;;5917:1;5914;5907:12;5871:2;5952:68;6016:3;6007:6;5996:9;5992:22;5952:68;;;5945:4;5938:5;5934:16;5927:94;5777:255;6116:2;6105:9;6101:18;6088:32;6140:18;6132:6;6129:30;6126:2;;;6172:1;6169;6162:12;6126:2;6207:70;6273:3;6264:6;6253:9;6249:22;6207:70;;;6200:4;6193:5;6189:16;6182:96;6042:247;6379:3;6368:9;6364:19;6351:33;6404:18;6396:6;6393:30;6390:2;;;6436:1;6433;6426:12;6390:2;6471:70;6537:3;6528:6;6517:9;6513:22;6471:70;;;6464:4;6457:5;6453:16;6446:96;6299:254;6640:3;6629:9;6625:19;6612:33;6665:18;6657:6;6654:30;6651:2;;;6697:1;6694;6687:12;6651:2;6732:70;6798:3;6789:6;6778:9;6774:22;6732:70;;;6725:4;6718:5;6714:16;6707:96;6563:251;6907:3;6896:9;6892:19;6879:33;6932:18;6924:6;6921:30;6918:2;;;6964:1;6961;6954:12;6918:2;6999:70;7065:3;7056:6;7045:9;7041:22;6999:70;;;6992:4;6985:5;6981:16;6974:96;6824:257;5381:1710;;;;;7152:731;;7285:4;7273:9;7268:3;7264:19;7260:30;7257:2;;;7303:1;7300;7293:12;7257:2;7321:20;7336:4;7321:20;;;7400:24;;7312:29;;-1:-1;7444:18;7433:30;;7430:2;;;7476:1;7473;7466:12;7430:2;7510:81;7587:3;7578:6;7567:9;7563:22;7510:81;;;7486:106;;-1:-1;7689:2;7674:18;;7668:25;7713:18;7702:30;;7699:2;;;7745:1;7742;7735:12;7699:2;7780:81;7857:3;7848:6;7837:9;7833:22;7780:81;;;7773:4;7766:5;7762:16;7755:107;7613:260;7251:632;;;;;7890:118;;7957:46;7995:6;7982:20;7957:46;;8015:122;;8093:39;8124:6;8118:13;8093:39;;8144:114;;8209:44;8245:6;8232:20;8209:44;;8265:263;;8380:2;8368:9;8359:7;8355:23;8351:32;8348:2;;;8396:1;8393;8386:12;8348:2;8431:1;8448:64;8504:7;8484:9;8448:64;;;8438:74;8342:186;-1:-1;;;;8342:186;8535:392;;8675:2;8663:9;8654:7;8650:23;8646:32;8643:2;;;8691:1;8688;8681:12;8643:2;8726:24;;8770:18;8759:30;;8756:2;;;8802:1;8799;8792:12;8756:2;8822:89;8903:7;8894:6;8883:9;8879:22;8822:89;;8934:257;;9046:2;9034:9;9025:7;9021:23;9017:32;9014:2;;;9062:1;9059;9052:12;9014:2;9097:1;9114:61;9167:7;9147:9;9114:61;;9198:636;;;9368:2;9356:9;9347:7;9343:23;9339:32;9336:2;;;9384:1;9381;9374:12;9336:2;9419:31;;9470:18;9459:30;;9456:2;;;9502:1;9499;9492:12;9456:2;9522:93;9607:7;9598:6;9587:9;9583:22;9522:93;;;9512:103;;9398:223;9680:2;9669:9;9665:18;9652:32;9704:18;9696:6;9693:30;9690:2;;;9736:1;9733;9726:12;9690:2;9756:62;9810:7;9801:6;9790:9;9786:22;9756:62;;;9746:72;;9631:193;9330:504;;;;;;9841:408;;9989:2;9977:9;9968:7;9964:23;9960:32;9957:2;;;10005:1;10002;9995:12;9957:2;10040:24;;10084:18;10073:30;;10070:2;;;10116:1;10113;10106:12;10070:2;10136:97;10225:7;10216:6;10205:9;10201:22;10136:97;;10256:263;;10371:2;10359:9;10350:7;10346:23;10342:32;10339:2;;;10387:1;10384;10377:12;10339:2;10422:1;10439:64;10495:7;10475:9;10439:64;;10527:173;;10614:46;10656:3;10648:6;10614:46;;;-1:-1;;10689:4;10680:14;;10607:93;10907:173;;10994:46;11036:3;11028:6;10994:46;;11088:142;11179:45;11218:5;11179:45;;;11174:3;11167:58;11161:69;;;11237:110;11310:31;11335:5;11310:31;;11772:621;;11917:54;11965:5;11917:54;;;11984:86;12063:6;12058:3;11984:86;;;11977:93;;12090:56;12140:5;12090:56;;;12167:1;12152:219;12177:6;12174:1;12171:13;12152:219;;;12224:63;12283:3;12274:6;12268:13;12224:63;;;12217:70;;12304:60;12357:6;12304:60;;;12294:70;-1:-1;12199:1;12192:9;12152:219;;;-1:-1;12384:3;;11896:497;-1:-1;;;;11896:497;12432:605;;12573:50;12617:5;12573:50;;;12636:86;12715:6;12710:3;12636:86;;;12629:93;;12742:52;12788:5;12742:52;;;12815:1;12800:215;12825:6;12822:1;12819:13;12800:215;;;12872:63;12931:3;12922:6;12916:13;12872:63;;;12865:70;;12952:56;13001:6;12952:56;;;12942:66;-1:-1;12847:1;12840:9;12800:215;;13076:629;;13225:50;13269:5;13225:50;;;13288:94;13375:6;13370:3;13288:94;;;13281:101;;13402:52;13448:5;13402:52;;;13475:1;13460:223;13485:6;13482:1;13479:13;13460:223;;;13532:71;13599:3;13590:6;13584:13;13532:71;;;13525:78;;13620:56;13669:6;13620:56;;;13610:66;-1:-1;13507:1;13500:9;13460:223;;13744:621;;13889:54;13937:5;13889:54;;;13956:86;14035:6;14030:3;13956:86;;;13949:93;;14062:56;14112:5;14062:56;;;14139:1;14124:219;14149:6;14146:1;14143:13;14124:219;;;14196:63;14255:3;14246:6;14240:13;14196:63;;;14189:70;;14276:60;14329:6;14276:60;;;14266:70;-1:-1;14171:1;14164:9;14124:219;;14404:605;;14545:50;14589:5;14545:50;;;14608:86;14687:6;14682:3;14608:86;;;14601:93;;14714:52;14760:5;14714:52;;;14787:1;14772:215;14797:6;14794:1;14791:13;14772:215;;;14844:63;14903:3;14894:6;14888:13;14844:63;;;14837:70;;14924:56;14973:6;14924:56;;;14914:66;-1:-1;14819:1;14812:9;14772:215;;15017:343;;15127:38;15159:5;15127:38;;;15177:70;15240:6;15235:3;15177:70;;;15170:77;;15252:52;15297:6;15292:3;15285:4;15278:5;15274:16;15252:52;;;15325:29;15347:6;15325:29;;;15316:39;;;;15107:253;-1:-1;;;15107:253;15367:154;15464:51;15509:5;15464:51;;15692:566;;15852:67;15916:2;15911:3;15852:67;;;15952:66;15932:87;;16053:66;16048:2;16039:12;;16032:88;16154:66;16149:2;16140:12;;16133:88;16249:2;16240:12;;15838:420;-1:-1;;15838:420;16267:669;;16427:68;16491:3;16486;16427:68;;;-1:-1;;;;;;;;;;;16508:87;;16629:66;16624:2;16615:12;;16608:88;16730:66;16725:2;16716:12;;16709:88;16831:66;16826:2;16817:12;;16810:88;16926:3;16917:13;;16413:523;-1:-1;;16413:523;16945:364;;17105:67;17169:2;17164:3;17105:67;;;17205:66;17185:87;;17300:2;17291:12;;17091:218;-1:-1;;17091:218;17318:364;;17478:67;17542:2;17537:3;17478:67;;;17578:66;17558:87;;17673:2;17664:12;;17464:218;-1:-1;;17464:218;17691:566;;17851:67;17915:2;17910:3;17851:67;;;-1:-1;;;;;;;;;;;17931:87;;18052:66;18047:2;18038:12;;18031:88;18153:66;18148:2;18139:12;;18132:88;18248:2;18239:12;;17837:420;-1:-1;;17837:420;18266:566;;18426:67;18490:2;18485:3;18426:67;;;-1:-1;;;;;;;;;;;18506:87;;18627:66;18622:2;18613:12;;18606:88;18728:66;18723:2;18714:12;;18707:88;18823:2;18814:12;;18412:420;-1:-1;;18412:420;18841:566;;19001:67;19065:2;19060:3;19001:67;;;-1:-1;;;;;;;;;;;19081:87;;19202:66;19197:2;19188:12;;19181:88;19303:66;19298:2;19289:12;;19282:88;19398:2;19389:12;;18987:420;-1:-1;;18987:420;19416:566;;19576:67;19640:2;19635:3;19576:67;;;-1:-1;;;;;;;;;;;19656:87;;19777:66;19772:2;19763:12;;19756:88;19878:66;19873:2;19864:12;;19857:88;19973:2;19964:12;;19562:420;-1:-1;;19562:420;19991:566;;20151:67;20215:2;20210:3;20151:67;;;-1:-1;;;;;;;;;;;20231:87;;20352:66;20347:2;20338:12;;20331:88;20453:66;20448:2;20439:12;;20432:88;20548:2;20539:12;;20137:420;-1:-1;;20137:420;20566:566;;20726:67;20790:2;20785:3;20726:67;;;20826:66;20806:87;;20927:66;20922:2;20913:12;;20906:88;21028:66;21023:2;21014:12;;21007:88;21123:2;21114:12;;20712:420;-1:-1;;20712:420;21141:566;;21301:67;21365:2;21360:3;21301:67;;;-1:-1;;;;;;;;;;;21381:87;;21502:66;21497:2;21488:12;;21481:88;21603:66;21598:2;21589:12;;21582:88;21698:2;21689:12;;21287:420;-1:-1;;21287:420;21716:566;;21876:67;21940:2;21935:3;21876:67;;;-1:-1;;;;;;;;;;;21956:87;;22077:66;22072:2;22063:12;;22056:88;22178:66;22173:2;22164:12;;22157:88;22273:2;22264:12;;21862:420;-1:-1;;21862:420;22291:566;;22451:67;22515:2;22510:3;22451:67;;;-1:-1;;;;;;;;;;;22531:87;;22652:66;22647:2;22638:12;;22631:88;22753:66;22748:2;22739:12;;22732:88;22848:2;22839:12;;22437:420;-1:-1;;22437:420;22866:566;;23026:67;23090:2;23085:3;23026:67;;;-1:-1;;;;;;;;;;;23106:87;;23227:66;23222:2;23213:12;;23206:88;23328:66;23323:2;23314:12;;23307:88;23423:2;23414:12;;23012:420;-1:-1;;23012:420;23441:566;;23601:67;23665:2;23660:3;23601:67;;;-1:-1;;;;;;;;;;;23681:87;;23802:66;23797:2;23788:12;;23781:88;23903:66;23898:2;23889:12;;23882:88;23998:2;23989:12;;23587:420;-1:-1;;23587:420;24016:465;;24176:67;24240:2;24235:3;24176:67;;;24276:66;24256:87;;24377:66;24372:2;24363:12;;24356:88;24472:2;24463:12;;24162:319;-1:-1;;24162:319;24588:488;24808:22;;24741:4;24732:14;;;24836:61;24736:3;24808:22;24836:61;;;24761:142;24981:4;24974:5;24970:16;24964:23;24993:62;25049:4;25044:3;25040:14;25027:11;25083:110;25156:31;25181:5;25156:31;;25327:114;25406:29;25429:5;25406:29;;25448:213;25566:2;25551:18;;25580:71;25555:9;25624:6;25580:71;;25668:579;25886:3;25871:19;;25901:79;25875:9;25953:6;25901:79;;;25991:80;26067:2;26056:9;26052:18;26043:6;25991:80;;;26082:72;26150:2;26139:9;26135:18;26126:6;26082:72;;;26165;26233:2;26222:9;26218:18;26209:6;26165:72;;26254:859;26564:3;26549:19;;26579:79;26553:9;26631:6;26579:79;;;26669:80;26745:2;26734:9;26730:18;26721:6;26669:80;;;26797:9;26791:4;26787:20;26782:2;26771:9;26767:18;26760:48;26822:104;26921:4;26912:6;26822:104;;;26814:112;;26974:9;26968:4;26964:20;26959:2;26948:9;26944:18;26937:48;26999:104;27098:4;27089:6;26999:104;;;26991:112;26535:578;-1:-1;;;;;;26535:578;27120:563;27330:3;27315:19;;27345:79;27319:9;27397:6;27345:79;;;27435:72;27503:2;27492:9;27488:18;27479:6;27435:72;;27690:324;27836:2;27821:18;;27850:71;27825:9;27894:6;27850:71;;;27932:72;28000:2;27989:9;27985:18;27976:6;27932:72;;28021:340;28175:2;28160:18;;28189:71;28164:9;28233:6;28189:71;;;28271:80;28347:2;28336:9;28332:18;28323:6;28271:80;;28368:859;28678:3;28663:19;;28693:71;28667:9;28737:6;28693:71;;;28775:80;28851:2;28840:9;28836:18;28827:6;28775:80;;;28903:9;28897:4;28893:20;28888:2;28877:9;28873:18;28866:48;28928:108;29031:4;29022:6;28928:108;;;28920:116;;29084:9;29078:4;29074:20;29069:2;29058:9;29054:18;29047:48;29109:108;29212:4;29203:6;29109:108;;29234:547;29436:3;29421:19;;29451:71;29425:9;29495:6;29451:71;;29788:827;30082:3;30067:19;;30097:71;30071:9;30141:6;30097:71;;;30179:72;30247:2;30236:9;30232:18;30223:6;30179:72;;30622:488;30822:2;30807:18;;30836:79;30811:9;30888:6;30836:79;;;30963:9;30957:4;30953:20;30948:2;30937:9;30933:18;30926:48;30988:112;31095:4;31086:6;30988:112;;31117:563;31327:3;31312:19;;31342:71;31316:9;31386:6;31342:71;;;31424:72;31492:2;31481:9;31477:18;31468:6;31424:72;;;31507:80;31583:2;31572:9;31568:18;31559:6;31507:80;;;31598:72;31666:2;31655:9;31651:18;31642:6;31598:72;;31687:827;31981:3;31966:19;;31996:71;31970:9;32040:6;31996:71;;;32078:72;32146:2;32135:9;32131:18;32122:6;32078:72;;32521:241;32653:2;32638:18;;32667:85;32642:9;32725:6;32667:85;;33019:407;33210:2;33224:47;;;33195:18;;33285:131;33195:18;33285:131;;33433:407;33624:2;33638:47;;;33609:18;;33699:131;33609:18;33699:131;;33847:407;34038:2;34052:47;;;34023:18;;34113:131;34023:18;34113:131;;34261:407;34452:2;34466:47;;;34437:18;;34527:131;34437:18;34527:131;;34675:407;34866:2;34880:47;;;34851:18;;34941:131;34851:18;34941:131;;35089:407;35280:2;35294:47;;;35265:18;;35355:131;35265:18;35355:131;;35503:407;35694:2;35708:47;;;35679:18;;35769:131;35679:18;35769:131;;35917:407;36108:2;36122:47;;;36093:18;;36183:131;36093:18;36183:131;;36331:407;36522:2;36536:47;;;36507:18;;36597:131;36507:18;36597:131;;36745:407;36936:2;36950:47;;;36921:18;;37011:131;36921:18;37011:131;;37159:407;37350:2;37364:47;;;37335:18;;37425:131;37335:18;37425:131;;37573:407;37764:2;37778:47;;;37749:18;;37839:131;37749:18;37839:131;;37987:407;38178:2;38192:47;;;38163:18;;38253:131;38163:18;38253:131;;38401:407;38592:2;38606:47;;;38577:18;;38667:131;38577:18;38667:131;;38815:407;39006:2;39020:47;;;38991:18;;39081:131;38991:18;39081:131;;39229:407;39420:2;39434:47;;;39405:18;;39495:131;39405:18;39495:131;;39643:528;39867:2;39852:18;;39881:131;39856:9;39985:6;39881:131;;;40060:9;40054:4;40050:20;40045:2;40034:9;40030:18;40023:48;40085:76;40156:4;40147:6;40085:76;;40178:205;40292:2;40277:18;;40306:67;40281:9;40346:6;40306:67;;40390:256;40452:2;40446:9;40478:17;;;40553:18;40538:34;;40574:22;;;40535:62;40532:2;;;40610:1;40607;40600:12;40532:2;40626;40619:22;40430:216;;-1:-1;40430:216;40653:254;;40808:18;40800:6;40797:30;40794:2;;;40840:1;40837;40830:12;40794:2;-1:-1;40869:4;40857:17;;;40887:15;;40731:176;41699:258;;41842:18;41834:6;41831:30;41828:2;;;41874:1;41871;41864:12;41828:2;-1:-1;41947:4;41918;41895:17;;;;-1:-1;;41891:33;41937:15;;41765:192;42484:103;42570:12;;42554:33;43547:178;43665:19;;;43714:4;43705:14;;43658:67;44458:105;;-1:-1;;;;;44639:54;;44527:31;44622:76;44705:79;44774:5;44757:27;44791:88;44869:4;44858:16;;44841:38;44998:92;45071:13;45064:21;;45047:43;45413:129;;45500:37;45531:5;45549:149;;45642:51;45687:5;45642:51;;46387:145;46468:6;46463:3;46458;46445:30;-1:-1;46524:1;46506:16;;46499:27;46438:94;46541:268;46606:1;46613:101;46627:6;46624:1;46621:13;46613:101;;;46694:11;;;46688:18;46675:11;;;46668:39;46649:2;46642:10;46613:101;;;46729:6;46726:1;46723:13;46720:2;;;-1:-1;;46794:1;46776:16;;46769:27;46590:219;46817:97;46905:2;46885:14;-1:-1;;46881:28;;46865:49
Swarm Source
bzzr://3be3bbc9bd418298498d2c846169e588e21fd0ba0c65c80f21a0c3d5adebf446
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.