Overview
Max Total Supply
56.145918286854 ETHRSI6040
Holders
364 (0.00%)
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.000010080679 ETHRSI6040Value
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract contains unverified libraries: FailAuctionLibrary, PlaceBidLibrary, ProposeLibrary, SettleRebalanceLibrary, StartRebalanceLibrary
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.
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xa360F2aF...eD08aE3DB The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
RebalancingSetToken
Compiler Version
v0.5.7+commit.6da8b019
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-08-29 */ // File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.2; pragma experimental "ABIEncoderV2"; /** * @title ERC20 interface * @dev see https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } // 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: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.2; /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://eips.ethereum.org/EIPS/eip-20 * Originally based on code by FirstBlood: * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for * all accounts just by listening to said events. Note that this isn't required by the specification, and other * compliant implementations may not do it. */ contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; uint256 private _totalSupply; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return A uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param owner address The address which owns the funds. * @param spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowed[owner][spender]; } /** * @dev Transfer token to a specified address * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another. * Note that while this function emits an Approval event, this is not required as per the specification, * and other compliant implementations may not emit the event. * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 the amount of tokens to be transferred */ function transferFrom(address from, address to, uint256 value) public returns (bool) { _transfer(from, to, value); _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); return true; } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { require(to != address(0)); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. * @param value The amount that will be created. */ function _mint(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burn(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Approve an address to spend another addresses' tokens. * @param owner The address that owns the tokens. * @param spender The address that will spend the tokens. * @param value The number of tokens that can be spent. */ function _approve(address owner, address spender, uint256 value) internal { require(spender != address(0)); require(owner != address(0)); _allowed[owner][spender] = value; emit Approval(owner, spender, value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. * Emits an Approval event (reflecting the reduced allowance). * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burnFrom(address account, uint256 value) internal { _burn(account, value); _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.2; /** * @title ERC20Detailed token * @dev The decimals are only for visualization purposes. * All the operations are done using the smallest and indivisible token unit, * just as on Ethereum all the operations are done in wei. */ contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /** * @return the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @return the symbol of the token. */ function symbol() public view returns (string memory) { return _symbol; } /** * @return the number of decimals of the token. */ function decimals() public view returns (uint8) { return _decimals; } } // 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; /** * Calculates and returns the maximum value for a uint256 * * @return The maximum value for uint256 */ function maxUInt256() internal pure returns (uint256) { return 2 ** 256 - 1; } /** * @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; } /** * 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); } } // 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/ISetFactory.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 ISetFactory * @author Set Protocol * * The ISetFactory interface provides operability for authorized contracts * to interact with SetTokenFactory */ interface ISetFactory { /* ============ External Functions ============ */ /** * Return core address * * @return address core address */ function core() external returns (address); /** * Deploys a new Set Token and adds it to the valid list of SetTokens * * @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[] calldata _components, uint[] calldata _units, uint256 _naturalUnit, bytes32 _name, bytes32 _symbol, bytes calldata _callData ) external returns (address); } // File: contracts/core/interfaces/IWhiteList.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 IWhiteList * @author Set Protocol * * The IWhiteList interface exposes the whitelist mapping to check components */ interface IWhiteList { /* ============ External Functions ============ */ /** * Validates address against white list * * @param _address Address to check * @return bool Whether passed in address is whitelisted */ function whiteList( address _address ) external view returns (bool); /** * Verifies an array of addresses against the whitelist * * @param _addresses Array of addresses to verify * @return bool Whether all addresses in the list are whitelsited */ function areValidAddresses( address[] calldata _addresses ) external view returns (bool); } // File: contracts/core/interfaces/IRebalancingSetFactory.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 IRebalancingSetFactory * @author Set Protocol * * The IRebalancingSetFactory interface provides operability for authorized contracts * to interact with RebalancingSetTokenFactory */ contract IRebalancingSetFactory is ISetFactory { /** * Getter for minimumRebalanceInterval of RebalancingSetTokenFactory, used * to enforce rebalanceInterval when creating a RebalancingSetToken * * @return uint256 Minimum amount of time between rebalances in seconds */ function minimumRebalanceInterval() external returns (uint256); /** * Getter for minimumProposalPeriod of RebalancingSetTokenFactory, used * to enforce proposalPeriod when creating a RebalancingSetToken * * @return uint256 Minimum amount of time users can review proposals in seconds */ function minimumProposalPeriod() external returns (uint256); /** * Getter for minimumTimeToPivot of RebalancingSetTokenFactory, used * to enforce auctionTimeToPivot when proposing a rebalance * * @return uint256 Minimum amount of time before auction pivot reached */ function minimumTimeToPivot() external returns (uint256); /** * Getter for maximumTimeToPivot of RebalancingSetTokenFactory, used * to enforce auctionTimeToPivot when proposing a rebalance * * @return uint256 Maximum amount of time before auction pivot reached */ function maximumTimeToPivot() external returns (uint256); /** * Getter for minimumNaturalUnit of RebalancingSetTokenFactory * * @return uint256 Minimum natural unit */ function minimumNaturalUnit() external returns (uint256); /** * Getter for maximumNaturalUnit of RebalancingSetTokenFactory * * @return uint256 Maximum Minimum natural unit */ function maximumNaturalUnit() external returns (uint256); /** * Getter for rebalanceAuctionModule address on RebalancingSetTokenFactory * * @return address Address of rebalanceAuctionModule */ function rebalanceAuctionModule() external returns (address); } // 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/lib/RebalancingLibrary.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 RebalancingLibrary * @author Set Protocol * * The RebalancingLibrary contains functions for facilitating the rebalancing process for * Rebalancing Set Tokens. Removes the old calculation functions * */ library RebalancingLibrary { /* ============ Enums ============ */ enum State { Default, Proposal, Rebalance, Drawdown } /* ============ Structs ============ */ struct AuctionPriceParameters { uint256 auctionStartTime; uint256 auctionTimeToPivot; uint256 auctionStartPrice; uint256 auctionPivotPrice; } struct BiddingParameters { uint256 minimumBid; uint256 remainingCurrentSets; uint256[] combinedCurrentUnits; uint256[] combinedNextSetUnits; address[] combinedTokenArray; } } // File: openzeppelin-solidity/contracts/math/Math.sol pragma solidity ^0.5.2; /** * @title Math * @dev Assorted math operations */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Calculates the average of two numbers. Since these are integers, * averages of an even and odd number cannot be represented, and will be * rounded down. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // File: contracts/core/tokens/rebalancing-libraries/FailAuctionLibrary.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 FailAuctionLibrary * @author Set Protocol * * Default implementation of Rebalancing Set Token endFailedAuction function */ library FailAuctionLibrary { using SafeMath for uint256; /** * Fail an auction that doesn't complete before reaching the pivot price. Move to Drawdown state * if bids have been placed. Reset to Default state if no bids placed. * * @param _startingCurrentSetAmount Amount of current set at beginning or rebalance * @param _calculatedUnitShares Calculated unitShares amount if rebalance were to be settled * @param _currentSet The Set that failed to rebalance * @param _coreAddress Core address * @param _auctionPriceParameters Struct containing auction price curve parameters * @param _biddingParameters Struct containing relevant data for calculating token flows * @param _rebalanceState State rebalancing set token is in * @return State of Rebalancing Set after function called */ function endFailedAuction( uint256 _startingCurrentSetAmount, uint256 _calculatedUnitShares, address _currentSet, address _coreAddress, RebalancingLibrary.AuctionPriceParameters memory _auctionPriceParameters, RebalancingLibrary.BiddingParameters memory _biddingParameters, uint8 _rebalanceState ) public returns (uint8) { // Token must be in Rebalance State require( _rebalanceState == uint8(RebalancingLibrary.State.Rebalance), "RebalanceAuctionModule.endFailedAuction: Rebalancing Set Token must be in Rebalance State" ); // Calculate timestamp when pivot is reached uint256 revertAuctionTime = _auctionPriceParameters.auctionStartTime.add( _auctionPriceParameters.auctionTimeToPivot ); // Make sure auction has gone past pivot point require( block.timestamp >= revertAuctionTime, "RebalanceAuctionModule.endFailedAuction: Can only be called after auction reaches pivot" ); uint8 newRebalanceState; /** * If not enough sets have been bid on then allow auction to fail where no bids being registered * returns the rebalancing set token to pre-auction state and some bids being registered puts the * rebalancing set token in Drawdown mode. * * However, if enough sets have been bid on. Then allow auction to fail and enter Drawdown state if * and only if the calculated post-auction unitShares is equal to 0. */ if (_biddingParameters.remainingCurrentSets >= _biddingParameters.minimumBid) { // Check if any bids have been placed if (_startingCurrentSetAmount == _biddingParameters.remainingCurrentSets) { // If bid not placed, reissue current Set ICore(_coreAddress).issueInVault( _currentSet, _startingCurrentSetAmount ); // Set Rebalance Set Token state to Default newRebalanceState = uint8(RebalancingLibrary.State.Default); } else { // Set Rebalancing Set Token to Drawdown state newRebalanceState = uint8(RebalancingLibrary.State.Drawdown); } } else { // If settleRebalance can be called then endFailedAuction can't be unless calculatedUnitShares // equals 0 require( _calculatedUnitShares == 0, "RebalancingSetToken.endFailedAuction: Cannot be called if rebalance is viably completed" ); // If calculated unitShares equals 0 set to Drawdown state newRebalanceState = uint8(RebalancingLibrary.State.Drawdown); } return newRebalanceState; } } // File: contracts/core/lib/auction-price-libraries/IAuctionPriceCurve.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 IAuctionPriceCurve * @author Set Protocol * * The IAuctionPriceCurve interface provides a structured way to interact with any AuctionLibrary */ interface IAuctionPriceCurve { /* * Getter for priceDivisor variable on Auction Price Curve Library */ function priceDivisor() external view returns (uint256); /* * Validate any auction parameters that have library-specific restrictions * * @param _auctionPriceParameters Struct containing relevant auction price parameters */ function validateAuctionPriceParameters( RebalancingLibrary.AuctionPriceParameters calldata _auctionPriceParameters ) external view; /* * Calculate the current priceRatio for an auction given defined price and time parameters * * @param _auctionPriceParameters Struct containing relevant auction price parameters * @return uint256 The auction price numerator * @return uint256 The auction price denominator */ function getCurrentPrice( RebalancingLibrary.AuctionPriceParameters calldata _auctionPriceParameters ) external view returns (uint256, uint256); } // File: contracts/core/tokens/rebalancing-libraries/PlaceBidLibrary.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 PlaceBidLibrary * @author Set Protocol * * Default implementation of Rebalancing Set Token placeBid function */ library PlaceBidLibrary { using SafeMath for uint256; /* ============ Internal Functions ============ */ /* * Place bid during rebalance auction. Can only be called by Core. * * @param _quantity The amount of currentSet to be rebalanced * @param _coreAddress Core address * @param _biddingParameters Struct containing relevant data for calculating token flows * @return inflowUnitArray Array of amount of tokens inserted into system in bid * @return outflowUnitArray Array of amount of tokens taken out of system in bid */ function validatePlaceBid( uint256 _quantity, address _coreAddress, RebalancingLibrary.BiddingParameters memory _biddingParameters ) public view returns (uint256) { // Make sure sender is a module require( ICore(_coreAddress).validModules(msg.sender), "RebalancingSetToken.placeBid: Sender must be approved module" ); // Make sure that bid amount is greater than zero require( _quantity > 0, "RebalancingSetToken.placeBid: Bid must be > 0" ); // Make sure that bid amount is multiple of minimum bid amount require( _quantity.mod(_biddingParameters.minimumBid) == 0, "RebalancingSetToken.placeBid: Must bid multiple of minimum bid" ); // Make sure that bid Amount is less than remainingCurrentSets require( _quantity <= _biddingParameters.remainingCurrentSets, "RebalancingSetToken.placeBid: Bid exceeds remaining current sets" ); } /* * Get token inflows and outflows required for bid. Also the amount of Rebalancing * Sets that would be generated. * * @param _quantity The amount of currentSet to be rebalanced * @param _auctionLibrary Auction library used in rebalance * @param _biddingParameters Struct containing relevant data for calculating token flows * @param _auctionPriceParameters Struct containing auction price curve parameters * @param _rebalanceState State of rebalancing set token * @return inflowUnitArray Array of amount of tokens inserted into system in bid * @return outflowUnitArray Array of amount of tokens taken out of system in bid */ function getBidPrice( uint256 _quantity, address _auctionLibrary, RebalancingLibrary.BiddingParameters memory _biddingParameters, RebalancingLibrary.AuctionPriceParameters memory _auctionPriceParameters, uint8 _rebalanceState ) public view returns (uint256[] memory, uint256[] memory) { // Confirm in Rebalance State require( _rebalanceState == uint8(RebalancingLibrary.State.Rebalance), "RebalancingSetToken.getBidPrice: State must be Rebalance" ); // Get bid conversion price, currently static placeholder for calling auctionlibrary uint256 priceNumerator; uint256 priceDivisor; (priceNumerator, priceDivisor) = IAuctionPriceCurve(_auctionLibrary).getCurrentPrice( _auctionPriceParameters ); // Normalized quantity amount uint256 unitsMultiplier = _quantity.div(_biddingParameters.minimumBid).mul(priceDivisor); // Calculate token flow arrays return createTokenFlowArrays( unitsMultiplier, priceNumerator, priceDivisor, _biddingParameters ); } /* * Creates arrays of token inflows and outflows * * @param _unitsMultiplier Bid amount normalized to number of standard bid amounts * @param _priceNumerator The numerator of the price ratio * @param _priceDivisor The denominator of the price ratio * @param _biddingParameters Struct containing relevant data for calculating token flows * @return inflowUnitArray Array of amount of tokens inserted into system in bid * @return outflowUnitArray Array of amount of tokens taken out of system in bid */ function createTokenFlowArrays( uint256 _unitsMultiplier, uint256 _priceNumerator, uint256 _priceDivisor, RebalancingLibrary.BiddingParameters memory _biddingParameters ) public pure returns (uint256[] memory, uint256[] memory) { // Declare unit arrays in memory uint256 combinedTokenCount = _biddingParameters.combinedTokenArray.length; uint256[] memory inflowUnitArray = new uint256[](combinedTokenCount); uint256[] memory outflowUnitArray = new uint256[](combinedTokenCount); // Cycle through each token in combinedTokenArray, calculate inflow/outflow and store // result in array for (uint256 i = 0; i < combinedTokenCount; i++) { ( inflowUnitArray[i], outflowUnitArray[i] ) = calculateTokenFlows( _biddingParameters.combinedCurrentUnits[i], _biddingParameters.combinedNextSetUnits[i], _unitsMultiplier, _priceNumerator, _priceDivisor ); } return (inflowUnitArray, outflowUnitArray); } /* * Calculates token inflow/outflow for single component in combinedTokenArray * * @param _currentUnit Amount of token i in currentSet per minimum bid amount * @param _nextSetUnit Amount of token i in nextSet per minimum bid amount * @param _unitsMultiplier Bid amount normalized to number of minimum bid amounts * @param _priceNumerator The numerator of the price ratio * @param _priceDivisor The denominator of the price ratio * @return inflowUnit Amount of token i transferred into the system * @return outflowUnit Amount of token i transferred to the bidder */ function calculateTokenFlows( uint256 _currentUnit, uint256 _nextSetUnit, uint256 _unitsMultiplier, uint256 _priceNumerator, uint256 _priceDivisor ) public pure returns (uint256, uint256) { /* * Below is a mathematically simplified formula for calculating token inflows and * outflows, the following is it's derivation: * token_flow = (bidQuantity/price)*(nextUnit - price*currentUnit) * * Where, * 1) price = (priceNumerator/priceDivisor), * 2) nextUnit and currentUnit are the amount of component i needed for a * standardAmount of sets to be rebalanced where one standardAmount = * max(natural unit nextSet, natural unit currentSet), and * 3) bidQuantity is a normalized amount in terms of the standardAmount used * to calculate nextUnit and currentUnit. This is represented by the unitsMultiplier * variable. * * Given these definitions we can derive the below formula as follows: * token_flow = (unitsMultiplier/(priceNumerator/priceDivisor))* * (nextUnit - (priceNumerator/priceDivisor)*currentUnit) * * We can then multiply this equation by (priceDivisor/priceDivisor) * which simplifies the above equation to: * * (unitsMultiplier/priceNumerator)* (nextUnit*priceDivisor - currentUnit*priceNumerator) * * This is the equation seen below, but since unsigned integers are used we must check to see if * nextUnit*priceDivisor > currentUnit*priceNumerator, otherwise those two terms must be * flipped in the equation. */ uint256 inflowUnit; uint256 outflowUnit; // Use if statement to check if token inflow or outflow if (_nextSetUnit.mul(_priceDivisor) > _currentUnit.mul(_priceNumerator)) { // Calculate inflow amount inflowUnit = _unitsMultiplier.mul( _nextSetUnit.mul(_priceDivisor).sub(_currentUnit.mul(_priceNumerator)) ).div(_priceNumerator); // Set outflow amount to 0 for component i, since tokens need to be injected in rebalance outflowUnit = 0; } else { // Calculate outflow amount outflowUnit = _unitsMultiplier.mul( _currentUnit.mul(_priceNumerator).sub(_nextSetUnit.mul(_priceDivisor)) ).div(_priceNumerator); // Set inflow amount to 0 for component i, since tokens need to be returned in rebalance inflowUnit = 0; } return (inflowUnit, outflowUnit); } } // File: contracts/core/tokens/rebalancing-libraries/ProposeLibrary.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 ProposeLibrary * @author Set Protocol * * Default implementation of Rebalancing Set Token propose function */ library ProposeLibrary { using SafeMath for uint256; /* ============ Structs ============ */ struct ProposalContext { address manager; address currentSet; address coreAddress; address componentWhitelist; address factoryAddress; uint256 lastRebalanceTimestamp; uint256 rebalanceInterval; uint8 rebalanceState; } /* ============ Internal Functions ============ */ /** * Function used to validate inputs to propose function * * @param _nextSet The Set to rebalance into * @param _auctionLibrary The library used to calculate the Dutch Auction price * @param _proposalContext Rebalancing Set Token state parameters needed for proposal validation */ function validateProposal( address _nextSet, address _auctionLibrary, ProposalContext memory _proposalContext, RebalancingLibrary.AuctionPriceParameters memory _auctionPriceParameters ) public { ICore coreInstance = ICore(_proposalContext.coreAddress); IRebalancingSetFactory factoryInstance = IRebalancingSetFactory(_proposalContext.factoryAddress); // Make sure it is manager that is proposing the rebalance require( msg.sender == _proposalContext.manager, "ProposeLibrary.validateProposal: Sender must be manager" ); // New Proposal can only be made in Default and Proposal state require( _proposalContext.rebalanceState == uint8(RebalancingLibrary.State.Default) || _proposalContext.rebalanceState == uint8(RebalancingLibrary.State.Proposal), "ProposeLibrary.validateProposal: State must be in Propose or Default" ); // Make sure enough time has passed from last rebalance to start a new proposal require( block.timestamp >= _proposalContext.lastRebalanceTimestamp.add( _proposalContext.rebalanceInterval ), "ProposeLibrary.validateProposal: Rebalance interval not elapsed" ); // Check that new proposed Set is valid Set created by Core require( coreInstance.validSets(_nextSet), "ProposeLibrary.validateProposal: Invalid or disabled proposed SetToken address" ); // Check proposed components on whitelist. This is to ensure managers are unable to add contract addresses // to a propose that prohibit the set from carrying out an auction i.e. a token that only the manager possesses require( IWhiteList( _proposalContext.componentWhitelist ).areValidAddresses(ISetToken(_nextSet).getComponents()), "ProposeLibrary.validateProposal: Proposed set contains invalid component token" ); // Check that the auction library is a valid priceLibrary tracked by Core require( coreInstance.validPriceLibraries(_auctionLibrary), "ProposeLibrary.validateProposal: Invalid or disabled PriceLibrary address" ); // Check that auctionTimeToPivot is greater than or equal to 6 hours require( _auctionPriceParameters.auctionTimeToPivot >= factoryInstance.minimumTimeToPivot(), "ProposeLibrary.validateProposal: Time to pivot must be greater than minimum" ); // Check that auctionTimeToPivot is less than or equal to 3 days require( _auctionPriceParameters.auctionTimeToPivot <= factoryInstance.maximumTimeToPivot(), "ProposeLibrary.validateProposal: Time to pivot must be greater than maximum" ); // Check that the proposed set natural unit is a multiple of current set natural unit, or vice versa. // Done to make sure that when calculating token units there will are no rounding errors. uint256 currentNaturalUnit = ISetToken(_proposalContext.currentSet).naturalUnit(); uint256 nextSetNaturalUnit = ISetToken(_nextSet).naturalUnit(); require( Math.max(currentNaturalUnit, nextSetNaturalUnit).mod( Math.min(currentNaturalUnit, nextSetNaturalUnit) ) == 0, "ProposeLibrary.validateProposal: Invalid proposed Set natural unit" ); // Check that pivot price is compliant with library restrictions IAuctionPriceCurve(_auctionLibrary).validateAuctionPriceParameters( _auctionPriceParameters ); } } // 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" ); } /** * 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/tokens/rebalancing-libraries/SettleRebalanceLibrary.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 SettleRebalanceLibrary * @author Set Protocol * * Default implementation of Rebalancing Set Token settle rebalance and related functions. */ library SettleRebalanceLibrary { using SafeMath for uint256; /* ============ Internal Functions ============ */ /** * Calculate the amount of nextSets to issue by using the component amounts in the * vault, new unitShares follow from this calculation * * @param _totalSupply Total supply of rebalancing set token * @param _remainingCurrentSets Amount of currentSets remaining * @param _minimumBid Minimum bid allowed, used to see if valid settle * @param _naturalUnit Natural unit of rebalancing set token * @param _nextSet Address of next set * @param _coreAddress Core address * @param _vaultAddress Vault address * @return uint256 Amount of nextSets to issue */ function settleRebalance( uint256 _totalSupply, uint256 _remainingCurrentSets, uint256 _minimumBid, uint256 _naturalUnit, address _nextSet, address _coreAddress, address _vaultAddress, uint8 _rebalanceState ) public returns (uint256) { // Must be in Rebalance state to call settlement require( _rebalanceState == uint8(RebalancingLibrary.State.Rebalance), "RebalancingSetToken.settleRebalance: State must be Rebalance" ); // Make sure all currentSets have been rebalanced require( _remainingCurrentSets < _minimumBid, "RebalancingSetToken.settleRebalance: Rebalance not completed" ); // Calculate next Set quantities uint256 issueAmount; uint256 nextUnitShares; ( issueAmount, nextUnitShares ) = calculateNextSetIssueQuantity( _totalSupply, _naturalUnit, _nextSet, _vaultAddress ); require( nextUnitShares > 0, "RebalancingSetToken.settleRebalance: Failed rebalance, unitshares equals 0. Call endFailedAuction." ); // Issue nextSet to RebalancingSetToken ICore(_coreAddress).issueInVault( _nextSet, issueAmount ); return nextUnitShares; } /** * Calculate the amount of nextSets to issue by using the component amounts in the * vault, unitShares following from this calculation. * * @param _totalSupply Total supply of rebalancing set token * @param _naturalUnit Natural unit of rebalancing set token * @param _nextSet Address of next set * @param _vaultAddress Vault address * @return uint256 Amount of nextSets to issue * @return uint256 New unitShares for the rebalancingSetToken */ function calculateNextSetIssueQuantity( uint256 _totalSupply, uint256 _naturalUnit, address _nextSet, address _vaultAddress ) public view returns (uint256, uint256) { // Collect data necessary to compute issueAmounts SetTokenLibrary.SetDetails memory nextSetToken = SetTokenLibrary.getSetDetails(_nextSet); uint256 maxIssueAmount = calculateMaxIssueAmount( _vaultAddress, nextSetToken ); // Calculate the amount of naturalUnits worth of rebalancingSetToken outstanding uint256 naturalUnitsOutstanding = _totalSupply.div(_naturalUnit); // Issue amount of Sets that is closest multiple of nextNaturalUnit to the maxIssueAmount // Since the initial division will round down to the nearest whole number when we multiply // by that same number we will return the closest multiple less than the maxIssueAmount uint256 issueAmount = maxIssueAmount.div(nextSetToken.naturalUnit).mul(nextSetToken.naturalUnit); // Divide final issueAmount by naturalUnitsOutstanding to get newUnitShares uint256 newUnitShares = issueAmount.div(naturalUnitsOutstanding); return (issueAmount, newUnitShares); } /** * Get the maximum possible issue amount of nextSet based on number of components owned by rebalancing * set token. * * @param _vaultAddress Vault address * @param _setToken nextSet details * @return uint256 maxIssueAmount */ function calculateMaxIssueAmount( address _vaultAddress, SetTokenLibrary.SetDetails memory _setToken ) public view returns (uint256) { uint256 maxIssueAmount = CommonMath.maxUInt256(); IVault vaultInstance = IVault(_vaultAddress); for (uint256 i = 0; i < _setToken.components.length; i++) { // Get amount of components in vault owned by rebalancingSetToken uint256 componentAmount = vaultInstance.getOwnerBalance( _setToken.components[i], address(this) ); // Calculate amount of Sets that can be issued from those components, if less than amount for other // components then set that as maxIssueAmount uint256 componentIssueAmount = componentAmount.div(_setToken.units[i]).mul(_setToken.naturalUnit); if (componentIssueAmount < maxIssueAmount) { maxIssueAmount = componentIssueAmount; } } return maxIssueAmount; } } // 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; } /// @return Returns index and isIn for the first occurrence starting from /// end function indexOfFromEnd(address[] memory A, address a) internal pure returns (uint256, bool) { uint256 length = A.length; for (uint256 i = length; i > 0; i--) { if (A[i - 1] == a) { return (i, true); } } return (0, false); } /** * 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 combination of two storage arrays. * @param A The first array * @param B The second array * @return Returns A appended by a */ function sExtend(address[] storage A, address[] storage B) internal { uint256 length = B.length; for (uint256 i = 0; i < length; i++) { A.push(B[i]); } } /** * 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)); } /** * Alternate implementation * Assumes there are no duplicates */ function unionB(address[] memory A, address[] memory B) internal pure returns (address[] memory) { bool[] memory includeMap = new bool[](A.length + B.length); uint256 count = 0; for (uint256 i = 0; i < A.length; i++) { includeMap[i] = true; count++; } for (uint256 j = 0; j < B.length; j++) { if (!contains(A, B[j])) { includeMap[A.length + j] = true; count++; } } address[] memory newAddresses = new address[](count); uint256 k = 0; for (uint256 m = 0; m < A.length; m++) { if (includeMap[m]) { newAddresses[k] = A[m]; k++; } } for (uint256 n = 0; n < B.length; n++) { if (includeMap[A.length + n]) { newAddresses[k] = B[n]; k++; } } return newAddresses; } /** * 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; } /** * @dev Reverses storage array in place */ function sReverse(address[] storage A) internal { address t; uint256 length = A.length; for (uint256 i = 0; i < length / 2; i++) { t = A[i]; A[i] = A[A.length - i - 1]; A[A.length - i - 1] = t; } } /** * 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; } } function sPop(address[] storage A, uint256 index) internal returns (address) { uint256 length = A.length; if (index >= length) { revert("Error: index out of bounds"); } address entry = A[index]; for (uint256 i = index; i < length - 1; i++) { A[i] = A[i + 1]; } A.length--; return entry; } /** * Deletes address at index and fills the spot with the last address. * Order is not preserved. * @return Returns the removed entry */ function sPopCheap(address[] storage A, uint256 index) internal returns (address) { uint256 length = A.length; if (index >= length) { revert("Error: index out of bounds"); } address entry = A[index]; if (index != length - 1) { A[index] = A[length - 1]; delete A[length - 1]; } A.length--; return entry; } /** * Deletes address at index. Works by swapping it with the last address, then deleting. * Order is not preserved * @param A Storage array to remove from */ function sRemoveCheap(address[] storage A, address a) internal { (uint256 index, bool isIn) = indexOf(A, a); if (!isIn) { revert("Error: entry not found"); } else { sPopCheap(A, index); return; } } /** * 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; } /** * Returns the elements indexed at indexArray. * @param A The array to index * @param indexArray The array to use to index * @return Returns array containing elements indexed at indexArray */ function argGet(address[] memory A, uint256[] memory indexArray) internal pure returns (address[] memory) { address[] memory array = new address[](indexArray.length); for (uint256 i = 0; i < indexArray.length; i++) { array[i] = A[indexArray[i]]; } return array; } } // File: contracts/core/tokens/rebalancing-libraries/StartRebalanceLibrary.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 StartRebalanceLibrary * @author Set Protocol * * Default implementation of Rebalancing Set Token startRebalance function */ library StartRebalanceLibrary { using SafeMath for uint256; using AddressArrayUtils for address[]; /* ============ Internal Functions ============ */ /** * Function used to validate time passed to start a rebalance * * @param _proposalStartTime Start time of proposal period * @param _proposalPeriod Required length of proposal period * @param _rebalanceState State rebalancing set token is in */ function validateStartRebalance( uint256 _proposalStartTime, uint256 _proposalPeriod, uint8 _rebalanceState ) external { // Must be in "Proposal" state before going into "Rebalance" state require( _rebalanceState == uint8(RebalancingLibrary.State.Proposal), "RebalancingSetToken.validateStartRebalance: State must be Proposal" ); // Be sure the full proposal period has elapsed require( block.timestamp >= _proposalStartTime.add(_proposalPeriod), "RebalancingSetToken.validateStartRebalance: Proposal period not elapsed" ); } /** * Function used to validate inputs to propose function and initialize biddingParameters struct * * @param _currentSet Address of current Set * @param _nextSet Address of next Set * @param _auctionLibrary Address of auction library being used in rebalance * @param _coreAddress Core address * @param _vaultAddress Vault address * @return Struct containing bidding parameters */ function redeemCurrentSetAndGetBiddingParameters( address _currentSet, address _nextSet, address _auctionLibrary, address _coreAddress, address _vaultAddress ) public returns (RebalancingLibrary.BiddingParameters memory) { // Redeem rounded quantity of current Sets and return redeemed amount of Sets uint256 remainingCurrentSets = redeemCurrentSet( _currentSet, _coreAddress, _vaultAddress ); // Create combined array data structures and calculate minimum bid needed for auction RebalancingLibrary.BiddingParameters memory biddingParameters = setUpBiddingParameters( _currentSet, _nextSet, _auctionLibrary, remainingCurrentSets ); return biddingParameters; } /** * Create struct that holds array representing all components in currentSet and nextSet. * Calcualate unit difference between both sets relative to the largest natural * unit of the two sets. Calculate minimumBid. * * @param _currentSet Address of current Set * @param _nextSet Address of next Set * @param _auctionLibrary Address of auction library being used in rebalance * @param _remainingCurrentSets Quantity of Current Sets redeemed * @return Struct containing bidding parameters */ function setUpBiddingParameters( address _currentSet, address _nextSet, address _auctionLibrary, uint256 _remainingCurrentSets ) public returns (RebalancingLibrary.BiddingParameters memory) { // Get set details for currentSet and nextSet (units, components, natural units) SetTokenLibrary.SetDetails memory currentSet = SetTokenLibrary.getSetDetails(_currentSet); SetTokenLibrary.SetDetails memory nextSet = SetTokenLibrary.getSetDetails(_nextSet); // Create combinedTokenArray address[] memory combinedTokenArray = currentSet.components.union( nextSet.components ); // Calcualate minimumBid uint256 minimumBid = calculateMinimumBid( currentSet.naturalUnit, nextSet.naturalUnit, _auctionLibrary ); // Require remainingCurrentSets to be greater than minimumBid otherwise no bidding would // be allowed require( _remainingCurrentSets >= minimumBid, "RebalancingSetToken.setUpBiddingParameters: Not enough collateral to rebalance" ); // Create memory version of combinedNextSetUnits and combinedCurrentUnits to only make one // call to storage once arrays have been created uint256[] memory combinedCurrentUnits; uint256[] memory combinedNextSetUnits; ( combinedCurrentUnits, combinedNextSetUnits ) = calculateCombinedUnitArrays( currentSet, nextSet, minimumBid, _auctionLibrary, combinedTokenArray ); // Build Bidding Parameters struct and return return RebalancingLibrary.BiddingParameters({ minimumBid: minimumBid, remainingCurrentSets: _remainingCurrentSets, combinedCurrentUnits: combinedCurrentUnits, combinedNextSetUnits: combinedNextSetUnits, combinedTokenArray: combinedTokenArray }); } /** * Calculate the minimumBid allowed for the rebalance * * @param _currentSetNaturalUnit Natural unit of currentSet * @param _nextSetNaturalUnit Natural of nextSet * @param _auctionLibrary Address of auction library being used in rebalance * @return Minimum bid amount */ function calculateMinimumBid( uint256 _currentSetNaturalUnit, uint256 _nextSetNaturalUnit, address _auctionLibrary ) private view returns (uint256) { // Get priceDivisor from auctionLibrary uint256 priceDivisor = IAuctionPriceCurve(_auctionLibrary).priceDivisor(); return Math.max( _currentSetNaturalUnit.mul(priceDivisor), _nextSetNaturalUnit.mul(priceDivisor) ); } /** * Create arrays that represents all components in currentSet and nextSet. * Calcualate unit difference between both sets relative to the largest natural * unit of the two sets. * * @param _currentSet Information on currentSet * @param _nextSet Information on nextSet * @param _minimumBid Minimum bid amount * @param _auctionLibrary Address of auction library being used in rebalance * @param _combinedTokenArray Array of component tokens involved in rebalance * @return Unit inflow/outflow arrays for current and next Set */ function calculateCombinedUnitArrays( SetTokenLibrary.SetDetails memory _currentSet, SetTokenLibrary.SetDetails memory _nextSet, uint256 _minimumBid, address _auctionLibrary, address[] memory _combinedTokenArray ) public returns (uint256[] memory, uint256[] memory) { // Create memory version of combinedNextSetUnits and combinedCurrentUnits to only make one // call to storage once arrays have been created uint256[] memory memoryCombinedCurrentUnits = new uint256[](_combinedTokenArray.length); uint256[] memory memoryCombinedNextSetUnits = new uint256[](_combinedTokenArray.length); for (uint256 i = 0; i < _combinedTokenArray.length; i++) { memoryCombinedCurrentUnits[i] = calculateCombinedUnit( _currentSet, _minimumBid, _auctionLibrary, _combinedTokenArray[i] ); memoryCombinedNextSetUnits[i] = calculateCombinedUnit( _nextSet, _minimumBid, _auctionLibrary, _combinedTokenArray[i] ); } return (memoryCombinedCurrentUnits, memoryCombinedNextSetUnits); } /** * Calculations the unit amount of Token to include in the the combined Set units. * * @param _setToken Information on the SetToken * @param _minimumBid Minimum bid amount * @param _auctionLibrary Address of auction library being used in rebalance * @param _currentComponent Current component in iteration * @return Unit inflow/outflow */ function calculateCombinedUnit( SetTokenLibrary.SetDetails memory _setToken, uint256 _minimumBid, address _auctionLibrary, address _currentComponent ) private returns (uint256) { // Check if component in arrays and get index if it is uint256 indexCurrent; bool isComponent; (indexCurrent, isComponent) = _setToken.components.indexOf(_currentComponent); // Compute unit amounts of token in Set if (isComponent) { return computeTransferValue( _setToken.units[indexCurrent], _setToken.naturalUnit, _minimumBid, _auctionLibrary ); } return 0; } /** * Calculates the maximum redemption quantity and redeems the Set into the vault. * Also updates remainingCurrentSets state variable * * @param _currentSet Address of current Set * @param _coreAddress Core address * @param _vaultAddress Vault address * @return Amount of currentSets remaining */ function redeemCurrentSet( address _currentSet, address _coreAddress, address _vaultAddress ) public returns (uint256) { // Get remainingCurrentSets and make it divisible by currentSet natural unit uint256 currentSetBalance = IVault(_vaultAddress).getOwnerBalance( _currentSet, address(this) ); // Calculates the set's natural unit uint256 currentSetNaturalUnit = ISetToken(_currentSet).naturalUnit(); // Rounds the redemption quantity to a multiple of the current Set natural unit and sets variable uint256 remainingCurrentSets = currentSetBalance.div(currentSetNaturalUnit).mul(currentSetNaturalUnit); ICore(_coreAddress).redeemInVault( _currentSet, remainingCurrentSets ); return remainingCurrentSets; } /** * Function to calculate the transfer value of a component given a standardized bid amount * (minimumBid/priceDivisor) * * @param _unit Units of the component token * @param _naturalUnit Natural unit of the Set token * @param _minimumBid Minimum bid amount * @return uint256 Amount of tokens per standard bid amount (minimumBid/priceDivisor) */ function computeTransferValue( uint256 _unit, uint256 _naturalUnit, uint256 _minimumBid, address _auctionLibrary ) internal returns (uint256) { uint256 priceDivisor = IAuctionPriceCurve(_auctionLibrary).priceDivisor(); return _minimumBid.mul(_unit).div(_naturalUnit).div(priceDivisor); } } // File: contracts/core/tokens/RebalancingSetToken.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 RebalancingSetToken * @author Set Protocol * * Implementation of Rebalancing Set token. */ contract RebalancingSetToken is ERC20, ERC20Detailed { using SafeMath for uint256; /* ============ State Variables ============ */ // Dependency variables address public core; address public factory; address public vault; address public componentWhiteListAddress; // Core and Vault instances ICore private coreInstance; IVault private vaultInstance; IWhiteList private componentWhiteListInstance; uint256 public naturalUnit; address public manager; RebalancingLibrary.State public rebalanceState; // State updated after every rebalance address public currentSet; uint256 public unitShares; uint256 public lastRebalanceTimestamp; // State governing rebalance cycle uint256 public proposalPeriod; uint256 public rebalanceInterval; // State to track proposal period uint256 public proposalStartTime; // State needed for auction/rebalance address public nextSet; address public auctionLibrary; uint256 public startingCurrentSetAmount; RebalancingLibrary.AuctionPriceParameters public auctionPriceParameters; RebalancingLibrary.BiddingParameters public biddingParameters; // To be used if token put into Drawdown State address[] public failedAuctionWithdrawComponents; /* ============ Events ============ */ event NewManagerAdded( address newManager, address oldManager ); event RebalanceProposed( address nextSet, address indexed auctionLibrary, uint256 indexed proposalPeriodEndTime ); event RebalanceStarted( address oldSet, address newSet ); /* ============ Constructor ============ */ /** * Constructor function for Rebalancing Set Token * * @param _factory Factory used to create the Rebalancing Set * @param _manager Manager of the Rebalancing Set * @param _initialSet Initial set that collateralizes the Rebalancing set * @param _initialUnitShares Units of currentSet that equals one share * @param _naturalUnit The minimum multiple of Sets that can be issued or redeemed * @param _proposalPeriod Amount of time for users to inspect a rebalance proposal * @param _rebalanceInterval Minimum amount of time between rebalances * @param _componentWhiteList Address of component WhiteList contract * @param _name The name of the new RebalancingSetToken * @param _symbol The symbol of the new RebalancingSetToken */ constructor( address _factory, address _manager, address _initialSet, uint256 _initialUnitShares, uint256 _naturalUnit, uint256 _proposalPeriod, uint256 _rebalanceInterval, address _componentWhiteList, string memory _name, string memory _symbol ) public ERC20Detailed( _name, _symbol, 18 ) { // Require initial unit shares is non-zero require( _initialUnitShares > 0, "RebalancingSetToken.constructor: Unit shares must be positive" ); IRebalancingSetFactory tokenFactory = IRebalancingSetFactory(_factory); require( _naturalUnit >= tokenFactory.minimumNaturalUnit(), "RebalancingSetToken.constructor: Natural Unit too low" ); require( _naturalUnit <= tokenFactory.maximumNaturalUnit(), "RebalancingSetToken.constructor: Natural Unit too large" ); // Require manager address is non-zero require( _manager != address(0), "RebalancingSetToken.constructor: Invalid manager address" ); // Require minimum rebalance interval and proposal period from factory require( _proposalPeriod >= tokenFactory.minimumProposalPeriod(), "RebalancingSetToken.constructor: Proposal period too short" ); require( _rebalanceInterval >= tokenFactory.minimumRebalanceInterval(), "RebalancingSetToken.constructor: Rebalance interval too short" ); core = IRebalancingSetFactory(_factory).core(); coreInstance = ICore(core); vault = coreInstance.vault(); vaultInstance = IVault(vault); componentWhiteListAddress = _componentWhiteList; componentWhiteListInstance = IWhiteList(_componentWhiteList); factory = _factory; manager = _manager; currentSet = _initialSet; unitShares = _initialUnitShares; naturalUnit = _naturalUnit; proposalPeriod = _proposalPeriod; rebalanceInterval = _rebalanceInterval; lastRebalanceTimestamp = block.timestamp; rebalanceState = RebalancingLibrary.State.Default; } /* ============ Public Functions ============ */ /** * Function used to set the terms of the next rebalance and start the proposal period * * @param _nextSet The Set to rebalance into * @param _auctionLibrary The library used to calculate the Dutch Auction price * @param _auctionTimeToPivot The amount of time for the auction to go ffrom start to pivot price * @param _auctionStartPrice The price to start the auction at * @param _auctionPivotPrice The price at which the price curve switches from linear to exponential */ function propose( address _nextSet, address _auctionLibrary, uint256 _auctionTimeToPivot, uint256 _auctionStartPrice, uint256 _auctionPivotPrice ) external { // Put together auction price parameters RebalancingLibrary.AuctionPriceParameters memory auctionPriceParams = RebalancingLibrary.AuctionPriceParameters({ auctionTimeToPivot: _auctionTimeToPivot, auctionStartPrice: _auctionStartPrice, auctionPivotPrice: _auctionPivotPrice, auctionStartTime: 0 }); // Create ProposeAuctionParameters ProposeLibrary.ProposalContext memory proposalContext = ProposeLibrary.ProposalContext({ manager: manager, currentSet: currentSet, coreAddress: core, componentWhitelist: componentWhiteListAddress, factoryAddress: factory, lastRebalanceTimestamp: lastRebalanceTimestamp, rebalanceInterval: rebalanceInterval, rebalanceState: uint8(rebalanceState) }); // Validate proposal inputs and initialize auctionPriceParameters ProposeLibrary.validateProposal( _nextSet, _auctionLibrary, proposalContext, auctionPriceParams ); // Update state parameters auctionPriceParameters = auctionPriceParams; nextSet = _nextSet; auctionLibrary = _auctionLibrary; proposalStartTime = block.timestamp; rebalanceState = RebalancingLibrary.State.Proposal; emit RebalanceProposed( _nextSet, _auctionLibrary, proposalStartTime.add(proposalPeriod) ); } /* * Initiate rebalance for the rebalancing set if the proposal period has elapsed after * a proposal. */ function startRebalance() external { // Validate the correct rebalance state and time elapsed StartRebalanceLibrary.validateStartRebalance( proposalStartTime, proposalPeriod, uint8(rebalanceState) ); // Redeem currentSet and set up biddingParameters biddingParameters = StartRebalanceLibrary.redeemCurrentSetAndGetBiddingParameters( currentSet, nextSet, auctionLibrary, core, vault ); // Update state parameters startingCurrentSetAmount = biddingParameters.remainingCurrentSets; auctionPriceParameters.auctionStartTime = block.timestamp; rebalanceState = RebalancingLibrary.State.Rebalance; emit RebalanceStarted(currentSet, nextSet); } /* * Initiate settlement for the rebalancing set. Full functionality now returned to * set owners * */ function settleRebalance() external { // Settle the rebalance and mint next Sets unitShares = SettleRebalanceLibrary.settleRebalance( totalSupply(), biddingParameters.remainingCurrentSets, biddingParameters.minimumBid, naturalUnit, nextSet, core, vault, uint8(rebalanceState) ); // Update other state parameters currentSet = nextSet; lastRebalanceTimestamp = block.timestamp; rebalanceState = RebalancingLibrary.State.Default; clearAuctionState(); } /* * Place bid during rebalance auction. Can only be called by Core. * * @param _quantity The amount of currentSet to be rebalanced * @return combinedTokenArray Array of token addresses invovled in rebalancing * @return inflowUnitArray Array of amount of tokens inserted into system in bid * @return outflowUnitArray Array of amount of tokens taken out of system in bid */ function placeBid( uint256 _quantity ) external returns (address[] memory, uint256[] memory, uint256[] memory) { // Validate bid quantity and module is sender PlaceBidLibrary.validatePlaceBid( _quantity, core, biddingParameters ); // Place bid and get back inflow and outflow arrays uint256[] memory inflowUnitArray; uint256[] memory outflowUnitArray; ( inflowUnitArray, outflowUnitArray ) = getBidPrice(_quantity); // Update remainingCurrentSet figure to account for placed bid biddingParameters.remainingCurrentSets = biddingParameters.remainingCurrentSets.sub(_quantity); return (biddingParameters.combinedTokenArray, inflowUnitArray, outflowUnitArray); } /* * Fail an auction that doesn't complete before reaching the pivot price. Move to Drawdown state * if bids have been placed. Reset to Default state if no bids placed. * */ function endFailedAuction() external { uint256 calculatedUnitShares; ( , calculatedUnitShares ) = SettleRebalanceLibrary.calculateNextSetIssueQuantity( totalSupply(), naturalUnit, nextSet, vault ); // Fail auction and either reset to Default state or kill Rebalancing Set Token and enter Drawdown // state uint8 integerRebalanceState = FailAuctionLibrary.endFailedAuction( startingCurrentSetAmount, calculatedUnitShares, currentSet, core, auctionPriceParameters, biddingParameters, uint8(rebalanceState) ); rebalanceState = RebalancingLibrary.State(integerRebalanceState); // Reset lastRebalanceTimestamp to now lastRebalanceTimestamp = block.timestamp; // Save combined token arrays to failedAuctionWithdrawComponents failedAuctionWithdrawComponents = biddingParameters.combinedTokenArray; // Clear auction state clearAuctionState(); } /* * Get token inflows and outflows required for bid. Also the amount of Rebalancing * Sets that would be generated. * * @param _quantity The amount of currentSet to be rebalanced * @return inflowUnitArray Array of amount of tokens inserted into system in bid * @return outflowUnitArray Array of amount of tokens taken out of system in bid */ function getBidPrice( uint256 _quantity ) public view returns (uint256[] memory, uint256[] memory) { return PlaceBidLibrary.getBidPrice( _quantity, auctionLibrary, biddingParameters, auctionPriceParameters, uint8(rebalanceState) ); } /* * Mint set token for given address. * Can only be called by Core contract. * * @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 { // Check that function caller is Core require( msg.sender == core, "RebalancingSetToken.mint: Sender must be core" ); // Check that set is not in Rebalance State require( rebalanceState != RebalancingLibrary.State.Rebalance, "RebalancingSetToken.mint: Cannot mint during Rebalance" ); // Check that set is not in Drawdown State require( rebalanceState != RebalancingLibrary.State.Drawdown, "RebalancingSetToken.mint: Cannot mint during Drawdown" ); // Update token balance of the manager _mint(_issuer, _quantity); } /* * 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 { // Check that set is not in Rebalancing State require( rebalanceState != RebalancingLibrary.State.Rebalance, "RebalancingSetToken.burn: Cannot burn during Rebalance" ); // Check to see if state is Drawdown if (rebalanceState == RebalancingLibrary.State.Drawdown) { // In Drawdown Sets can only be burned as part of the withdrawal process require( coreInstance.validModules(msg.sender), "RebalancingSetToken.burn: Set cannot be redeemed during Drawdown" ); } else { // When in non-Rebalance or Drawdown state, check that function caller is Core // so that Sets can be redeemed require( msg.sender == core, "RebalancingSetToken.burn: Sender must be core" ); } _burn(_from, _quantity); } /* * Set new manager address * * @param _newManager The address of the new manager account */ function setManager( address _newManager ) external { require( msg.sender == manager, "RebalancingSetToken.setManager: Sender must be the manager" ); emit NewManagerAdded(_newManager, manager); manager = _newManager; } /* ============ Getter Functions ============ */ /* * Get addresses of setToken underlying the Rebalancing Set * * @return componentAddresses Array of currentSet */ function getComponents() external view returns (address[] memory) { address[] memory components = new address[](1); components[0] = currentSet; return components; } /* * Get unitShares of Rebalancing Set * * @return units Array of component unit */ function getUnits() external view returns (uint256[] memory) { uint256[] memory units = new uint256[](1); units[0] = unitShares; return units; } /* * Get biddingParameters of Rebalancing Set * * @return biddingParams Object with bidding information */ function getBiddingParameters() external view returns (uint256[] memory) { uint256[] memory biddingParams = new uint256[](2); biddingParams[0] = biddingParameters.minimumBid; biddingParams[1] = biddingParameters.remainingCurrentSets; return biddingParams; } /* * Get auctionPriceParameters of Rebalancing Set * * @return auctionParams Object with auction information */ function getAuctionPriceParameters() external view returns (uint256[] memory) { uint256[] memory auctionParams = new uint256[](4); auctionParams[0] = auctionPriceParameters.auctionStartTime; auctionParams[1] = auctionPriceParameters.auctionTimeToPivot; auctionParams[2] = auctionPriceParameters.auctionStartPrice; auctionParams[3] = auctionPriceParameters.auctionPivotPrice; return auctionParams; } /* * Checks to make sure address is the current set of the RebalancingSetToken. * Conforms to the ISetToken Interface. * * @param _tokenAddress Address of token being checked * @return bool True if token is the current Set */ function tokenIsComponent( address _tokenAddress ) external view returns (bool) { return _tokenAddress == currentSet; } /* * Get combinedTokenArray of Rebalancing Set * * @return combinedTokenArray */ function getCombinedTokenArrayLength() external view returns (uint256) { return biddingParameters.combinedTokenArray.length; } /* * Get combinedTokenArray of Rebalancing Set * * @return combinedTokenArray */ function getCombinedTokenArray() external view returns (address[] memory) { return biddingParameters.combinedTokenArray; } /* * Get combinedCurrentUnits of Rebalancing Set * * @return combinedCurrentUnits */ function getCombinedCurrentUnits() external view returns (uint256[] memory) { return biddingParameters.combinedCurrentUnits; } /* * Get combinedNextSetUnits of Rebalancing Set * * @return combinedNextSetUnits */ function getCombinedNextSetUnits() external view returns (uint256[] memory) { return biddingParameters.combinedNextSetUnits; } /* * Get failedAuctionWithdrawComponents of Rebalancing Set * * @return failedAuctionWithdrawComponents */ function getFailedAuctionWithdrawComponents() external view returns (address[] memory) { return failedAuctionWithdrawComponents; } /* ============ Internal Functions ============ */ /* * Reset auction specific state after failed or successful rebalance */ function clearAuctionState() internal { nextSet = address(0); auctionLibrary = address(0); startingCurrentSetAmount = 0; delete auctionPriceParameters; delete biddingParameters; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"unitShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getUnits","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"failedAuctionWithdrawComponents","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rebalanceInterval","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenAddress","type":"address"}],"name":"tokenIsComponent","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"proposalPeriod","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_issuer","type":"address"},{"name":"_quantity","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"naturalUnit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"startingCurrentSetAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"manager","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"startRebalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getCombinedTokenArrayLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"biddingParameters","outputs":[{"name":"minimumBid","type":"uint256"},{"name":"remainingCurrentSets","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"endFailedAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nextSet","type":"address"},{"name":"_auctionLibrary","type":"address"},{"name":"_auctionTimeToPivot","type":"uint256"},{"name":"_auctionStartPrice","type":"uint256"},{"name":"_auctionPivotPrice","type":"uint256"}],"name":"propose","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getCombinedTokenArray","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"auctionLibrary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_quantity","type":"uint256"}],"name":"placeBid","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getComponents","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_quantity","type":"uint256"}],"name":"getBidPrice","outputs":[{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_quantity","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAuctionPriceParameters","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBiddingParameters","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"proposalStartTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRebalanceTimestamp","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextSet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCombinedNextSetUnits","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newManager","type":"address"}],"name":"setManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"auctionPriceParameters","outputs":[{"name":"auctionStartTime","type":"uint256"},{"name":"auctionTimeToPivot","type":"uint256"},{"name":"auctionStartPrice","type":"uint256"},{"name":"auctionPivotPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getFailedAuctionWithdrawComponents","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCombinedCurrentUnits","outputs":[{"name":"","type":"uint256[]"}],"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":"rebalanceState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"settleRebalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"componentWhiteListAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_factory","type":"address"},{"name":"_manager","type":"address"},{"name":"_initialSet","type":"address"},{"name":"_initialUnitShares","type":"uint256"},{"name":"_naturalUnit","type":"uint256"},{"name":"_proposalPeriod","type":"uint256"},{"name":"_rebalanceInterval","type":"uint256"},{"name":"_componentWhiteList","type":"address"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newManager","type":"address"},{"indexed":false,"name":"oldManager","type":"address"}],"name":"NewManagerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nextSet","type":"address"},{"indexed":true,"name":"auctionLibrary","type":"address"},{"indexed":true,"name":"proposalPeriodEndTime","type":"uint256"}],"name":"RebalanceProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldSet","type":"address"},{"indexed":false,"name":"newSet","type":"address"}],"name":"RebalanceStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003a0938038062003a0983398101806040526200003791908101906200079f565b8181601282600390805190602001906200005392919062000652565b5081516200006990600490602085019062000652565b506005805460ff90921660ff19909216919091179055505086620000c4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bb9062000b0c565b60405180910390fd5b60008a905080600160a060020a031663befbe99c6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200012157600080fd5b505af115801562000136573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506200015c9190810190620008bd565b87101562000198576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bb9062000ad6565b80600160a060020a0316638be5c4666040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015620001f057600080fd5b505af115801562000205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506200022b9190810190620008bd565b87111562000267576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bb9062000b1e565b600160a060020a038a16620002aa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bb9062000ae8565b80600160a060020a031663f81d6d326040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200030257600080fd5b505af115801562000317573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506200033d9190810190620008bd565b86101562000379576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bb9062000abe565b80600160a060020a03166381b1c8206040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015620003d157600080fd5b505af1158015620003e6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506200040c9190810190620008bd565b85101562000448576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bb9062000afa565b8a600160a060020a031663f2f4eb266040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015620004a057600080fd5b505af1158015620004b5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620004db919081019062000776565b6005805461010060a860020a031916610100600160a060020a039384168102919091179182905560098054919092048316600160a060020a03199091161790819055604080517ffbfa77cf0000000000000000000000000000000000000000000000000000000081529051919092169163fbfa77cf916004808301926020929190829003018186803b1580156200057157600080fd5b505afa15801562000586573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620005ac919081019062000776565b60078054600160a060020a0319908116600160a060020a039384161791829055600a8054928416928216929092179091556008805482169683169687179055600b805482169096179095556006805486169c82169c909c17909b555050600d8054600e80548516998c1699909917909855600f9690965550600c939093556011919091556012554260105591909116919092161760a060020a60ff021916905562000bcd565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200069557805160ff1916838001178555620006c5565b82800160010185558215620006c5579182015b82811115620006c5578251825591602001919060010190620006a8565b50620006d3929150620006d7565b5090565b620006f491905b80821115620006d35760008155600101620006de565b90565b600062000705825162000b88565b9392505050565b600082601f8301126200071e57600080fd5b8151620007356200072f8262000b57565b62000b30565b915080825260208301602083018583830111156200075257600080fd5b6200075f83828462000b9a565b50505092915050565b6000620007058251620006f4565b6000602082840312156200078957600080fd5b6000620007978484620006f7565b949350505050565b6000806000806000806000806000806101408b8d031215620007c057600080fd5b6000620007ce8d8d620006f7565b9a50506020620007e18d828e01620006f7565b9950506040620007f48d828e01620006f7565b9850506060620008078d828e0162000768565b97505060806200081a8d828e0162000768565b96505060a06200082d8d828e0162000768565b95505060c0620008408d828e0162000768565b94505060e0620008538d828e01620006f7565b9350506101008b01516001604060020a038111156200087157600080fd5b6200087f8d828e016200070c565b9250506101208b01516001604060020a038111156200089d57600080fd5b620008ab8d828e016200070c565b9150509295989b9194979a5092959850565b600060208284031215620008d057600080fd5b600062000797848462000768565b6000620008ed603a8362000b7f565b600080516020620039e983398151915281527f2050726f706f73616c20706572696f6420746f6f2073686f7274000000000000602082015260400192915050565b60006200093d60358362000b7f565b600080516020620039e983398151915281527f204e61747572616c20556e697420746f6f206c6f770000000000000000000000602082015260400192915050565b60006200098d60388362000b7f565b600080516020620039e983398151915281527f20496e76616c6964206d616e6167657220616464726573730000000000000000602082015260400192915050565b6000620009dd603d8362000b7f565b600080516020620039e983398151915281527f20526562616c616e636520696e74657276616c20746f6f2073686f7274000000602082015260400192915050565b600062000a2d603d8362000b7f565b600080516020620039e983398151915281527f20556e697420736861726573206d75737420626520706f736974697665000000602082015260400192915050565b600062000a7d60378362000b7f565b600080516020620039e983398151915281527f204e61747572616c20556e697420746f6f206c61726765000000000000000000602082015260400192915050565b6020808252810162000ad081620008de565b92915050565b6020808252810162000ad0816200092e565b6020808252810162000ad0816200097e565b6020808252810162000ad081620009ce565b6020808252810162000ad08162000a1e565b6020808252810162000ad08162000a6e565b6040518181016001604060020a038111828210171562000b4f57600080fd5b604052919050565b60006001604060020a0382111562000b6e57600080fd5b506020601f91909101601f19160190565b90815260200190565b6000600160a060020a03821662000ad0565b60005b8381101562000bb757818101518382015260200162000b9d565b8381111562000bc7576000848401525b50505050565b612e0c8062000bdd6000396000f3fe608060405234801561001057600080fd5b50600436106102bf5760003560e060020a9004806395d89b4111610186578063c45a0155116100ed578063f0284b1c116100a6578063f75af97f11610080578063f75af97f14610572578063fa2d8c9014610587578063fbfa77cf1461058f578063fccde48f14610597576102bf565b8063f0284b1c1461055a578063f056a9ae14610562578063f2f4eb261461056a576102bf565b8063c45a015514610504578063cb6316991461050c578063cdb026a114610514578063d0ebdbe71461051c578063d600ae481461052f578063dd62ed3e14610547576102bf565b8063a065172b1161013f578063a065172b146104be578063a2e59c91146104c6578063a457c2d7146104ce578063a9059cbb146104e1578063a9faafd9146104f4578063b83d8157146104fc576102bf565b806395d89b411461045057806396213fc7146104585780639979ef451461046057806399d50d5d146104825780639b013aee1461048a5780639dc29fac146104ab576102bf565b8063395093511161022a578063570f3167116101e3578063570f3167146103ef57806357d3810e146103f757806370a082311461040d57806375aff3c1146104205780637632b24b146104285780638618711c1461043b576102bf565b806339509351146103a757806340c10f19146103ba57806342a7cfd5146103cf5780634394380b146103d7578063481c6a75146103df5780634dce7057146103e7576102bf565b806318160ddd1161027c57806318160ddd1461035457806318c53aca1461035c57806323b872dd1461036f5780632c103c791461038257806330b866271461038a578063313ce56714610392576102bf565b80630193aea2146102c4578063027aa9f5146102e257806306fdde03146102f7578063095ea7b31461030c5780630ca60f861461032c57806316d1d9161461034c575b600080fd5b6102cc61059f565b6040516102d99190612a75565b60405180910390f35b6102ea6105a5565b6040516102d991906129a2565b6102ff6105eb565b6040516102d991906129f4565b61031f61031a3660046120d6565b610681565b6040516102d991906129d8565b61033f61033a3660046121b8565b610698565b6040516102d9919061289f565b6102cc6106bf565b6102cc6106c5565b61031f61036a366004611fb4565b6106cb565b61031f61037d366004612014565b6106df565b6102cc610737565b61033f61073d565b61039a61074c565b6040516102d99190612c90565b61031f6103b53660046120d6565b610755565b6103cd6103c83660046120d6565b610791565b005b6102cc610850565b6102cc610856565b61033f61085c565b6103cd61086b565b6102cc610ab0565b6103ff610ab6565b6040516102d9929190612afa565b6102cc61041b366004611fb4565b610abf565b6103cd610ada565b6103cd610436366004612061565b610cbc565b610443610ecd565b6040516102d99190612958565b6102ff610f31565b61033f610f92565b61047361046e3660046121b8565b610fa1565b6040516102d993929190612969565b6104436110f2565b61049d6104983660046121b8565b61114e565b6040516102d99291906129b3565b6103cd6104b93660046120d6565b61121c565b6102ea611370565b6102ea611406565b61031f6104dc3660046120d6565b61145c565b61031f6104ef3660046120d6565b611498565b6102cc6114a5565b6102cc6114ab565b61033f6114b1565b61033f6114c0565b6102ea6114cf565b6103cd61052a366004611fb4565b611529565b6105376115ca565b6040516102d99493929190612bbc565b6102cc610555366004611fda565b6115d9565b610443611604565b6102ea611664565b61033f6116bd565b61057a6116d1565b6040516102d991906129e6565b6103cd6116e1565b61033f61181a565b61033f611829565b600f5481565b60408051600180825281830190925260609182919060208083019080388339019050509050600f54816000815181106105da57fe5b602090810291909101015290505b90565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106775780601f1061064c57610100808354040283529160200191610677565b820191906000526020600020905b81548152906001019060200180831161065a57829003601f168201915b5050505050905090565b600061068e338484611838565b5060015b92915050565b602081815481106106a557fe5b600091825260209091200154600160a060020a0316905081565b60125481565b60025490565b600e54600160a060020a0390811691161490565b60006106ec8484846118c6565b600160a060020a03841660009081526001602090815260408083203380855292529091205461072c918691610727908663ffffffff61198916565b611838565b5060015b9392505050565b60115481565b600e54600160a060020a031681565b60055460ff1690565b336000818152600160209081526040808320600160a060020a0387168452909152812054909161068e918590610727908663ffffffff61199e16565b6005546101009004600160a060020a031633146107cc5760405160e560020a62461bcd0281526004016107c390612a45565b60405180910390fd5b6002600d5460a060020a900460ff1660038111156107e657fe5b14156108075760405160e560020a62461bcd0281526004016107c390612a25565b6003600d5460a060020a900460ff16600381111561082157fe5b14156108425760405160e560020a62461bcd0281526004016107c390612a35565b61084c82826119b0565b5050565b600c5481565b60165481565b600d54600160a060020a031681565b73b2d113cd923b763bd4f2187233257da57f3f1ddb638f1880c4601354601154600d60149054906101000a900460ff1660038111156108a657fe5b6040518463ffffffff1660e060020a0281526004016108c793929190612c68565b60006040518083038186803b1580156108df57600080fd5b505af41580156108f3573d6000803e3d6000fd5b5050600e546014546015546005546007546040517fa569cda100000000000000000000000000000000000000000000000000000000815273b2d113cd923b763bd4f2187233257da57f3f1ddb975063a569cda1965061097095600160a060020a0390811695811694811693610100900481169216906004016128d6565b60006040518083038186803b15801561098857600080fd5b505af415801561099c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109c49190810190612183565b8051601b908155602080830151601c55604083015180516109e992601d920190611b71565b5060608201518051610a05916003840191602090910190611b71565b5060808201518051610a21916004840191602090910190611bbc565b5050601c546016555042601755600d805474ff0000000000000000000000000000000000000000191674020000000000000000000000000000000000000000179055600e546014546040517fe57340a36ab2ae0bdbec3486f504d5df3a525cd11937e20641f2c64ca126f1c192610aa692600160a060020a03918216929116906128bb565b60405180910390a1565b601f5490565b601b54601c5482565b600160a060020a031660009081526020819052604090205490565b600073c0aafee4b4edc54dd3aea0bf4dbe7bddde6365ca63495c23bd610afe6106c5565b600c5460145460075460405160e060020a63ffffffff8716028152610b35949392600160a060020a03908116921690600401612b15565b604080518083038186803b158015610b4c57600080fd5b505af4158015610b60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b8491908101906121f4565b601654600e54600554600d549395506000945073a2619134b0851744d6e5052392400df73b24d7fc93631ab90ff993928792600160a060020a039182169261010090910490911690601790601b9060a060020a900460ff166003811115610be757fe5b6040518863ffffffff1660e060020a028152600401610c0c9796959493929190612b4a565b60206040518083038186803b158015610c2457600080fd5b505af4158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c5c9190810190612224565b90508060ff166003811115610c6d57fe5b600d805474ff0000000000000000000000000000000000000000191660a060020a836003811115610c9a57fe5b021790555042601055601f8054610cb391602091611c2a565b5061084c611a5d565b610cc4611c6a565b604051806080016040528060008152602001858152602001848152602001838152509050610cf0611c92565b604080516101008082018352600d54600160a060020a038082168452600e5481166020850152600554929092048216938301939093526008548116606083015260065416608082015260105460a082015260125460c08201529060e082019060a060020a900460ff166003811115610d6457fe5b60ff1690526040517f56ca7aa200000000000000000000000000000000000000000000000000000000815290915073dd5825965a016d8bbbbdf4862a1ac9d3fb6d5382906356ca7aa290610dc2908a908a9086908890600401612918565b60006040518083038186803b158015610dda57600080fd5b505af4158015610dee573d6000803e3d6000fd5b505083516017555050602082015160185560408201516019556060820151601a5560148054600160a060020a0389811673ffffffffffffffffffffffffffffffffffffffff19928316179092556015805492891692909116919091179055426013819055600d805474ff0000000000000000000000000000000000000000191660a060020a179055601154610e83919061199e565b86600160a060020a03167f6a20b1a24d612c34a3b539bd9f3cc66319e62c01bafbc9fc9f5362e2bfbacb3c89604051610ebc919061289f565b60405180910390a350505050505050565b6060601b60040180548060200260200160405190810160405280929190818152602001828054801561067757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610f0a575050505050905090565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106775780601f1061064c57610100808354040283529160200191610677565b601554600160a060020a031681565b6005546040517f773d40cc00000000000000000000000000000000000000000000000000000000815260609182918291734689051f4246630deb7c1c4cfb2ffa25643d886c9163773d40cc9161100d9188916101009004600160a060020a031690601b90600401612a83565b60206040518083038186803b15801561102557600080fd5b505af4158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061105d91908101906121d6565b5060608061106a8661114e565b601c549193509150611082908763ffffffff61198916565b601c55601f805460408051602080840282018101909252828152859285928591908301828280156110dc57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116110be575b5050505050925094509450945050509193909250565b604080516001808252818301909252606091829190602080830190803883395050600e548251929350600160a060020a03169183915060009061113157fe5b600160a060020a0390921660209283029190910190910152905090565b601554600d546060918291734689051f4246630deb7c1c4cfb2ffa25643d886c91635a6bff16918691600160a060020a031690601b9060179060a060020a900460ff16600381111561119c57fe5b6040518663ffffffff1660e060020a0281526004016111bf959493929190612ab0565b60006040518083038186803b1580156111d757600080fd5b505af41580156111eb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112139190810190612106565b91509150915091565b6002600d5460a060020a900460ff16600381111561123657fe5b14156112575760405160e560020a62461bcd0281526004016107c390612a55565b6003600d5460a060020a900460ff16600381111561127157fe5b1415611334576009546040517f5e633498000000000000000000000000000000000000000000000000000000008152600160a060020a0390911690635e633498906112c09033906004016128ad565b60206040518083038186803b1580156112d857600080fd5b505afa1580156112ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113109190810190612165565b61132f5760405160e560020a62461bcd0281526004016107c390612a65565b611366565b6005546101009004600160a060020a031633146113665760405160e560020a62461bcd0281526004016107c390612a05565b61084c8282611ad3565b60408051600480825260a0820190925260609182919060208201608080388339019050509050601760000154816000815181106113a957fe5b602002602001018181525050601760010154816001815181106113c857fe5b602002602001018181525050601760020154816002815181106113e757fe5b602002602001018181525050601760030154816003815181106105da57fe5b604080516002808252606080830184529283929190602083019080388339019050509050601b600001548160008151811061143d57fe5b602002602001018181525050601b60010154816001815181106105da57fe5b336000818152600160209081526040808320600160a060020a0387168452909152812054909161068e918590610727908663ffffffff61198916565b600061068e3384846118c6565b60135481565b60105481565b600654600160a060020a031681565b601454600160a060020a031681565b6060601b60030180548060200260200160405190810160405280929190818152602001828054801561067757602002820191906000526020600020905b81548152602001906001019080831161150c575050505050905090565b600d54600160a060020a031633146115565760405160e560020a62461bcd0281526004016107c390612a15565b600d546040517ff9c15f5b74b4e002e8881b2d9810116b1d4d45461e6dd7ac8111381b592e2c6591611593918491600160a060020a0316906128bb565b60405180910390a1600d805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b601754601854601954601a5484565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6060602080548060200260200160405190810160405280929190818152602001828054801561067757602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610f0a575050505050905090565b6060601b600201805480602002602001604051908101604052809291908181526020018280548015610677576020028201919060005260206000209081548152602001906001019080831161150c575050505050905090565b6005546101009004600160a060020a031681565b600d5460a060020a900460ff1681565b73c0aafee4b4edc54dd3aea0bf4dbe7bddde6365ca63084f9bce6117036106c5565b601c54601b54600c54601454600554600754600d54600160a060020a03938416936101009093048316929091169060a060020a900460ff16600381111561174657fe5b6040518963ffffffff1660e060020a02815260040161176c989796959493929190612bf1565b60206040518083038186803b15801561178457600080fd5b505af4158015611798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117bc91908101906121d6565b600f55601454600e805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0390921691909117905542601055600d805474ff000000000000000000000000000000000000000019169055611818611a5d565b565b600754600160a060020a031681565b600854600160a060020a031681565b600160a060020a03821661184b57600080fd5b600160a060020a03831661185e57600080fd5b600160a060020a0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906118b9908590612a75565b60405180910390a3505050565b600160a060020a0382166118d957600080fd5b600160a060020a038316600090815260208190526040902054611902908263ffffffff61198916565b600160a060020a038085166000908152602081905260408082209390935590841681522054611937908263ffffffff61199e16565b600160a060020a0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906118b9908590612a75565b60008282111561199857600080fd5b50900390565b60008282018381101561073057600080fd5b600160a060020a0382166119c357600080fd5b6002546119d6908263ffffffff61199e16565b600255600160a060020a038216600090815260208190526040902054611a02908263ffffffff61199e16565b600160a060020a0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a51908590612a75565b60405180910390a35050565b6014805473ffffffffffffffffffffffffffffffffffffffff1990811690915560158054909116905560006016819055601781905560188190556019819055601a819055601b818155601c82905590611ab7601d82611cd6565b611ac5600383016000611cd6565b61084c600483016000611cd6565b600160a060020a038216611ae657600080fd5b600254611af9908263ffffffff61198916565b600255600160a060020a038216600090815260208190526040902054611b25908263ffffffff61198916565b600160a060020a0383166000818152602081905260408082209390935591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a51908590612a75565b828054828255906000526020600020908101928215611bac579160200282015b82811115611bac578251825591602001919060010190611b91565b50611bb8929150611cf7565b5090565b828054828255906000526020600020908101928215611c1e579160200282015b82811115611c1e578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190611bdc565b50611bb8929150611d11565b828054828255906000526020600020908101928215611c1e5760005260206000209182015b82811115611c1e578254825591600101919060010190611c4f565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b5080546000825590600052602060002090810190611cf49190611cf7565b50565b6105e891905b80821115611bb85760008155600101611cfd565b6105e891905b80821115611bb857805473ffffffffffffffffffffffffffffffffffffffff19168155600101611d17565b60006107308235612d0f565b60006107308251612d0f565b600082601f830112611d6b57600080fd5b8151611d7e611d7982612cc5565b612c9e565b91508181835260208401935060208101905083856020840282011115611da357600080fd5b60005b83811015611dcf5781611db98882611d4e565b8452506020928301929190910190600101611da6565b5050505092915050565b600082601f830112611dea57600080fd5b8151611df8611d7982612cc5565b91508181835260208401935060208101905083856020840282011115611e1d57600080fd5b60005b83811015611dcf5781611e338882611f9c565b8452506020928301929190910190600101611e20565b600082601f830112611e5a57600080fd5b8151611e68611d7982612cc5565b91508181835260208401935060208101905083856020840282011115611e8d57600080fd5b60005b83811015611dcf5781611ea38882611f9c565b8452506020928301929190910190600101611e90565b60006107308251612d1a565b600060a08284031215611ed757600080fd5b611ee160a0612c9e565b90506000611eef8484611f9c565b8252506020611f0084848301611f9c565b602083015250604082015167ffffffffffffffff811115611f2057600080fd5b611f2c84828501611dd9565b604083015250606082015167ffffffffffffffff811115611f4c57600080fd5b611f5884828501611dd9565b606083015250608082015167ffffffffffffffff811115611f7857600080fd5b611f8484828501611d5a565b60808301525092915050565b600061073082356105e8565b600061073082516105e8565b60006107308251612d37565b600060208284031215611fc657600080fd5b6000611fd28484611d42565b949350505050565b60008060408385031215611fed57600080fd5b6000611ff98585611d42565b925050602061200a85828601611d42565b9150509250929050565b60008060006060848603121561202957600080fd5b60006120358686611d42565b935050602061204686828701611d42565b925050604061205786828701611f90565b9150509250925092565b600080600080600060a0868803121561207957600080fd5b60006120858888611d42565b955050602061209688828901611d42565b94505060406120a788828901611f90565b93505060606120b888828901611f90565b92505060806120c988828901611f90565b9150509295509295909350565b600080604083850312156120e957600080fd5b60006120f58585611d42565b925050602061200a85828601611f90565b6000806040838503121561211957600080fd5b825167ffffffffffffffff81111561213057600080fd5b61213c85828601611e49565b925050602083015167ffffffffffffffff81111561215957600080fd5b61200a85828601611e49565b60006020828403121561217757600080fd5b6000611fd28484611eb9565b60006020828403121561219557600080fd5b815167ffffffffffffffff8111156121ac57600080fd5b611fd284828501611ec5565b6000602082840312156121ca57600080fd5b6000611fd28484611f90565b6000602082840312156121e857600080fd5b6000611fd28484611f9c565b6000806040838503121561220757600080fd5b60006122138585611f9c565b925050602061200a85828601611f9c565b60006020828403121561223657600080fd5b6000611fd28484611fa8565b600061224e8383612271565b505060200190565b600061224e838361288d565b61226b81612d3d565b82525050565b61226b81612d0f565b600061228582612cf8565b61228f8185612d06565b935061229a83612ce6565b60005b828110156122c5576122b0868351612242565b95506122bb82612ce6565b915060010161229d565b5093949350505050565b60006122da82612cfc565b6122e48185612d06565b93506122ef83612cec565b60005b828110156122c55761230c8661230784612db0565b612242565b955061231782612d00565b91506001016122f2565b600061232c82612cf8565b6123368185612d06565b935061234183612ce6565b60005b828110156122c557612357868351612256565b955061236282612ce6565b9150600101612344565b600061237782612cfc565b6123818185612d06565b935061238c83612cec565b60005b828110156122c5576123a9866123a484612dbc565b612256565b95506123b482612d00565b915060010161238f565b61226b81612d1a565b61226b81612d48565b60006123db82612cf8565b6123e58185612d06565b93506123f5818560208601612d5e565b6123fe81612dc8565b9093019392505050565b6000612415602d83612d06565b7f526562616c616e63696e67536574546f6b656e2e6275726e3a2053656e64657281527f206d75737420626520636f726500000000000000000000000000000000000000602082015260400192915050565b6000612474603a83612d06565b7f526562616c616e63696e67536574546f6b656e2e7365744d616e616765723a2081527f53656e646572206d75737420626520746865206d616e61676572000000000000602082015260400192915050565b60006124d3603683612d06565b7f526562616c616e63696e67536574546f6b656e2e6d696e743a2043616e6e6f7481527f206d696e7420647572696e6720526562616c616e636500000000000000000000602082015260400192915050565b6000612532603583612d06565b7f526562616c616e63696e67536574546f6b656e2e6d696e743a2043616e6e6f7481527f206d696e7420647572696e672044726177646f776e0000000000000000000000602082015260400192915050565b6000612591602d83612d06565b7f526562616c616e63696e67536574546f6b656e2e6d696e743a2053656e64657281527f206d75737420626520636f726500000000000000000000000000000000000000602082015260400192915050565b60006125f0603683612d06565b7f526562616c616e63696e67536574546f6b656e2e6275726e3a2043616e6e6f7481527f206275726e20647572696e6720526562616c616e636500000000000000000000602082015260400192915050565b600061264f604083612d06565b7f526562616c616e63696e67536574546f6b656e2e6275726e3a2053657420636181527f6e6e6f742062652072656465656d656420647572696e672044726177646f776e602082015260400192915050565b805160808301906126b2848261288d565b5060208201516126c5602085018261288d565b5060408201516126d8604085018261288d565b5060608201516126eb606085018261288d565b50505050565b8054608083019061270181612d9d565b61270b858261288d565b5050600182015461271b81612d9d565b612728602086018261288d565b5050600282015461273881612d9d565b612745604086018261288d565b5050600382015461275581612d9d565b612762606086018261288d565b5050505050565b805460009060a084019061277c81612d9d565b612786868261288d565b5050600183015461279681612d9d565b6127a3602087018261288d565b506002840185830360408701526127ba838261236c565b9250506003840185830360608701526127d3838261236c565b9250506004840185830360808701526127ec83826122cf565b9695505050505050565b80516101008301906128088482612271565b50602082015161281b6020850182612271565b50604082015161282e6040850182612271565b5060608201516128416060850182612271565b5060808201516128546080850182612271565b5060a082015161286760a085018261288d565b5060c082015161287a60c085018261288d565b5060e08201516126eb60e0850182612896565b61226b816105e8565b61226b81612d37565b602081016106928284612271565b602081016106928284612262565b604081016128c98285612271565b6107306020830184612271565b60a081016128e48288612271565b6128f16020830187612271565b6128fe6040830186612271565b61290b6060830185612271565b6127ec6080830184612271565b6101c081016129278287612271565b6129346020830186612271565b61294160408301856127f6565b61294f6101408301846126a1565b95945050505050565b60208082528101610730818461227a565b6060808252810161297a818661227a565b9050818103602083015261298e8185612321565b9050818103604083015261294f8184612321565b602080825281016107308184612321565b604080825281016129c48185612321565b90508181036020830152611fd28184612321565b6020810161069282846123be565b6020810161069282846123c7565b6020808252810161073081846123d0565b6020808252810161069281612408565b6020808252810161069281612467565b60208082528101610692816124c6565b6020808252810161069281612525565b6020808252810161069281612584565b60208082528101610692816125e3565b6020808252810161069281612642565b60208101610692828461288d565b60608101612a91828661288d565b612a9e6020830185612271565b818103604083015261294f8184612769565b6101008101612abf828861288d565b612acc6020830187612271565b8181036040830152612ade8186612769565b9050612aed60608301856126f1565b6127ec60e0830184612896565b60408101612b08828561288d565b610730602083018461288d565b60808101612b23828761288d565b612b30602083018661288d565b612b3d6040830185612271565b61294f6060830184612271565b6101408101612b59828a61288d565b612b66602083018961288d565b612b736040830188612271565b612b806060830187612271565b612b8d60808301866126f1565b818103610100830152612ba08185612769565b9050612bb0610120830184612896565b98975050505050505050565b60808101612bca828761288d565b612bd7602083018661288d565b612be4604083018561288d565b61294f606083018461288d565b6101008101612c00828b61288d565b612c0d602083018a61288d565b612c1a604083018961288d565b612c27606083018861288d565b612c346080830187612271565b612c4160a0830186612271565b612c4e60c0830185612271565b612c5b60e0830184612896565b9998505050505050505050565b60608101612c76828661288d565b612c83602083018561288d565b611fd26040830184612896565b602081016106928284612896565b60405181810167ffffffffffffffff81118282101715612cbd57600080fd5b604052919050565b600067ffffffffffffffff821115612cdc57600080fd5b5060209081020190565b60200190565b60009081526020902090565b5190565b5490565b60010190565b90815260200190565b600061069282612d2b565b151590565b600060048210611bb857fe5b600160a060020a031690565b60ff1690565b600061069282612d53565b600061069282612d1f565b600061069282612d0f565b60005b83811015612d79578181015183820152602001612d61565b838111156126eb5750506000910152565b6000610692612d98836105e8565b612d2b565b6000610692612dab836105e8565b6105e8565b60006106928254612d8a565b60006106928254612d9d565b601f01601f19169056fea265627a7a723058202bbac5ffc9e275d60b7960627099bd2842502594fa837be06c87496fe14bbbf86c6578706572696d656e74616cf50037526562616c616e63696e67536574546f6b656e2e636f6e7374727563746f723a00000000000000000000000015518cdd49d83471e9f85cdcfbd72c8e2a78dde20000000000000000000000009d622389970120c38fa491b6d1ca5328237889e5000000000000000000000000d14d4e7eb9b36ae1ac0efd5e0833bf517eafd91c000000000000000000000000000000000000000000000000000000000008893500000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054600000000000000000000000000c6449473be76ab2a70329fa66cbe504a2500533800000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000001845544820353020534d412043726f73736f766572205365740000000000000000000000000000000000000000000000000000000000000000000000000000000a4554483530534d41434f00000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102bf5760003560e060020a9004806395d89b4111610186578063c45a0155116100ed578063f0284b1c116100a6578063f75af97f11610080578063f75af97f14610572578063fa2d8c9014610587578063fbfa77cf1461058f578063fccde48f14610597576102bf565b8063f0284b1c1461055a578063f056a9ae14610562578063f2f4eb261461056a576102bf565b8063c45a015514610504578063cb6316991461050c578063cdb026a114610514578063d0ebdbe71461051c578063d600ae481461052f578063dd62ed3e14610547576102bf565b8063a065172b1161013f578063a065172b146104be578063a2e59c91146104c6578063a457c2d7146104ce578063a9059cbb146104e1578063a9faafd9146104f4578063b83d8157146104fc576102bf565b806395d89b411461045057806396213fc7146104585780639979ef451461046057806399d50d5d146104825780639b013aee1461048a5780639dc29fac146104ab576102bf565b8063395093511161022a578063570f3167116101e3578063570f3167146103ef57806357d3810e146103f757806370a082311461040d57806375aff3c1146104205780637632b24b146104285780638618711c1461043b576102bf565b806339509351146103a757806340c10f19146103ba57806342a7cfd5146103cf5780634394380b146103d7578063481c6a75146103df5780634dce7057146103e7576102bf565b806318160ddd1161027c57806318160ddd1461035457806318c53aca1461035c57806323b872dd1461036f5780632c103c791461038257806330b866271461038a578063313ce56714610392576102bf565b80630193aea2146102c4578063027aa9f5146102e257806306fdde03146102f7578063095ea7b31461030c5780630ca60f861461032c57806316d1d9161461034c575b600080fd5b6102cc61059f565b6040516102d99190612a75565b60405180910390f35b6102ea6105a5565b6040516102d991906129a2565b6102ff6105eb565b6040516102d991906129f4565b61031f61031a3660046120d6565b610681565b6040516102d991906129d8565b61033f61033a3660046121b8565b610698565b6040516102d9919061289f565b6102cc6106bf565b6102cc6106c5565b61031f61036a366004611fb4565b6106cb565b61031f61037d366004612014565b6106df565b6102cc610737565b61033f61073d565b61039a61074c565b6040516102d99190612c90565b61031f6103b53660046120d6565b610755565b6103cd6103c83660046120d6565b610791565b005b6102cc610850565b6102cc610856565b61033f61085c565b6103cd61086b565b6102cc610ab0565b6103ff610ab6565b6040516102d9929190612afa565b6102cc61041b366004611fb4565b610abf565b6103cd610ada565b6103cd610436366004612061565b610cbc565b610443610ecd565b6040516102d99190612958565b6102ff610f31565b61033f610f92565b61047361046e3660046121b8565b610fa1565b6040516102d993929190612969565b6104436110f2565b61049d6104983660046121b8565b61114e565b6040516102d99291906129b3565b6103cd6104b93660046120d6565b61121c565b6102ea611370565b6102ea611406565b61031f6104dc3660046120d6565b61145c565b61031f6104ef3660046120d6565b611498565b6102cc6114a5565b6102cc6114ab565b61033f6114b1565b61033f6114c0565b6102ea6114cf565b6103cd61052a366004611fb4565b611529565b6105376115ca565b6040516102d99493929190612bbc565b6102cc610555366004611fda565b6115d9565b610443611604565b6102ea611664565b61033f6116bd565b61057a6116d1565b6040516102d991906129e6565b6103cd6116e1565b61033f61181a565b61033f611829565b600f5481565b60408051600180825281830190925260609182919060208083019080388339019050509050600f54816000815181106105da57fe5b602090810291909101015290505b90565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106775780601f1061064c57610100808354040283529160200191610677565b820191906000526020600020905b81548152906001019060200180831161065a57829003601f168201915b5050505050905090565b600061068e338484611838565b5060015b92915050565b602081815481106106a557fe5b600091825260209091200154600160a060020a0316905081565b60125481565b60025490565b600e54600160a060020a0390811691161490565b60006106ec8484846118c6565b600160a060020a03841660009081526001602090815260408083203380855292529091205461072c918691610727908663ffffffff61198916565b611838565b5060015b9392505050565b60115481565b600e54600160a060020a031681565b60055460ff1690565b336000818152600160209081526040808320600160a060020a0387168452909152812054909161068e918590610727908663ffffffff61199e16565b6005546101009004600160a060020a031633146107cc5760405160e560020a62461bcd0281526004016107c390612a45565b60405180910390fd5b6002600d5460a060020a900460ff1660038111156107e657fe5b14156108075760405160e560020a62461bcd0281526004016107c390612a25565b6003600d5460a060020a900460ff16600381111561082157fe5b14156108425760405160e560020a62461bcd0281526004016107c390612a35565b61084c82826119b0565b5050565b600c5481565b60165481565b600d54600160a060020a031681565b73b2d113cd923b763bd4f2187233257da57f3f1ddb638f1880c4601354601154600d60149054906101000a900460ff1660038111156108a657fe5b6040518463ffffffff1660e060020a0281526004016108c793929190612c68565b60006040518083038186803b1580156108df57600080fd5b505af41580156108f3573d6000803e3d6000fd5b5050600e546014546015546005546007546040517fa569cda100000000000000000000000000000000000000000000000000000000815273b2d113cd923b763bd4f2187233257da57f3f1ddb975063a569cda1965061097095600160a060020a0390811695811694811693610100900481169216906004016128d6565b60006040518083038186803b15801561098857600080fd5b505af415801561099c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109c49190810190612183565b8051601b908155602080830151601c55604083015180516109e992601d920190611b71565b5060608201518051610a05916003840191602090910190611b71565b5060808201518051610a21916004840191602090910190611bbc565b5050601c546016555042601755600d805474ff0000000000000000000000000000000000000000191674020000000000000000000000000000000000000000179055600e546014546040517fe57340a36ab2ae0bdbec3486f504d5df3a525cd11937e20641f2c64ca126f1c192610aa692600160a060020a03918216929116906128bb565b60405180910390a1565b601f5490565b601b54601c5482565b600160a060020a031660009081526020819052604090205490565b600073c0aafee4b4edc54dd3aea0bf4dbe7bddde6365ca63495c23bd610afe6106c5565b600c5460145460075460405160e060020a63ffffffff8716028152610b35949392600160a060020a03908116921690600401612b15565b604080518083038186803b158015610b4c57600080fd5b505af4158015610b60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b8491908101906121f4565b601654600e54600554600d549395506000945073a2619134b0851744d6e5052392400df73b24d7fc93631ab90ff993928792600160a060020a039182169261010090910490911690601790601b9060a060020a900460ff166003811115610be757fe5b6040518863ffffffff1660e060020a028152600401610c0c9796959493929190612b4a565b60206040518083038186803b158015610c2457600080fd5b505af4158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c5c9190810190612224565b90508060ff166003811115610c6d57fe5b600d805474ff0000000000000000000000000000000000000000191660a060020a836003811115610c9a57fe5b021790555042601055601f8054610cb391602091611c2a565b5061084c611a5d565b610cc4611c6a565b604051806080016040528060008152602001858152602001848152602001838152509050610cf0611c92565b604080516101008082018352600d54600160a060020a038082168452600e5481166020850152600554929092048216938301939093526008548116606083015260065416608082015260105460a082015260125460c08201529060e082019060a060020a900460ff166003811115610d6457fe5b60ff1690526040517f56ca7aa200000000000000000000000000000000000000000000000000000000815290915073dd5825965a016d8bbbbdf4862a1ac9d3fb6d5382906356ca7aa290610dc2908a908a9086908890600401612918565b60006040518083038186803b158015610dda57600080fd5b505af4158015610dee573d6000803e3d6000fd5b505083516017555050602082015160185560408201516019556060820151601a5560148054600160a060020a0389811673ffffffffffffffffffffffffffffffffffffffff19928316179092556015805492891692909116919091179055426013819055600d805474ff0000000000000000000000000000000000000000191660a060020a179055601154610e83919061199e565b86600160a060020a03167f6a20b1a24d612c34a3b539bd9f3cc66319e62c01bafbc9fc9f5362e2bfbacb3c89604051610ebc919061289f565b60405180910390a350505050505050565b6060601b60040180548060200260200160405190810160405280929190818152602001828054801561067757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610f0a575050505050905090565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106775780601f1061064c57610100808354040283529160200191610677565b601554600160a060020a031681565b6005546040517f773d40cc00000000000000000000000000000000000000000000000000000000815260609182918291734689051f4246630deb7c1c4cfb2ffa25643d886c9163773d40cc9161100d9188916101009004600160a060020a031690601b90600401612a83565b60206040518083038186803b15801561102557600080fd5b505af4158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061105d91908101906121d6565b5060608061106a8661114e565b601c549193509150611082908763ffffffff61198916565b601c55601f805460408051602080840282018101909252828152859285928591908301828280156110dc57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116110be575b5050505050925094509450945050509193909250565b604080516001808252818301909252606091829190602080830190803883395050600e548251929350600160a060020a03169183915060009061113157fe5b600160a060020a0390921660209283029190910190910152905090565b601554600d546060918291734689051f4246630deb7c1c4cfb2ffa25643d886c91635a6bff16918691600160a060020a031690601b9060179060a060020a900460ff16600381111561119c57fe5b6040518663ffffffff1660e060020a0281526004016111bf959493929190612ab0565b60006040518083038186803b1580156111d757600080fd5b505af41580156111eb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112139190810190612106565b91509150915091565b6002600d5460a060020a900460ff16600381111561123657fe5b14156112575760405160e560020a62461bcd0281526004016107c390612a55565b6003600d5460a060020a900460ff16600381111561127157fe5b1415611334576009546040517f5e633498000000000000000000000000000000000000000000000000000000008152600160a060020a0390911690635e633498906112c09033906004016128ad565b60206040518083038186803b1580156112d857600080fd5b505afa1580156112ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113109190810190612165565b61132f5760405160e560020a62461bcd0281526004016107c390612a65565b611366565b6005546101009004600160a060020a031633146113665760405160e560020a62461bcd0281526004016107c390612a05565b61084c8282611ad3565b60408051600480825260a0820190925260609182919060208201608080388339019050509050601760000154816000815181106113a957fe5b602002602001018181525050601760010154816001815181106113c857fe5b602002602001018181525050601760020154816002815181106113e757fe5b602002602001018181525050601760030154816003815181106105da57fe5b604080516002808252606080830184529283929190602083019080388339019050509050601b600001548160008151811061143d57fe5b602002602001018181525050601b60010154816001815181106105da57fe5b336000818152600160209081526040808320600160a060020a0387168452909152812054909161068e918590610727908663ffffffff61198916565b600061068e3384846118c6565b60135481565b60105481565b600654600160a060020a031681565b601454600160a060020a031681565b6060601b60030180548060200260200160405190810160405280929190818152602001828054801561067757602002820191906000526020600020905b81548152602001906001019080831161150c575050505050905090565b600d54600160a060020a031633146115565760405160e560020a62461bcd0281526004016107c390612a15565b600d546040517ff9c15f5b74b4e002e8881b2d9810116b1d4d45461e6dd7ac8111381b592e2c6591611593918491600160a060020a0316906128bb565b60405180910390a1600d805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b601754601854601954601a5484565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6060602080548060200260200160405190810160405280929190818152602001828054801561067757602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610f0a575050505050905090565b6060601b600201805480602002602001604051908101604052809291908181526020018280548015610677576020028201919060005260206000209081548152602001906001019080831161150c575050505050905090565b6005546101009004600160a060020a031681565b600d5460a060020a900460ff1681565b73c0aafee4b4edc54dd3aea0bf4dbe7bddde6365ca63084f9bce6117036106c5565b601c54601b54600c54601454600554600754600d54600160a060020a03938416936101009093048316929091169060a060020a900460ff16600381111561174657fe5b6040518963ffffffff1660e060020a02815260040161176c989796959493929190612bf1565b60206040518083038186803b15801561178457600080fd5b505af4158015611798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117bc91908101906121d6565b600f55601454600e805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0390921691909117905542601055600d805474ff000000000000000000000000000000000000000019169055611818611a5d565b565b600754600160a060020a031681565b600854600160a060020a031681565b600160a060020a03821661184b57600080fd5b600160a060020a03831661185e57600080fd5b600160a060020a0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906118b9908590612a75565b60405180910390a3505050565b600160a060020a0382166118d957600080fd5b600160a060020a038316600090815260208190526040902054611902908263ffffffff61198916565b600160a060020a038085166000908152602081905260408082209390935590841681522054611937908263ffffffff61199e16565b600160a060020a0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906118b9908590612a75565b60008282111561199857600080fd5b50900390565b60008282018381101561073057600080fd5b600160a060020a0382166119c357600080fd5b6002546119d6908263ffffffff61199e16565b600255600160a060020a038216600090815260208190526040902054611a02908263ffffffff61199e16565b600160a060020a0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a51908590612a75565b60405180910390a35050565b6014805473ffffffffffffffffffffffffffffffffffffffff1990811690915560158054909116905560006016819055601781905560188190556019819055601a819055601b818155601c82905590611ab7601d82611cd6565b611ac5600383016000611cd6565b61084c600483016000611cd6565b600160a060020a038216611ae657600080fd5b600254611af9908263ffffffff61198916565b600255600160a060020a038216600090815260208190526040902054611b25908263ffffffff61198916565b600160a060020a0383166000818152602081905260408082209390935591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a51908590612a75565b828054828255906000526020600020908101928215611bac579160200282015b82811115611bac578251825591602001919060010190611b91565b50611bb8929150611cf7565b5090565b828054828255906000526020600020908101928215611c1e579160200282015b82811115611c1e578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190611bdc565b50611bb8929150611d11565b828054828255906000526020600020908101928215611c1e5760005260206000209182015b82811115611c1e578254825591600101919060010190611c4f565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b5080546000825590600052602060002090810190611cf49190611cf7565b50565b6105e891905b80821115611bb85760008155600101611cfd565b6105e891905b80821115611bb857805473ffffffffffffffffffffffffffffffffffffffff19168155600101611d17565b60006107308235612d0f565b60006107308251612d0f565b600082601f830112611d6b57600080fd5b8151611d7e611d7982612cc5565b612c9e565b91508181835260208401935060208101905083856020840282011115611da357600080fd5b60005b83811015611dcf5781611db98882611d4e565b8452506020928301929190910190600101611da6565b5050505092915050565b600082601f830112611dea57600080fd5b8151611df8611d7982612cc5565b91508181835260208401935060208101905083856020840282011115611e1d57600080fd5b60005b83811015611dcf5781611e338882611f9c565b8452506020928301929190910190600101611e20565b600082601f830112611e5a57600080fd5b8151611e68611d7982612cc5565b91508181835260208401935060208101905083856020840282011115611e8d57600080fd5b60005b83811015611dcf5781611ea38882611f9c565b8452506020928301929190910190600101611e90565b60006107308251612d1a565b600060a08284031215611ed757600080fd5b611ee160a0612c9e565b90506000611eef8484611f9c565b8252506020611f0084848301611f9c565b602083015250604082015167ffffffffffffffff811115611f2057600080fd5b611f2c84828501611dd9565b604083015250606082015167ffffffffffffffff811115611f4c57600080fd5b611f5884828501611dd9565b606083015250608082015167ffffffffffffffff811115611f7857600080fd5b611f8484828501611d5a565b60808301525092915050565b600061073082356105e8565b600061073082516105e8565b60006107308251612d37565b600060208284031215611fc657600080fd5b6000611fd28484611d42565b949350505050565b60008060408385031215611fed57600080fd5b6000611ff98585611d42565b925050602061200a85828601611d42565b9150509250929050565b60008060006060848603121561202957600080fd5b60006120358686611d42565b935050602061204686828701611d42565b925050604061205786828701611f90565b9150509250925092565b600080600080600060a0868803121561207957600080fd5b60006120858888611d42565b955050602061209688828901611d42565b94505060406120a788828901611f90565b93505060606120b888828901611f90565b92505060806120c988828901611f90565b9150509295509295909350565b600080604083850312156120e957600080fd5b60006120f58585611d42565b925050602061200a85828601611f90565b6000806040838503121561211957600080fd5b825167ffffffffffffffff81111561213057600080fd5b61213c85828601611e49565b925050602083015167ffffffffffffffff81111561215957600080fd5b61200a85828601611e49565b60006020828403121561217757600080fd5b6000611fd28484611eb9565b60006020828403121561219557600080fd5b815167ffffffffffffffff8111156121ac57600080fd5b611fd284828501611ec5565b6000602082840312156121ca57600080fd5b6000611fd28484611f90565b6000602082840312156121e857600080fd5b6000611fd28484611f9c565b6000806040838503121561220757600080fd5b60006122138585611f9c565b925050602061200a85828601611f9c565b60006020828403121561223657600080fd5b6000611fd28484611fa8565b600061224e8383612271565b505060200190565b600061224e838361288d565b61226b81612d3d565b82525050565b61226b81612d0f565b600061228582612cf8565b61228f8185612d06565b935061229a83612ce6565b60005b828110156122c5576122b0868351612242565b95506122bb82612ce6565b915060010161229d565b5093949350505050565b60006122da82612cfc565b6122e48185612d06565b93506122ef83612cec565b60005b828110156122c55761230c8661230784612db0565b612242565b955061231782612d00565b91506001016122f2565b600061232c82612cf8565b6123368185612d06565b935061234183612ce6565b60005b828110156122c557612357868351612256565b955061236282612ce6565b9150600101612344565b600061237782612cfc565b6123818185612d06565b935061238c83612cec565b60005b828110156122c5576123a9866123a484612dbc565b612256565b95506123b482612d00565b915060010161238f565b61226b81612d1a565b61226b81612d48565b60006123db82612cf8565b6123e58185612d06565b93506123f5818560208601612d5e565b6123fe81612dc8565b9093019392505050565b6000612415602d83612d06565b7f526562616c616e63696e67536574546f6b656e2e6275726e3a2053656e64657281527f206d75737420626520636f726500000000000000000000000000000000000000602082015260400192915050565b6000612474603a83612d06565b7f526562616c616e63696e67536574546f6b656e2e7365744d616e616765723a2081527f53656e646572206d75737420626520746865206d616e61676572000000000000602082015260400192915050565b60006124d3603683612d06565b7f526562616c616e63696e67536574546f6b656e2e6d696e743a2043616e6e6f7481527f206d696e7420647572696e6720526562616c616e636500000000000000000000602082015260400192915050565b6000612532603583612d06565b7f526562616c616e63696e67536574546f6b656e2e6d696e743a2043616e6e6f7481527f206d696e7420647572696e672044726177646f776e0000000000000000000000602082015260400192915050565b6000612591602d83612d06565b7f526562616c616e63696e67536574546f6b656e2e6d696e743a2053656e64657281527f206d75737420626520636f726500000000000000000000000000000000000000602082015260400192915050565b60006125f0603683612d06565b7f526562616c616e63696e67536574546f6b656e2e6275726e3a2043616e6e6f7481527f206275726e20647572696e6720526562616c616e636500000000000000000000602082015260400192915050565b600061264f604083612d06565b7f526562616c616e63696e67536574546f6b656e2e6275726e3a2053657420636181527f6e6e6f742062652072656465656d656420647572696e672044726177646f776e602082015260400192915050565b805160808301906126b2848261288d565b5060208201516126c5602085018261288d565b5060408201516126d8604085018261288d565b5060608201516126eb606085018261288d565b50505050565b8054608083019061270181612d9d565b61270b858261288d565b5050600182015461271b81612d9d565b612728602086018261288d565b5050600282015461273881612d9d565b612745604086018261288d565b5050600382015461275581612d9d565b612762606086018261288d565b5050505050565b805460009060a084019061277c81612d9d565b612786868261288d565b5050600183015461279681612d9d565b6127a3602087018261288d565b506002840185830360408701526127ba838261236c565b9250506003840185830360608701526127d3838261236c565b9250506004840185830360808701526127ec83826122cf565b9695505050505050565b80516101008301906128088482612271565b50602082015161281b6020850182612271565b50604082015161282e6040850182612271565b5060608201516128416060850182612271565b5060808201516128546080850182612271565b5060a082015161286760a085018261288d565b5060c082015161287a60c085018261288d565b5060e08201516126eb60e0850182612896565b61226b816105e8565b61226b81612d37565b602081016106928284612271565b602081016106928284612262565b604081016128c98285612271565b6107306020830184612271565b60a081016128e48288612271565b6128f16020830187612271565b6128fe6040830186612271565b61290b6060830185612271565b6127ec6080830184612271565b6101c081016129278287612271565b6129346020830186612271565b61294160408301856127f6565b61294f6101408301846126a1565b95945050505050565b60208082528101610730818461227a565b6060808252810161297a818661227a565b9050818103602083015261298e8185612321565b9050818103604083015261294f8184612321565b602080825281016107308184612321565b604080825281016129c48185612321565b90508181036020830152611fd28184612321565b6020810161069282846123be565b6020810161069282846123c7565b6020808252810161073081846123d0565b6020808252810161069281612408565b6020808252810161069281612467565b60208082528101610692816124c6565b6020808252810161069281612525565b6020808252810161069281612584565b60208082528101610692816125e3565b6020808252810161069281612642565b60208101610692828461288d565b60608101612a91828661288d565b612a9e6020830185612271565b818103604083015261294f8184612769565b6101008101612abf828861288d565b612acc6020830187612271565b8181036040830152612ade8186612769565b9050612aed60608301856126f1565b6127ec60e0830184612896565b60408101612b08828561288d565b610730602083018461288d565b60808101612b23828761288d565b612b30602083018661288d565b612b3d6040830185612271565b61294f6060830184612271565b6101408101612b59828a61288d565b612b66602083018961288d565b612b736040830188612271565b612b806060830187612271565b612b8d60808301866126f1565b818103610100830152612ba08185612769565b9050612bb0610120830184612896565b98975050505050505050565b60808101612bca828761288d565b612bd7602083018661288d565b612be4604083018561288d565b61294f606083018461288d565b6101008101612c00828b61288d565b612c0d602083018a61288d565b612c1a604083018961288d565b612c27606083018861288d565b612c346080830187612271565b612c4160a0830186612271565b612c4e60c0830185612271565b612c5b60e0830184612896565b9998505050505050505050565b60608101612c76828661288d565b612c83602083018561288d565b611fd26040830184612896565b602081016106928284612896565b60405181810167ffffffffffffffff81118282101715612cbd57600080fd5b604052919050565b600067ffffffffffffffff821115612cdc57600080fd5b5060209081020190565b60200190565b60009081526020902090565b5190565b5490565b60010190565b90815260200190565b600061069282612d2b565b151590565b600060048210611bb857fe5b600160a060020a031690565b60ff1690565b600061069282612d53565b600061069282612d1f565b600061069282612d0f565b60005b83811015612d79578181015183820152602001612d61565b838111156126eb5750506000910152565b6000610692612d98836105e8565b612d2b565b6000610692612dab836105e8565b6105e8565b60006106928254612d8a565b60006106928254612d9d565b601f01601f19169056fea265627a7a723058202bbac5ffc9e275d60b7960627099bd2842502594fa837be06c87496fe14bbbf86c6578706572696d656e74616cf50037
Libraries Used
FailAuctionLibrary : 0xa2619134b0851744d6e5052392400df73b24d7fcUnverifiedPlaceBidLibrary : 0x4689051f4246630deb7c1c4cfb2ffa25643d886cUnverifiedProposeLibrary : 0xdd5825965a016d8bbbbdf4862a1ac9d3fb6d5382UnverifiedSettleRebalanceLibrary : 0xc0aafee4b4edc54dd3aea0bf4dbe7bddde6365caUnverifiedStartRebalanceLibrary : 0xb2d113cd923b763bd4f2187233257da57f3f1ddbUnverified
Deployed Bytecode Sourcemap
103840:20044:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;103840:20044:0;;;;;;;;-1:-1:-1;;;103840:20044:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104509:25;;;:::i;:::-;;;;;;;;;;;;;;;;120186:208;;;:::i;:::-;;;;;;;;11432:83;;;:::i;:::-;;;;;;;;5680:148;;;;;;;;;:::i;:::-;;;;;;;;105138:48;;;;;;;;;:::i;:::-;;;;;;;;104663:32;;;:::i;3833:91::-;;;:::i;121813:179::-;;;;;;;;;:::i;6301:228::-;;;;;;;;;:::i;104627:29::-;;;:::i;104477:25::-;;;:::i;11748:83::-;;;:::i;:::-;;;;;;;;7055:203;;;;;;;;;:::i;117046:804::-;;;;;;;;;:::i;:::-;;104316:26;;;:::i;104892:39::-;;;:::i;104349:22::-;;;:::i;111634:864::-;;;:::i;122111:172::-;;;:::i;105016:61::-;;;:::i;:::-;;;;;;;;;4143:106;;;;;;;;;:::i;114832:1167::-;;;:::i;109624:1873::-;;;;;;;;;:::i;122402:168::-;;;:::i;:::-;;;;;;;;11582:87;;;:::i;104856:29::-;;;:::i;113751:870::-;;;;;;;;;:::i;:::-;;;;;;;;;;119830:228;;;:::i;116424:367::-;;;;;;;;;:::i;:::-;;;;;;;;;118113:1048;;;;;;;;;:::i;121031:489::-;;;:::i;120545:330::-;;;:::i;7789:213::-;;;;;;;;;:::i;4893:140::-;;;;;;;;;:::i;104743:32::-;;;:::i;104541:37::-;;;:::i;104056:22::-;;;:::i;104827:::-;;;:::i;122988:172::-;;;:::i;119299:315::-;;;;;;;;;:::i;104938:71::-;;;:::i;:::-;;;;;;;;;;;4588:131;;;;;;;;;:::i;123305:176::-;;;:::i;122693:172::-;;;:::i;104030:19::-;;;:::i;104378:46::-;;;:::i;:::-;;;;;;;;112638:646;;;:::i;104085:20::-;;;:::i;104112:40::-;;;:::i;104509:25::-;;;;:::o;120186:208::-;120315:16;;;120329:1;120315:16;;;;;;;;;120256;;;;120315;;;;;;;105:10:-1;120315:16:0;88:34:-1;136:17;;-1:-1;120315:16:0;120290:41;;120353:10;;120342:5;120348:1;120342:8;;;;;;;;;;;;;;;;;:21;120381:5;-1:-1:-1;120186:208:0;;:::o;11432:83::-;11502:5;11495:12;;;;;;;;-1:-1:-1;;11495:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11469:13;;11495:12;;11502:5;;11495:12;;11502:5;11495:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11432:83;:::o;5680:148::-;5745:4;5762:36;5771:10;5783:7;5792:5;5762:8;:36::i;:::-;-1:-1:-1;5816:4:0;5680:148;;;;;:::o;105138:48::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;105138:48:0;;-1:-1:-1;105138:48:0;:::o;104663:32::-;;;;:::o;3833:91::-;3904:12;;3833:91;:::o;121813:179::-;121974:10;;-1:-1:-1;;;;;121974:10:0;;;121957:27;;;;121813:179::o;6301:228::-;6380:4;6397:26;6407:4;6413:2;6417:5;6397:9;:26::i;:::-;-1:-1:-1;;;;;6461:14:0;;;;;;:8;:14;;;;;;;;6449:10;6461:26;;;;;;;;;6434:65;;6443:4;;6461:37;;6492:5;6461:37;:30;:37;:::i;:::-;6434:8;:65::i;:::-;-1:-1:-1;6517:4:0;6301:228;;;;;;:::o;104627:29::-;;;;:::o;104477:25::-;;;-1:-1:-1;;;;;104477:25:0;;:::o;11748:83::-;11814:9;;;;11748:83;:::o;7055:203::-;7161:10;7135:4;7182:20;;;:8;:20;;;;;;;;-1:-1:-1;;;;;7182:29:0;;;;;;;;;;7135:4;;7152:76;;7173:7;;7182:45;;7216:10;7182:45;:33;:45;:::i;117046:804::-;117238:4;;;;;-1:-1:-1;;;;;117238:4:0;117224:10;:18;117202:113;;;;-1:-1:-1;;;;;117202:113:0;;;;;;;;;;;;;;;;;117421:34;117403:14;;-1:-1:-1;;;117403:14:0;;;;:52;;;;;;;;;;117381:156;;;;-1:-1:-1;;;;;117381:156:0;;;;;;;;;117642:33;117624:14;;-1:-1:-1;;;117624:14:0;;;;:51;;;;;;;;;;117602:154;;;;-1:-1:-1;;;;;117602:154:0;;;;;;;;;117817:25;117823:7;117832:9;117817:5;:25::i;:::-;117046:804;;:::o;104316:26::-;;;;:::o;104892:39::-;;;;:::o;104349:22::-;;;-1:-1:-1;;;;;104349:22:0;;:::o;111634:864::-;111760:21;:44;111819:17;;111851:14;;111886;;;;;;;;;;;111880:21;;;;;;;;111760:152;;;;;-1:-1:-1;;;111760:152:0;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111760:152:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;112080:10:0;;112105:7;;112127:14;;112156:4;;112175:5;;112004:187;;;;;:21;;-1:-1:-1;112004:61:0;;-1:-1:-1;112004:187:0;;-1:-1:-1;;;;;112080:10:0;;;;112105:7;;;112127:14;;;112080:10;112156:4;;;;;112175:5;;112004:187;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;112004:187:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;112004:187:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;112004:187:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;112004:187:0;;;;;;;;;111984:207;;:17;:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;111984:207:0;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;111984:207:0;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;112267:38:0;;112240:24;:65;-1:-1:-1;112358:15:0;112316:22;:57;112384:14;:51;;-1:-1:-1;;112384:51:0;;;;;112470:10;;112482:7;;112453:37;;;;;;-1:-1:-1;;;;;112470:10:0;;;;112482:7;;;112453:37;;;;;;;;;;111634:864::o;122111:172::-;122232:36;:43;122111:172;:::o;105016:61::-;;;;;;:::o;4143:106::-;-1:-1:-1;;;;;4225:16:0;4198:7;4225:16;;;;;;;;;;;;4143:106::o;114832:1167::-;114894:28;114997:22;:52;115064:13;:11;:13::i;:::-;115092:11;;115118:7;;115140:5;;114997:159;;-1:-1:-1;;;114997:159:0;;;;;;;;;115092:11;-1:-1:-1;;;;;115118:7:0;;;;115140:5;;114997:159;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;114997:159:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114997:159: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;114997:159:0;;;;;;;;;115375:24;;115449:10;;115474:4;;115568:14;;114933:223;;-1:-1:-1;115295:27:0;;-1:-1:-1;115325:18:0;;:35;;115375:24;114933:223;;-1:-1:-1;;;;;115449:10:0;;;;;115474:4;;;;;;;115493:22;;115530:17;;-1:-1:-1;;;115568:14:0;;;;115562:21;;;;;;;;115325:269;;;;;-1:-1:-1;;;115325:269:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115325:269:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;115325:269: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;115325:269:0;;;;;;;;;115295:299;;115647:21;115622:47;;;;;;;;;;115605:14;:64;;-1:-1:-1;;115605:64:0;-1:-1:-1;;;115605:64:0;;;;;;;;;;;;;-1:-1:-1;115755:15:0;115730:22;:40;115891:36;115857:70;;;;:31;;:70;:::i;:::-;;115972:19;:17;:19::i;109624:1873::-;109905:67;;:::i;:::-;109988:266;;;;;;;;110237:1;109988:266;;;;110069:19;109988:266;;;;110126:18;109988:266;;;;110182:18;109988:266;;;109905:349;;110311:53;;:::i;:::-;110380:441;;;;;;;;;110439:7;;-1:-1:-1;;;;;110439:7:0;;;110380:441;;110477:10;;;;110380:441;;;;110519:4;;;;;;;;110380:441;;;;;;;110562:25;;;;110380:441;;;;110622:7;;;110380:441;;;;110672:22;;110380:441;;;;110732:17;;110380:441;;;;;;;;;-1:-1:-1;;;110790:14:0;;;;110784:21;;;;;;;;110380:441;;;;110909:158;;;;;110311:510;;-1:-1:-1;110909:14:0;;:31;;:158;;110955:8;;110978:15;;110311:510;;111038:18;;110909:158;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110909:158:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;111116:43:0;;:22;:43;-1:-1:-1;;111116:43:0;;;;;;;;;;;;;;;;;;111170:7;:18;;-1:-1:-1;;;;;111170:18:0;;;-1:-1:-1;;111170:18:0;;;;;;;111199:14;:32;;;;;;;;;;;;;;;111262:15;111242:17;:35;;;111288:14;:50;;-1:-1:-1;;111288:50:0;-1:-1:-1;;;111288:50:0;;;111463:14;;111441:37;;111262:15;111441:21;:37::i;:::-;111411:15;-1:-1:-1;;;;;111356:133:0;;111388:8;111356:133;;;;;;;;;;;;;;;109624:1873;;;;;;;:::o;122402:168::-;122485:16;122526:17;:36;;122519:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;122519:43:0;;;;;;;;;;;;;;;;;;;;;;122402:168;:::o;11582:87::-;11654:7;11647:14;;;;;;;;-1:-1:-1;;11647:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11621:13;;11647:14;;11654:7;;11647:14;;11654:7;11647:14;;;;;;;;;;;;;;;;;;;;;;;;104856:29;;;-1:-1:-1;;;;;104856:29:0;;:::o;113751:870::-;114036:4;;113965:118;;;;;113840:16;;;;;;113965:15;;:32;;:118;;114012:9;;114036:4;;;-1:-1:-1;;;;;114036:4:0;;114055:17;;113965:118;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;113965:118:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;113965:118: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;113965:118:0;;;;;;;;;;114157:32;114200:33;114319:22;114331:9;114319:11;:22::i;:::-;114467:38;;114244:97;;-1:-1:-1;114244:97:0;-1:-1:-1;114467:53:0;;114510:9;114467:53;:42;:53;:::i;:::-;114426:38;:94;114541:36;114533:80;;;;;;;;;;;;;;;;;;;114579:15;;114596:16;;114541:36;;114533:80;;;114541:36;114533:80;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;114533:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113751:870;;;;;:::o;119830:228::-;119969:16;;;119983:1;119969:16;;;;;;;;;119905;;;;119969;;;;;;;105:10:-1;119969:16:0;88:34:-1;-1:-1;;120012:10:0;;119996:13;;;;-1:-1:-1;;;;;;120012:10:0;;119996:13;;-1:-1:-1;120012:10:0;;119996:13;;;;-1:-1:-1;;;;;119996:26:0;;;:13;;;;;;;;;;;:26;120040:10;-1:-1:-1;119830:228:0;:::o;116424:367::-;116653:14;;116757;;116528:16;;;;116587:15;;:27;;116629:9;;-1:-1:-1;;;;;116653:14:0;;116682:17;;116714:22;;-1:-1:-1;;;116757:14:0;;;;116751:21;;;;;;;;116587:196;;;;;-1:-1:-1;;;116587:196:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;116587:196:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;116587:196:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;116587:196:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;116587:196:0;;;;;;;;;116580:203;;;;116424:367;;;:::o;118113:1048::-;118315:34;118297:14;;-1:-1:-1;;;118297:14:0;;;;:52;;;;;;;;;;118275:156;;;;-1:-1:-1;;;;;118275:156:0;;;;;;;;;118512:33;118494:14;;-1:-1:-1;;;118494:14:0;;;;:51;;;;;;;;;118490:628;;;118674:12;;:37;;;;;-1:-1:-1;;;;;118674:12:0;;;;:25;;:37;;118700:10;;118674:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;118674:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;118674:37: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;118674:37:0;;;;;;;;;118648:163;;;;-1:-1:-1;;;;;118648:163:0;;;;;;;;;118490:628;;;119021:4;;;;;-1:-1:-1;;;;;119021:4:0;119007:10;:18;118981:125;;;;-1:-1:-1;;;;;118981:125:0;;;;;;;;;119130:23;119136:5;119143:9;119130:5;:23::i;121031:489::-;121185:16;;;121199:1;121185:16;;;;;;;;;121118;;;;121185;;;;17:15:-1;;105:10;121185:16:0;88:34:-1;136:17;;-1:-1;121185:16:0;121152:49;;121231:22;:39;;;121212:13;121226:1;121212:16;;;;;;;;;;;;;:58;;;;;121300:22;:41;;;121281:13;121295:1;121281:16;;;;;;;;;;;;;:60;;;;;121371:22;:40;;;121352:13;121366:1;121352:16;;;;;;;;;;;;;:59;;;;;121441:22;:40;;;121422:13;121436:1;121422:16;;;;;;;120545:330;120694:16;;;120708:1;120694:16;;;120627;120694;;;;;120627;;;120694;120708:1;120694:16;;;;;105:10:-1;120694:16:0;88:34:-1;136:17;;-1:-1;120694:16:0;120661:49;;120740:17;:28;;;120721:13;120735:1;120721:16;;;;;;;;;;;;;:47;;;;;120798:17;:38;;;120779:13;120793:1;120779:16;;;;;;;7789:213;7900:10;7874:4;7921:20;;;:8;:20;;;;;;;;-1:-1:-1;;;;;7921:29:0;;;;;;;;;;7874:4;;7891:81;;7912:7;;7921:50;;7955:15;7921:50;:33;:50;:::i;4893:140::-;4954:4;4971:32;4981:10;4993:2;4997:5;4971:9;:32::i;104743:::-;;;;:::o;104541:37::-;;;;:::o;104056:22::-;;;-1:-1:-1;;;;;104056:22:0;;:::o;104827:::-;;;-1:-1:-1;;;;;104827:22:0;;:::o;122988:172::-;123073:16;123114:17;:38;;123107:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122988:172;:::o;119299:315::-;119426:7;;-1:-1:-1;;;;;119426:7:0;119412:10;:21;119390:129;;;;-1:-1:-1;;;;;119390:129:0;;;;;;;;;119566:7;;119537:37;;;;;;119553:11;;-1:-1:-1;;;;;119566:7:0;;119537:37;;;;;;;;;;119585:7;:21;;-1:-1:-1;;119585:21:0;-1:-1:-1;;;;;119585:21:0;;;;;;;;;;119299:315::o;104938:71::-;;;;;;;;;;:::o;4588:131::-;-1:-1:-1;;;;;4687:15:0;;;4660:7;4687:15;;;:8;:15;;;;;;;;:24;;;;;;;;;;;;;4588:131::o;123305:176::-;123401:16;123442:31;123435:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;123435:38:0;;;;;;;;;;;;;;;;;;;;;;123305:176;:::o;122693:172::-;122778:16;122819:17;:38;;122812:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122693:172;:::o;104030:19::-;;;;;;-1:-1:-1;;;;;104030:19:0;;:::o;104378:46::-;;;-1:-1:-1;;;104378:46:0;;;;;:::o;112638:646::-;112764:22;:38;112817:13;:11;:13::i;:::-;112845:38;;:17;112898:28;112941:11;;112967:7;;112989:4;;113008:5;;113034:14;;-1:-1:-1;;;;;112967:7:0;;;;;112989:4;;;;;;113008:5;;;;-1:-1:-1;;;113034:14:0;;;;113028:21;;;;;;;;112764:296;;;;;-1:-1:-1;;;112764:296:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;112764:296:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;112764:296: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;112764:296:0;;;;;;;;;112751:10;:309;113128:7;;113115:10;:20;;-1:-1:-1;;113115:20:0;-1:-1:-1;;;;;113128:7:0;;;113115:20;;;;;;113171:15;113146:22;:40;113197:14;:49;;-1:-1:-1;;113197:49:0;;;113257:19;:17;:19::i;:::-;112638:646::o;104085:20::-;;;-1:-1:-1;;;;;104085:20:0;;:::o;104112:40::-;;;-1:-1:-1;;;;;104112:40:0;;:::o;9888:254::-;-1:-1:-1;;;;;9981:21:0;;9973:30;;;;;;-1:-1:-1;;;;;10022:19:0;;10014:28;;;;;;-1:-1:-1;;;;;10055:15:0;;;;;;;:8;:15;;;;;;;;:24;;;;;;;;;;;;;;:32;;;10103:31;;;;;10082:5;;10103:31;;;;;;;;;;9888:254;;;:::o;8229:262::-;-1:-1:-1;;;;;8317:16:0;;8309:25;;;;;;-1:-1:-1;;;;;8365:15:0;;:9;:15;;;;;;;;;;;:26;;8385:5;8365:26;:19;:26;:::i;:::-;-1:-1:-1;;;;;8347:15:0;;;:9;:15;;;;;;;;;;;:44;;;;8418:13;;;;;;;:24;;8436:5;8418:24;:17;:24;:::i;:::-;-1:-1:-1;;;;;8402:13:0;;;:9;:13;;;;;;;;;;;;:40;;;;8458:25;;;;;;;;;;8477:5;;8458:25;;2199:150;2257:7;2290:1;2285;:6;;2277:15;;;;;;-1:-1:-1;2315:5:0;;;2199:150::o;2437:::-;2495:7;2527:5;;;2551:6;;;;2543:15;;;;;8843:269;-1:-1:-1;;;;;8918:21:0;;8910:30;;;;;;8968:12;;:23;;8985:5;8968:23;:16;:23;:::i;:::-;8953:12;:38;-1:-1:-1;;;;;9023:18:0;;:9;:18;;;;;;;;;;;:29;;9046:5;9023:29;:22;:29;:::i;:::-;-1:-1:-1;;;;;9002:18:0;;:9;:18;;;;;;;;;;;:50;;;;9068:36;;9002:18;;:9;9068:36;;;;9098:5;;9068:36;;;;;;;;;;8843:269;;:::o;123638:243::-;123701:7;:20;;-1:-1:-1;;123701:20:0;;;;;;123732:14;:27;;;;;;;123719:1;123770:24;:28;;;123816:22;123809:29;;;;;;;;;;;;;;;123856:17;123849:24;;;;;;;123856:17;123849:24;;123719:1;123849:24;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;9346:269::-;-1:-1:-1;;;;;9421:21:0;;9413:30;;;;;;9471:12;;:23;;9488:5;9471:23;:16;:23;:::i;:::-;9456:12;:38;-1:-1:-1;;;;;9526:18:0;;:9;:18;;;;;;;;;;;:29;;9549:5;9526:29;:22;:29;:::i;:::-;-1:-1:-1;;;;;9505:18:0;;:9;:18;;;;;;;;;;;:50;;;;9571:36;;;;;;9601:5;;9571:36;;103840:20044;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;103840:20044:0;;;-1:-1:-1;103840:20044:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;103840:20044:0;-1:-1:-1;;;;;103840:20044:0;;;;;;;;;;;-1:-1:-1;103840:20044:0;;;;;;;-1:-1:-1;103840:20044:0;;;-1:-1:-1;103840:20044:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;103840:20044:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;103840:20044:0;;;;;;;5:118:-1;;72:46;110:6;97:20;72:46;;130:122;;208:39;239:6;233:13;208:39;;277:714;;401:3;394:4;386:6;382:17;378:27;368:2;;419:1;416;409:12;368:2;449:6;443:13;471:76;486:60;539:6;486:60;;;471:76;;;462:85;;564:5;589:6;582:5;575:21;619:4;611:6;607:17;597:27;;641:4;636:3;632:14;625:21;;694:6;741:3;733:4;725:6;721:17;716:3;712:27;709:36;706:2;;;758:1;755;748:12;706:2;783:1;768:217;793:6;790:1;787:13;768:217;;;851:3;873:48;917:3;905:10;873:48;;;861:61;;-1:-1;945:4;936:14;;;;964;;;;;815:1;808:9;768:217;;;772:14;361:630;;;;;;;;1017:714;;1141:3;1134:4;1126:6;1122:17;1118:27;1108:2;;1159:1;1156;1149:12;1108:2;1189:6;1183:13;1211:76;1226:60;1279:6;1226:60;;1211:76;1202:85;;1304:5;1329:6;1322:5;1315:21;1359:4;1351:6;1347:17;1337:27;;1381:4;1376:3;1372:14;1365:21;;1434:6;1481:3;1473:4;1465:6;1461:17;1456:3;1452:27;1449:36;1446:2;;;1498:1;1495;1488:12;1446:2;1523:1;1508:217;1533:6;1530:1;1527:13;1508:217;;;1591:3;1613:48;1657:3;1645:10;1613:48;;;1601:61;;-1:-1;1685:4;1676:14;;;;1704;;;;;1555:1;1548:9;1508:217;;1757:722;;1885:3;1878:4;1870:6;1866:17;1862:27;1852:2;;1903:1;1900;1893:12;1852:2;1933:6;1927:13;1955:80;1970:64;2027:6;1970:64;;1955:80;1946:89;;2052:5;2077:6;2070:5;2063:21;2107:4;2099:6;2095:17;2085:27;;2129:4;2124:3;2120:14;2113:21;;2182:6;2229:3;2221:4;2213:6;2209:17;2204:3;2200:27;2197:36;2194:2;;;2246:1;2243;2236:12;2194:2;2271:1;2256:217;2281:6;2278:1;2275:13;2256:217;;;2339:3;2361:48;2405:3;2393:10;2361:48;;;2349:61;;-1:-1;2433:4;2424:14;;;;2452;;;;;2303:1;2296:9;2256:217;;2487:116;;2562:36;2590:6;2584:13;2562:36;;2660:1343;;2795:4;2783:9;2778:3;2774:19;2770:30;2767:2;;;2813:1;2810;2803:12;2767:2;2831:20;2846:4;2831:20;;;2822:29;-1:-1;2907:1;2938:60;2994:3;2974:9;2938:60;;;2914:85;;-1:-1;3076:2;3109:60;3165:3;3141:22;;;3109:60;;;3102:4;3095:5;3091:16;3084:86;3020:161;3268:2;3257:9;3253:18;3247:25;3292:18;3284:6;3281:30;3278:2;;;3324:1;3321;3314:12;3278:2;3359:81;3436:3;3427:6;3416:9;3412:22;3359:81;;;3352:4;3345:5;3341:16;3334:107;3191:261;3539:2;3528:9;3524:18;3518:25;3563:18;3555:6;3552:30;3549:2;;;3595:1;3592;3585:12;3549:2;3630:81;3707:3;3698:6;3687:9;3683:22;3630:81;;;3623:4;3616:5;3612:16;3605:107;3462:261;3808:3;3797:9;3793:19;3787:26;3833:18;3825:6;3822:30;3819:2;;;3865:1;3862;3855:12;3819:2;3900:81;3977:3;3968:6;3957:9;3953:22;3900:81;;;3893:4;3886:5;3882:16;3875:107;3733:260;2761:1242;;;;;4010:118;;4077:46;4115:6;4102:20;4077:46;;4135:122;;4213:39;4244:6;4238:13;4213:39;;4264:118;;4340:37;4369:6;4363:13;4340:37;;4389:241;;4493:2;4481:9;4472:7;4468:23;4464:32;4461:2;;;4509:1;4506;4499:12;4461:2;4544:1;4561:53;4606:7;4586:9;4561:53;;;4551:63;4455:175;-1:-1;;;;4455:175;4637:366;;;4758:2;4746:9;4737:7;4733:23;4729:32;4726:2;;;4774:1;4771;4764:12;4726:2;4809:1;4826:53;4871:7;4851:9;4826:53;;;4816:63;;4788:97;4916:2;4934:53;4979:7;4970:6;4959:9;4955:22;4934:53;;;4924:63;;4895:98;4720:283;;;;;;5010:491;;;;5148:2;5136:9;5127:7;5123:23;5119:32;5116:2;;;5164:1;5161;5154:12;5116:2;5199:1;5216:53;5261:7;5241:9;5216:53;;;5206:63;;5178:97;5306:2;5324:53;5369:7;5360:6;5349:9;5345:22;5324:53;;;5314:63;;5285:98;5414:2;5432:53;5477:7;5468:6;5457:9;5453:22;5432:53;;;5422:63;;5393:98;5110:391;;;;;;5508:743;;;;;;5680:3;5668:9;5659:7;5655:23;5651:33;5648:2;;;5697:1;5694;5687:12;5648:2;5732:1;5749:53;5794:7;5774:9;5749:53;;;5739:63;;5711:97;5839:2;5857:53;5902:7;5893:6;5882:9;5878:22;5857:53;;;5847:63;;5818:98;5947:2;5965:53;6010:7;6001:6;5990:9;5986:22;5965:53;;;5955:63;;5926:98;6055:2;6073:53;6118:7;6109:6;6098:9;6094:22;6073:53;;;6063:63;;6034:98;6163:3;6182:53;6227:7;6218:6;6207:9;6203:22;6182:53;;;6172:63;;6142:99;5642:609;;;;;;;;;6258:366;;;6379:2;6367:9;6358:7;6354:23;6350:32;6347:2;;;6395:1;6392;6385:12;6347:2;6430:1;6447:53;6492:7;6472:9;6447:53;;;6437:63;;6409:97;6537:2;6555:53;6600:7;6591:6;6580:9;6576:22;6555:53;;6631:657;;;6813:2;6801:9;6792:7;6788:23;6784:32;6781:2;;;6829:1;6826;6819:12;6781:2;6864:24;;6908:18;6897:30;;6894:2;;;6940:1;6937;6930:12;6894:2;6960:89;7041:7;7032:6;7021:9;7017:22;6960:89;;;6950:99;;6843:212;7107:2;7096:9;7092:18;7086:25;7131:18;7123:6;7120:30;7117:2;;;7163:1;7160;7153:12;7117:2;7183:89;7264:7;7255:6;7244:9;7240:22;7183:89;;7295:257;;7407:2;7395:9;7386:7;7382:23;7378:32;7375:2;;;7423:1;7420;7413:12;7375:2;7458:1;7475:61;7528:7;7508:9;7475:61;;7559:412;;7709:2;7697:9;7688:7;7684:23;7680:32;7677:2;;;7725:1;7722;7715:12;7677:2;7760:24;;7804:18;7793:30;;7790:2;;;7836:1;7833;7826:12;7790:2;7856:99;7947:7;7938:6;7927:9;7923:22;7856:99;;7978:241;;8082:2;8070:9;8061:7;8057:23;8053:32;8050:2;;;8098:1;8095;8088:12;8050:2;8133:1;8150:53;8195:7;8175:9;8150:53;;8226:263;;8341:2;8329:9;8320:7;8316:23;8312:32;8309:2;;;8357:1;8354;8347:12;8309:2;8392:1;8409:64;8465:7;8445:9;8409:64;;8496:399;;;8628:2;8616:9;8607:7;8603:23;8599:32;8596:2;;;8644:1;8641;8634:12;8596:2;8679:1;8696:64;8752:7;8732:9;8696:64;;;8686:74;;8658:108;8797:2;8815:64;8871:7;8862:6;8851:9;8847:22;8815:64;;8902:259;;9015:2;9003:9;8994:7;8990:23;8986:32;8983:2;;;9031:1;9028;9021:12;8983:2;9066:1;9083:62;9137:7;9117:9;9083:62;;9169:173;;9256:46;9298:3;9290:6;9256:46;;;-1:-1;;9331:4;9322:14;;9249:93;9549:173;;9636:46;9678:3;9670:6;9636:46;;9928:142;10019:45;10058:5;10019:45;;;10014:3;10007:58;10001:69;;;10077:110;10150:31;10175:5;10150:31;;10612:621;;10757:54;10805:5;10757:54;;;10824:86;10903:6;10898:3;10824:86;;;10817:93;;10930:56;10980:5;10930:56;;;11007:1;10992:219;11017:6;11014:1;11011:13;10992:219;;;11064:63;11123:3;11114:6;11108:13;11064:63;;;11057:70;;11144:60;11197:6;11144:60;;;11134:70;-1:-1;11039:1;11032:9;10992:219;;;-1:-1;11224:3;;10736:497;-1:-1;;;;10736:497;11272:643;;11412:51;11457:5;11412:51;;;11476:84;11553:6;11548:3;11476:84;;;11469:91;;11580:53;11627:5;11580:53;;;11654:1;11639:254;11664:6;11661:1;11658:13;11639:254;;;11711:101;11808:3;11763:43;11799:6;11763:43;;;11711:101;;;11704:108;;11829:57;11879:6;11829:57;;;11819:67;-1:-1;11686:1;11679:9;11639:254;;11954:621;;12099:54;12147:5;12099:54;;;12166:86;12245:6;12240:3;12166:86;;;12159:93;;12272:56;12322:5;12272:56;;;12349:1;12334:219;12359:6;12356:1;12353:13;12334:219;;;12406:63;12465:3;12456:6;12450:13;12406:63;;;12399:70;;12486:60;12539:6;12486:60;;;12476:70;-1:-1;12381:1;12374:9;12334:219;;12614:643;;12754:51;12799:5;12754:51;;;12818:84;12895:6;12890:3;12818:84;;;12811:91;;12922:53;12969:5;12922:53;;;12996:1;12981:254;13006:6;13003:1;13000:13;12981:254;;;13053:101;13150:3;13105:43;13141:6;13105:43;;;13053:101;;;13046:108;;13171:57;13221:6;13171:57;;;13161:67;-1:-1;13028:1;13021:9;12981:254;;13265:111;13342:28;13364:5;13342:28;;13383:142;13474:45;13513:5;13474:45;;13532:347;;13644:39;13677:5;13644:39;;;13695:71;13759:6;13754:3;13695:71;;;13688:78;;13771:52;13816:6;13811:3;13804:4;13797:5;13793:16;13771:52;;;13844:29;13866:6;13844:29;;;13835:39;;;;13624:255;-1:-1;;;13624:255;13887:465;;14047:67;14111:2;14106:3;14047:67;;;14147:66;14127:87;;14248:66;14243:2;14234:12;;14227:88;14343:2;14334:12;;14033:319;-1:-1;;14033:319;14361:465;;14521:67;14585:2;14580:3;14521:67;;;14621:66;14601:87;;14722:66;14717:2;14708:12;;14701:88;14817:2;14808:12;;14507:319;-1:-1;;14507:319;14835:465;;14995:67;15059:2;15054:3;14995:67;;;15095:66;15075:87;;15196:66;15191:2;15182:12;;15175:88;15291:2;15282:12;;14981:319;-1:-1;;14981:319;15309:465;;15469:67;15533:2;15528:3;15469:67;;;15569:66;15549:87;;15670:66;15665:2;15656:12;;15649:88;15765:2;15756:12;;15455:319;-1:-1;;15455:319;15783:465;;15943:67;16007:2;16002:3;15943:67;;;16043:66;16023:87;;16144:66;16139:2;16130:12;;16123:88;16239:2;16230:12;;15929:319;-1:-1;;15929:319;16257:465;;16417:67;16481:2;16476:3;16417:67;;;16517:66;16497:87;;16618:66;16613:2;16604:12;;16597:88;16713:2;16704:12;;16403:319;-1:-1;;16403:319;16731:465;;16891:67;16955:2;16950:3;16891:67;;;16991:66;16971:87;;17092:66;17087:2;17078:12;;17071:88;17187:2;17178:12;;16877:319;-1:-1;;16877:319;17311:896;17569:22;;17492:4;17483:14;;;17597:69;17487:3;17569:22;17597:69;;;17512:160;17758:4;17751:5;17747:16;17741:23;17770:70;17834:4;17829:3;17825:14;17812:11;17770:70;;;17682:164;17931:4;17924:5;17920:16;17914:23;17943:70;18007:4;18002:3;17998:14;17985:11;17943:70;;;17856:163;18104:4;18097:5;18093:16;18087:23;18116:70;18180:4;18175:3;18171:14;18158:11;18116:70;;;18029:163;17465:742;;;;18321:1180;18582:22;;18499:4;18490:14;;;18629:55;18582:22;18629:55;;;18690:69;18749:3;18732:11;18690:69;;;-1:-1;;18839:3;18828:15;;18822:22;18869:55;18822:22;18869:55;;;18930:70;18994:4;18989:3;18985:14;18972:11;18930:70;;;-1:-1;;19079:3;19068:15;;19062:22;19109:55;19062:22;19109:55;;;19170:70;19234:4;19229:3;19225:14;19212:11;19170:70;;;-1:-1;;19319:3;19308:15;;19302:22;19349:55;19302:22;19349:55;;;19410:70;19474:4;19469:3;19465:14;19452:11;19410:70;;;19256:230;18472:1029;;;;;19605:1516;19858:22;;19605:1516;;19781:4;19772:14;;;19905:55;19858:22;19905:55;;;19966:69;20025:3;20008:11;19966:69;;;-1:-1;;20117:3;20106:15;;20100:22;20147:55;20100:22;20147:55;;;20208:70;20272:4;20267:3;20263:14;20250:11;20208:70;;;20051:233;20366:3;20359:5;20355:15;20416:3;20410:4;20406:14;20399:4;20394:3;20390:14;20383:38;20436:107;20538:4;20525:11;20436:107;;;20428:115;;20294:261;20637:3;20630:5;20626:15;20687:3;20681:4;20677:14;20670:4;20665:3;20661:14;20654:38;20707:107;20809:4;20796:11;20707:107;;;20699:115;;20565:261;20906:3;20899:5;20895:15;20956:3;20950:4;20946:14;20939:4;20934:3;20930:14;20923:38;20976:107;21078:4;21065:11;20976:107;;;20968:115;19754:1367;-1:-1;;;;;;19754:1367;21213:1548;21449:22;;21380:5;21371:15;;;21477:69;21375:3;21449:22;21477:69;;;21401:151;21630:4;21623:5;21619:16;21613:23;21642:70;21706:4;21701:3;21697:14;21684:11;21642:70;;;21562:156;21797:4;21790:5;21786:16;21780:23;21809:70;21873:4;21868:3;21864:14;21851:11;21809:70;;;21728:157;21971:4;21964:5;21960:16;21954:23;21983:70;22047:4;22042:3;22038:14;22025:11;21983:70;;;21895:164;22141:4;22134:5;22130:16;22124:23;22153:70;22217:4;22212:3;22208:14;22195:11;22153:70;;;22069:160;22319:4;22312:5;22308:16;22302:23;22331:70;22395:4;22390:3;22386:14;22373:11;22331:70;;;22239:168;22492:4;22485:5;22481:16;22475:23;22504:70;22568:4;22563:3;22559:14;22546:11;22504:70;;;22417:163;22662:4;22655:5;22651:16;22645:23;22674:66;22734:4;22729:3;22725:14;22712:11;22674:66;;22768:110;22841:31;22866:5;22841:31;;23272:114;23351:29;23374:5;23351:29;;23641:213;23759:2;23744:18;;23773:71;23748:9;23817:6;23773:71;;23861:229;23987:2;23972:18;;24001:79;23976:9;24053:6;24001:79;;24097:324;24243:2;24228:18;;24257:71;24232:9;24301:6;24257:71;;;24339:72;24407:2;24396:9;24392:18;24383:6;24339:72;;24428:707;24666:3;24651:19;;24681:79;24655:9;24733:6;24681:79;;;24771:80;24847:2;24836:9;24832:18;24823:6;24771:80;;;24862;24938:2;24927:9;24923:18;24914:6;24862:80;;;24953;25029:2;25018:9;25014:18;25005:6;24953:80;;;25044:81;25120:3;25109:9;25105:19;25096:6;25044:81;;25142:880;25498:3;25483:19;;25513:79;25487:9;25565:6;25513:79;;;25603:80;25679:2;25668:9;25664:18;25655:6;25603:80;;;25694:146;25836:2;25825:9;25821:18;25812:6;25694:146;;;25851:161;26007:3;25996:9;25992:19;25983:6;25851:161;;;25469:553;;;;;;;;26029:361;26197:2;26211:47;;;26182:18;;26272:108;26182:18;26366:6;26272:108;;26397:879;26721:2;26735:47;;;26706:18;;26796:108;26706:18;26890:6;26796:108;;;26788:116;;26952:9;26946:4;26942:20;26937:2;26926:9;26922:18;26915:48;26977:108;27080:4;27071:6;26977:108;;;26969:116;;27133:9;27127:4;27123:20;27118:2;27107:9;27103:18;27096:48;27158:108;27261:4;27252:6;27158:108;;27283:361;27451:2;27465:47;;;27436:18;;27526:108;27436:18;27620:6;27526:108;;27651:620;27897:2;27911:47;;;27882:18;;27972:108;27882:18;28066:6;27972:108;;;27964:116;;28128:9;28122:4;28118:20;28113:2;28102:9;28098:18;28091:48;28153:108;28256:4;28247:6;28153:108;;28278:201;28390:2;28375:18;;28404:65;28379:9;28442:6;28404:65;;28486:229;28612:2;28597:18;;28626:79;28601:9;28678:6;28626:79;;28722:301;28860:2;28874:47;;;28845:18;;28935:78;28845:18;28999:6;28935:78;;29030:407;29221:2;29235:47;;;29206:18;;29296:131;29206:18;29296:131;;29444:407;29635:2;29649:47;;;29620:18;;29710:131;29620:18;29710:131;;29858:407;30049:2;30063:47;;;30034:18;;30124:131;30034:18;30124:131;;30272:407;30463:2;30477:47;;;30448:18;;30538:131;30448:18;30538:131;;30686:407;30877:2;30891:47;;;30862:18;;30952:131;30862:18;30952:131;;31100:407;31291:2;31305:47;;;31276:18;;31366:131;31276:18;31366:131;;31514:407;31705:2;31719:47;;;31690:18;;31780:131;31690:18;31780:131;;31928:213;32046:2;32031:18;;32060:71;32035:9;32104:6;32060:71;;32148:649;32397:2;32382:18;;32411:79;32386:9;32463:6;32411:79;;;32501:80;32577:2;32566:9;32562:18;32553:6;32501:80;;;32629:9;32623:4;32619:20;32614:2;32603:9;32599:18;32592:48;32654:133;32782:4;32773:6;32654:133;;32804:1035;33182:3;33167:19;;33197:79;33171:9;33249:6;33197:79;;;33287:80;33363:2;33352:9;33348:18;33339:6;33287:80;;;33415:9;33409:4;33405:20;33400:2;33389:9;33385:18;33378:48;33440:133;33568:4;33559:6;33440:133;;;33432:141;;33584:157;33737:2;33726:9;33722:18;33713:6;33584:157;;;33752:77;33824:3;33813:9;33809:19;33800:6;33752:77;;33846:324;33992:2;33977:18;;34006:71;33981:9;34050:6;34006:71;;;34088:72;34156:2;34145:9;34141:18;34132:6;34088:72;;34177:587;34387:3;34372:19;;34402:79;34376:9;34454:6;34402:79;;;34492:80;34568:2;34557:9;34553:18;34544:6;34492:80;;;34583;34659:2;34648:9;34644:18;34635:6;34583:80;;;34674;34750:2;34739:9;34735:18;34726:6;34674:80;;34771:1275;35205:3;35190:19;;35220:79;35194:9;35272:6;35220:79;;;35310:80;35386:2;35375:9;35371:18;35362:6;35310:80;;;35401;35477:2;35466:9;35462:18;35453:6;35401:80;;;35492;35568:2;35557:9;35553:18;35544:6;35492:80;;;35583:158;35736:3;35725:9;35721:19;35712:6;35583:158;;;35790:9;35784:4;35780:20;35774:3;35763:9;35759:19;35752:49;35815:133;35943:4;35934:6;35815:133;;;35807:141;;35959:77;36031:3;36020:9;36016:19;36007:6;35959:77;;;35176:870;;;;;;;;;;;36053:547;36255:3;36240:19;;36270:71;36244:9;36314:6;36270:71;;;36352:72;36420:2;36409:9;36405:18;36396:6;36352:72;;;36435;36503:2;36492:9;36488:18;36479:6;36435:72;;;36518;36586:2;36575:9;36571:18;36562:6;36518:72;;36607:1059;36925:3;36910:19;;36940:79;36914:9;36992:6;36940:79;;;37030:80;37106:2;37095:9;37091:18;37082:6;37030:80;;;37121;37197:2;37186:9;37182:18;37173:6;37121:80;;;37212;37288:2;37277:9;37273:18;37264:6;37212:80;;;37303:81;37379:3;37368:9;37364:19;37355:6;37303:81;;;37395;37471:3;37460:9;37456:19;37447:6;37395:81;;;37487;37563:3;37552:9;37548:19;37539:6;37487:81;;;37579:77;37651:3;37640:9;37636:19;37627:6;37579:77;;;36896:770;;;;;;;;;;;;37673:459;37851:2;37836:18;;37865:79;37840:9;37917:6;37865:79;;;37955:80;38031:2;38020:9;38016:18;38007:6;37955:80;;;38046:76;38118:2;38107:9;38103:18;38094:6;38046:76;;38139:205;38253:2;38238:18;;38267:67;38242:9;38307:6;38267:67;;38351:256;38413:2;38407:9;38439:17;;;38514:18;38499:34;;38535:22;;;38496:62;38493:2;;;38571:1;38568;38561:12;38493:2;38587;38580:22;38391:216;;-1:-1;38391:216;38614:254;;38769:18;38761:6;38758:30;38755:2;;;38801:1;38798;38791:12;38755:2;-1:-1;38830:4;38818:17;;;38848:15;;38692:176;39403:121;39512:4;39500:17;;39481:43;39535:141;;39617:15;;;39664:4;39651:18;;;39609:67;39969:107;40059:12;;40043:33;40083:104;40170:12;;40154:33;40650:114;40756:1;40746:12;;40727:37;41027:178;41145:19;;;41194:4;41185:14;;41138:67;41942:105;;42011:31;42036:5;42011:31;;42054:92;42127:13;42120:21;;42103:43;42153:127;;42241:1;42234:5;42231:12;42221:2;;42247:9;42287:128;-1:-1;;;;;42356:54;;42339:76;42508:88;42586:4;42575:16;;42558:38;43363:129;;43450:37;43481:5;43450:37;;43499:133;;43586:41;43621:5;43586:41;;43639:121;;43718:37;43749:5;43718:37;;43890:268;43955:1;43962:101;43976:6;43973:1;43970:13;43962:101;;;44043:11;;;44037:18;44024:11;;;44017:39;43998:2;43991:10;43962:101;;;44078:6;44075:1;44072:13;44069:2;;;-1:-1;;44143:1;44125:16;;44118:27;43939:219;44166:161;;44256:66;44287:34;44310:10;44287:34;;;44256:66;;44334:161;;44424:66;44455:34;44478:10;44455:34;;;44424:66;;44502:137;;44577:57;44628:4;44622:11;44577:57;;44646:137;;44721:57;44772:4;44766:11;44721:57;;44790:97;44878:2;44858:14;-1:-1;;44854:28;;44838:49
Swarm Source
bzzr://2bbac5ffc9e275d60b7960627099bd2842502594fa837be06c87496fe14bbbf8
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.