More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 364 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Remove_liquidity | 15998318 | 596 days ago | IN | 0 ETH | 0.00898992 | ||||
Remove_liquidity | 15378266 | 686 days ago | IN | 0 ETH | 0.00272872 | ||||
Remove_liquidity | 12806138 | 1091 days ago | IN | 0 ETH | 0.00248253 | ||||
Remove_liquidity | 12536932 | 1133 days ago | IN | 0 ETH | 0.00477532 | ||||
Remove_liquidity | 12473687 | 1143 days ago | IN | 0 ETH | 0.01783051 | ||||
Remove_liquidity | 12310749 | 1168 days ago | IN | 0 ETH | 0.01280844 | ||||
Remove_liquidity | 11930684 | 1226 days ago | IN | 0 ETH | 0.03184515 | ||||
Remove_liquidity | 11891275 | 1233 days ago | IN | 0 ETH | 0.06724169 | ||||
Remove_liquidity | 11888953 | 1233 days ago | IN | 0 ETH | 0.04404154 | ||||
Remove_liquidity | 11849594 | 1239 days ago | IN | 0 ETH | 0.0064 | ||||
Remove_liquidity | 11805578 | 1246 days ago | IN | 0 ETH | 0.06645642 | ||||
Remove_liquidity | 11805573 | 1246 days ago | IN | 0 ETH | 0.0606562 | ||||
Remove_liquidity | 11742221 | 1255 days ago | IN | 0 ETH | 0.01519959 | ||||
Remove_liquidity | 11719528 | 1259 days ago | IN | 0 ETH | 0.05462341 | ||||
Remove_liquidity | 11719520 | 1259 days ago | IN | 0 ETH | 0.04835667 | ||||
Remove_liquidity | 11718541 | 1259 days ago | IN | 0 ETH | 0.01235311 | ||||
Remove_liquidity | 11649184 | 1270 days ago | IN | 0 ETH | 0.01074136 | ||||
Remove_liquidity | 11638136 | 1271 days ago | IN | 0 ETH | 0.01691764 | ||||
Remove_liquidity | 11635938 | 1272 days ago | IN | 0 ETH | 0.03968456 | ||||
Remove_liquidity | 11633342 | 1272 days ago | IN | 0 ETH | 0.06182955 | ||||
Remove_liquidity | 11608399 | 1276 days ago | IN | 0 ETH | 0.05077402 | ||||
Remove_liquidity | 11596782 | 1278 days ago | IN | 0 ETH | 0.03471624 | ||||
Remove_liquidity | 11574781 | 1281 days ago | IN | 0 ETH | 0.01110256 | ||||
Remove_liquidity | 11573478 | 1281 days ago | IN | 0 ETH | 0.01731699 | ||||
Remove_liquidity | 11569753 | 1282 days ago | IN | 0 ETH | 0.02643748 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
SaffronPool
Compiler Version
v0.7.4+commit.3f05b770
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-12-13 */ // File: contracts/interfaces/ISaffronBase.sol // SPDX-License-Identifier: MIT pragma solidity ^0.7.1; interface ISaffronBase { enum Tranche {S, AA, A} enum LPTokenType {dsec, principal} // Store values (balances, dsec, vdsec) with TrancheUint256 struct TrancheUint256 { uint256 S; uint256 AA; uint256 A; } struct epoch_params { uint256 start_date; // Time when the platform launched uint256 duration; // Duration of epoch } } // File: contracts/interfaces/ISaffronStrategy.sol pragma solidity ^0.7.1; interface ISaffronStrategy is ISaffronBase{ function deploy_all_capital() external; function select_adapter_for_liquidity_removal() external returns(address); function add_adapter(address adapter_address) external; function add_pool(address pool_address) external; function delete_adapters() external; function set_governance(address to) external; function get_adapter_address(uint256 adapter_index) external view returns(address); } // File: contracts/interfaces/ISaffronPool.sol pragma solidity ^0.7.1; interface ISaffronPool is ISaffronBase { function add_liquidity(uint256 amount, Tranche tranche) external; function remove_liquidity(address v1_dsec_token_address, uint256 dsec_amount, address v1_principal_token_address, uint256 principal_amount) external; function get_base_asset_address() external view returns(address); function hourly_strategy(address adapter_address) external; function wind_down_epoch(uint256 epoch, uint256 amount_sfi) external; function set_governance(address to) external; function get_epoch_cycle_params() external view returns (uint256, uint256); function shutdown() external; } // File: contracts/interfaces/ISaffronAdapter.sol pragma solidity ^0.7.1; interface ISaffronAdapter is ISaffronBase { function deploy_capital(uint256 amount) external; function return_capital(uint256 base_asset_amount, address to) external; function approve_transfer(address addr,uint256 amount) external; function get_base_asset_address() external view returns(address); function set_base_asset(address addr) external; function get_holdings() external returns(uint256); function get_interest(uint256 principal) external returns(uint256); function set_governance(address to) external; } // File: contracts/lib/SafeMath.sol pragma solidity ^0.7.1; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot 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-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/lib/IERC20.sol pragma solidity ^0.7.1; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: 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 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/lib/Context.sol pragma solidity ^0.7.1; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: contracts/lib/Address.sol pragma solidity ^0.7.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.3._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.3._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: contracts/lib/ERC20.sol pragma solidity ^0.7.1; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } // File: contracts/lib/SafeERC20.sol pragma solidity ^0.7.1; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: contracts/SFI.sol pragma solidity ^0.7.1; contract SFI is ERC20 { using SafeERC20 for IERC20; address public governance; address public SFI_minter; uint256 public MAX_TOKENS = 100000 ether; constructor (string memory name, string memory symbol) ERC20(name, symbol) { // Initial governance is Saffron Deployer governance = msg.sender; } function mint_SFI(address to, uint256 amount) public { require(msg.sender == SFI_minter, "must be SFI_minter"); require(this.totalSupply() + amount < MAX_TOKENS, "cannot mint more than MAX_TOKENS"); _mint(to, amount); } function set_minter(address to) external { require(msg.sender == governance, "must be governance"); SFI_minter = to; } function set_governance(address to) external { require(msg.sender == governance, "must be governance"); governance = to; } event ErcSwept(address who, address to, address token, uint256 amount); function erc_sweep(address _token, address _to) public { require(msg.sender == governance, "must be governance"); IERC20 tkn = IERC20(_token); uint256 tBal = tkn.balanceOf(address(this)); tkn.safeTransfer(_to, tBal); emit ErcSwept(msg.sender, _to, _token, tBal); } } // File: contracts/SaffronLPBalanceToken.sol pragma solidity ^0.7.1; contract SaffronLPBalanceToken is ERC20 { address public pool_address; constructor (string memory name, string memory symbol) ERC20(name, symbol) { // Set pool_address to saffron pool that created token pool_address = msg.sender; } // Allow creating new tranche tokens function mint(address to, uint256 amount) public { require(msg.sender == pool_address, "must be pool"); _mint(to, amount); } function burn(address account, uint256 amount) public { require(msg.sender == pool_address, "must be pool"); _burn(account, amount); } function set_governance(address to) external { require(msg.sender == pool_address, "must be pool"); pool_address = to; } } // File: contracts/SaffronPool.sol pragma solidity ^0.7.1; contract SaffronPool is ISaffronPool { using SafeMath for uint256; using SafeERC20 for IERC20; address public governance; // Governance (v3: add off-chain/on-chain governance) address public base_asset_address; // Base asset managed by the pool (DAI, USDT, YFI...) address public SFI_address; // SFI token uint256 public pool_principal; // Current principal balance (added minus removed) uint256 public pool_interest; // Current interest balance (redeemable by dsec tokens) uint256 public tranche_A_multiplier; // Current yield multiplier for tranche A uint256 public SFI_ratio; // Ratio of base asset to SFI necessary to join tranche A bool public _shutdown = false; // v0, v1: shutdown the pool after the final capital deploy to prevent burning funds /**** ADAPTERS ****/ address public best_adapter_address; // Current best adapter selected by strategy uint256 public adapter_total_principal; // v0, v1: only one adapter ISaffronAdapter[] private adapters; // v2: list of adapters mapping(address=>uint256) private adapter_index; // v1: adapter contract address lookup for array indexes /**** STRATEGY ****/ address public strategy; /**** EPOCHS ****/ epoch_params public epoch_cycle = epoch_params({ start_date: 1604239200, // 11/01/2020 @ 2:00pm (UTC) duration: 14 days // 1210000 seconds }); /**** EPOCH INDEXED STORAGE ****/ uint256[] public epoch_principal; // Total principal owned by the pool (all tranches) mapping(uint256=>bool) public epoch_wound_down; // True if epoch has been wound down already (governance) /**** EPOCH-TRANCHE INDEXED STORAGE ****/ // Array of arrays, example: tranche_SFI_earned[epoch][Tranche.S] address[3][] public dsec_token_addresses; // Address for each dsec token address[3][] public principal_token_addresses; // Address for each principal token uint256[3][] public tranche_total_dsec; // Total dsec (tokens + vdsec) uint256[3][] public tranche_total_principal; // Total outstanding principal tokens uint256[3][] public tranche_total_utilized; // Total utilized balance in each tranche uint256[3][] public tranche_total_unutilized; // Total unutilized balance in each tranche uint256[3][] public tranche_S_virtual_utilized; // Total utilized virtual balance taken from tranche S (first index unused) uint256[3][] public tranche_S_virtual_unutilized; // Total unutilized virtual balance taken from tranche S (first index unused) uint256[3][] public tranche_interest_earned; // Interest earned (calculated at wind_down_epoch) uint256[3][] public tranche_SFI_earned; // Total SFI earned (minted at wind_down_epoch) /**** SFI GENERATION ****/ // v0: pool generates SFI based on subsidy schedule // v1: pool is distributed SFI generated by the strategy contract // v1: pools each get an amount of SFI generated depending on the total liquidity added within each interval TrancheUint256 public TRANCHE_SFI_MULTIPLIER = TrancheUint256({ S: 90000, AA: 0, A: 10000 }); /**** TRANCHE BALANCES ****/ // (v0 & v1: epochs are hard-forks) // (v2: epoch rollover implemented) // TrancheUint256 private eternal_unutilized_balances; // Unutilized balance (in base assets) for each tranche (assets held in this pool + assets held in platforms) // TrancheUint256 private eternal_utilized_balances; // Balance for each tranche that is not held within this pool but instead held on a platform via an adapter /**** SAFFRON LP TOKENS ****/ // If we just have a token address then we can look up epoch and tranche balance tokens using a mapping(address=>SaffronLPdsecInfo) // LP tokens are dsec (redeemable for interest+SFI) and principal (redeemable for base asset) tokens struct SaffronLPTokenInfo { bool exists; uint256 epoch; Tranche tranche; LPTokenType token_type; } mapping(address=>SaffronLPTokenInfo) private saffron_LP_token_info; constructor(address _strategy, address _base_asset, address _SFI_address, bool epoch_cycle_reset) { governance = msg.sender; base_asset_address = _base_asset; strategy = _strategy; SFI_address = _SFI_address; tranche_A_multiplier = 10; // v1: start enhanced yield at 10X SFI_ratio = 500; // v1: constant ratio epoch_cycle.duration = (epoch_cycle_reset ? 20 minutes : 14 days); // Make testing previous epochs easier epoch_cycle.start_date = (epoch_cycle_reset ? (block.timestamp) - (3 * epoch_cycle.duration) : 1604239200); // Make testing previous epochs easier } function new_epoch(uint256 epoch, address[] memory saffron_LP_dsec_token_addresses, address[] memory saffron_LP_principal_token_addresses) public { require(tranche_total_principal.length == epoch, "improper new epoch"); require(governance == msg.sender, "must be governance"); epoch_principal.push(0); tranche_total_dsec.push([0,0,0]); tranche_total_principal.push([0,0,0]); tranche_total_utilized.push([0,0,0]); tranche_total_unutilized.push([0,0,0]); tranche_S_virtual_utilized.push([0,0,0]); tranche_S_virtual_unutilized.push([0,0,0]); tranche_interest_earned.push([0,0,0]); tranche_SFI_earned.push([0,0,0]); dsec_token_addresses.push([ // Address for each dsec token saffron_LP_dsec_token_addresses[uint256(Tranche.S)], saffron_LP_dsec_token_addresses[uint256(Tranche.AA)], saffron_LP_dsec_token_addresses[uint256(Tranche.A)] ]); principal_token_addresses.push([ // Address for each principal token saffron_LP_principal_token_addresses[uint256(Tranche.S)], saffron_LP_principal_token_addresses[uint256(Tranche.AA)], saffron_LP_principal_token_addresses[uint256(Tranche.A)] ]); // Token info for looking up epoch and tranche of dsec tokens by token contract address saffron_LP_token_info[saffron_LP_dsec_token_addresses[uint256(Tranche.S)]] = SaffronLPTokenInfo({ exists: true, epoch: epoch, tranche: Tranche.S, token_type: LPTokenType.dsec }); saffron_LP_token_info[saffron_LP_dsec_token_addresses[uint256(Tranche.AA)]] = SaffronLPTokenInfo({ exists: true, epoch: epoch, tranche: Tranche.AA, token_type: LPTokenType.dsec }); saffron_LP_token_info[saffron_LP_dsec_token_addresses[uint256(Tranche.A)]] = SaffronLPTokenInfo({ exists: true, epoch: epoch, tranche: Tranche.A, token_type: LPTokenType.dsec }); // for looking up epoch and tranche of PRINCIPAL tokens by token contract address saffron_LP_token_info[saffron_LP_principal_token_addresses[uint256(Tranche.S)]] = SaffronLPTokenInfo({ exists: true, epoch: epoch, tranche: Tranche.S, token_type: LPTokenType.principal }); saffron_LP_token_info[saffron_LP_principal_token_addresses[uint256(Tranche.AA)]] = SaffronLPTokenInfo({ exists: true, epoch: epoch, tranche: Tranche.AA, token_type: LPTokenType.principal }); saffron_LP_token_info[saffron_LP_principal_token_addresses[uint256(Tranche.A)]] = SaffronLPTokenInfo({ exists: true, epoch: epoch, tranche: Tranche.A, token_type: LPTokenType.principal }); } struct BalanceVars { // Tranche balance uint256 deposit; // User deposit uint256 capacity; // Capacity for user's intended tranche uint256 change; // Change from deposit - capacity // S tranche specific vars uint256 consumed; // Total consumed uint256 utilized_consumed; uint256 unutilized_consumed; uint256 available_utilized; uint256 available_unutilized; } event TrancheBalance(uint256 tranche, uint256 amount, uint256 deposit, uint256 capacity, uint256 change, uint256 consumed, uint256 utilized_consumed, uint256 unutilized_consumed, uint256 available_utilized, uint256 available_unutilized); event DsecGeneration(uint256 time_remaining, uint256 amount, uint256 dsec, address dsec_address, uint256 epoch, uint256 tranche, address user_address, address principal_token_addr); event AddLiquidity(uint256 new_pool_principal, uint256 new_epoch_principal, uint256 new_eternal_balance, uint256 new_tranche_principal, uint256 new_tranche_dsec); // LP user adds liquidity to the pool // Pre-requisite (front-end): have user approve transfer on front-end to base asset using our contract address function add_liquidity(uint256 amount, Tranche tranche) external override { require(!_shutdown, "pool shutdown"); require(tranche == Tranche.S || tranche == Tranche.A, "v1: can't add_liquidity into AA tranche"); uint256 epoch = get_current_epoch(); require(amount != 0, "can't add 0"); require(epoch == 3, "v1.3: must be epoch 3 only"); BalanceVars memory bv = BalanceVars({ deposit: 0, capacity: 0, change: 0, consumed: 0, utilized_consumed: 0, unutilized_consumed: 0, available_utilized: 0, available_unutilized: 0 }); (bv.available_utilized, bv.available_unutilized) = get_available_S_balances(); if (tranche == Tranche.S) { tranche_total_unutilized[epoch][uint256(Tranche.S)] = tranche_total_unutilized[epoch][uint256(Tranche.S)].add(amount); bv.deposit = amount; } // if (tranche == Tranche.AA) {} // v1: AA tranche disabled (S tranche is effectively AA) if (tranche == Tranche.A) { // Find capacity for S tranche to facilitate a deposit into A. Deposit is min(principal, capacity): restricted by the user's capital or S tranche capacity bv.capacity = (bv.available_utilized.add(bv.available_unutilized)).div(tranche_A_multiplier); bv.deposit = (amount < bv.capacity) ? amount : bv.capacity; bv.consumed = bv.deposit.mul(tranche_A_multiplier); if (bv.consumed <= bv.available_utilized) { // Take capacity from tranche S utilized first and give virtual utilized balance to AA bv.utilized_consumed = bv.consumed; } else { // Take capacity from tranche S utilized and tranche S unutilized and give virtual utilized/unutilized balances to AA bv.utilized_consumed = bv.available_utilized; bv.unutilized_consumed = bv.consumed.sub(bv.utilized_consumed); tranche_S_virtual_unutilized[epoch][uint256(Tranche.AA)] = tranche_S_virtual_unutilized[epoch][uint256(Tranche.AA)].add(bv.unutilized_consumed); } tranche_S_virtual_utilized[epoch][uint256(Tranche.AA)] = tranche_S_virtual_utilized[epoch][uint256(Tranche.AA)].add(bv.utilized_consumed); if (bv.deposit < amount) bv.change = amount.sub(bv.deposit); } // Calculate the dsec for deposited DAI uint256 dsec = bv.deposit.mul(get_seconds_until_epoch_end(epoch)); // Update pool principal eternal and epoch state pool_principal = pool_principal.add(bv.deposit); // Add DAI to principal totals epoch_principal[epoch] = epoch_principal[epoch].add(bv.deposit); // Add DAI total balance for epoch // Update dsec and principal balance state tranche_total_dsec[epoch][uint256(tranche)] = tranche_total_dsec[epoch][uint256(tranche)].add(dsec); tranche_total_principal[epoch][uint256(tranche)] = tranche_total_principal[epoch][uint256(tranche)].add(bv.deposit); // Transfer DAI from LP to pool IERC20(base_asset_address).safeTransferFrom(msg.sender, address(this), bv.deposit); if (tranche == Tranche.A) IERC20(SFI_address).safeTransferFrom(msg.sender, address(this), bv.deposit / SFI_ratio); // Mint Saffron LP epoch 1 tranche dsec tokens and transfer them to sender SaffronLPBalanceToken(dsec_token_addresses[epoch][uint256(tranche)]).mint(msg.sender, dsec); // Mint Saffron LP epoch 1 tranche principal tokens and transfer them to sender SaffronLPBalanceToken(principal_token_addresses[epoch][uint256(tranche)]).mint(msg.sender, bv.deposit); emit TrancheBalance(uint256(tranche), bv.deposit, bv.deposit, bv.capacity, bv.change, bv.consumed, bv.utilized_consumed, bv.unutilized_consumed, bv.available_utilized, bv.available_unutilized); emit DsecGeneration(get_seconds_until_epoch_end(epoch), bv.deposit, dsec, dsec_token_addresses[epoch][uint256(tranche)], epoch, uint256(tranche), msg.sender, principal_token_addresses[epoch][uint256(tranche)]); emit AddLiquidity(pool_principal, epoch_principal[epoch], 0, tranche_total_principal[epoch][uint256(tranche)], tranche_total_dsec[epoch][uint256(tranche)]); } event WindDownEpochSFI(uint256 previous_epoch, uint256 S_SFI, uint256 AA_SFI, uint256 A_SFI); event WindDownEpochState(uint256 epoch, uint256 tranche_S_interest, uint256 tranche_AA_interest, uint256 tranche_A_interest, uint256 tranche_SFI_earnings_S, uint256 tranche_SFI_earnings_AA, uint256 tranche_SFI_earnings_A); struct WindDownVars { uint256 previous_epoch; uint256 epoch_interest; uint256 epoch_dsec; uint256 tranche_A_interest_ratio; uint256 tranche_A_interest; uint256 tranche_S_interest; } function wind_down_epoch(uint256 epoch, uint256 amount_sfi) public override { require(msg.sender == strategy, "must be strategy"); require(!epoch_wound_down[epoch], "epoch already wound down"); uint256 current_epoch = get_current_epoch(); require(epoch < current_epoch, "cannot wind down future epoch"); WindDownVars memory wind_down = WindDownVars({ previous_epoch: 0, epoch_interest: 0, epoch_dsec: 0, tranche_A_interest_ratio: 0, tranche_A_interest: 0, tranche_S_interest: 0 }); wind_down.previous_epoch = current_epoch - 1; require(block.timestamp >= get_epoch_end(wind_down.previous_epoch), "can't call before epoch ended"); // Calculate SFI earnings per tranche tranche_SFI_earned[epoch][uint256(Tranche.S)] = TRANCHE_SFI_MULTIPLIER.S.mul(amount_sfi).div(100000); tranche_SFI_earned[epoch][uint256(Tranche.AA)] = TRANCHE_SFI_MULTIPLIER.AA.mul(amount_sfi).div(100000); tranche_SFI_earned[epoch][uint256(Tranche.A)] = TRANCHE_SFI_MULTIPLIER.A.mul(amount_sfi).div(100000); emit WindDownEpochSFI(wind_down.previous_epoch, tranche_SFI_earned[epoch][uint256(Tranche.S)], tranche_SFI_earned[epoch][uint256(Tranche.AA)], tranche_SFI_earned[epoch][uint256(Tranche.A)]); // Calculate interest earnings per tranche // Wind down will calculate interest and SFI earned by each tranche for the epoch which has ended // Liquidity cannot be removed until wind_down_epoch is called and epoch_wound_down[epoch] is set to true // Calculate pool_interest // v0, v1: we only have one adapter ISaffronAdapter adapter = ISaffronAdapter(best_adapter_address); wind_down.epoch_interest = adapter.get_interest(adapter_total_principal); pool_interest = pool_interest.add(wind_down.epoch_interest); // Total dsec // TODO: assert (dsec.totalSupply == epoch_dsec) wind_down.epoch_dsec = tranche_total_dsec[epoch][uint256(Tranche.S)].add(tranche_total_dsec[epoch][uint256(Tranche.A)]); wind_down.tranche_A_interest_ratio = tranche_total_dsec[epoch][uint256(Tranche.A)].mul(1 ether).div(wind_down.epoch_dsec); // Calculate tranche share of interest wind_down.tranche_A_interest = (wind_down.epoch_interest.mul(wind_down.tranche_A_interest_ratio).div(1 ether)).mul(tranche_A_multiplier); wind_down.tranche_S_interest = wind_down.epoch_interest.sub(wind_down.tranche_A_interest); // Update state for remove_liquidity tranche_interest_earned[epoch][uint256(Tranche.S)] = wind_down.tranche_S_interest; tranche_interest_earned[epoch][uint256(Tranche.AA)] = 0; tranche_interest_earned[epoch][uint256(Tranche.A)] = wind_down.tranche_A_interest; // Distribute SFI earnings to S tranche based on S tranche % share of dsec via vdsec emit WindDownEpochState(epoch, wind_down.tranche_S_interest, 0, wind_down.tranche_A_interest, uint256(tranche_SFI_earned[epoch][uint256(Tranche.S)]), uint256(tranche_SFI_earned[epoch][uint256(Tranche.AA)]), uint256(tranche_SFI_earned[epoch][uint256(Tranche.A)])); epoch_wound_down[epoch] = true; delete wind_down; } event RemoveLiquidityDsec(uint256 dsec_percent, uint256 interest_owned, uint256 SFI_owned); event RemoveLiquidityPrincipal(uint256 principal); function remove_liquidity(address dsec_token_address, uint256 dsec_amount, address principal_token_address, uint256 principal_amount) external override { require(dsec_amount > 0 || principal_amount > 0, "can't remove 0"); ISaffronAdapter best_adapter = ISaffronAdapter(best_adapter_address); uint256 interest_owned; uint256 SFI_earn; uint256 SFI_return; uint256 dsec_percent; // Update state for removal via dsec token if (dsec_token_address != address(0x0) && dsec_amount > 0) { // Get info about the v1 dsec token from its address and check that it exists SaffronLPTokenInfo memory token_info = saffron_LP_token_info[dsec_token_address]; require(token_info.exists, "balance token lookup failed"); SaffronLPBalanceToken sbt = SaffronLPBalanceToken(dsec_token_address); require(sbt.balanceOf(msg.sender) >= dsec_amount, "insufficient dsec balance"); // Token epoch must be a past epoch uint256 token_epoch = token_info.epoch; require(token_info.token_type == LPTokenType.dsec, "bad dsec address"); require(token_epoch == 3, "v1.3: bal token epoch must be 3"); require(epoch_wound_down[token_epoch], "can't remove from wound up epoch"); uint256 tranche_dsec = tranche_total_dsec[token_epoch][uint256(token_info.tranche)]; // Dsec gives user claim over a tranche's earned SFI and interest dsec_percent = (tranche_dsec == 0) ? 0 : dsec_amount.mul(1 ether).div(tranche_dsec); interest_owned = tranche_interest_earned[token_epoch][uint256(token_info.tranche)].mul(dsec_percent) / 1 ether; SFI_earn = tranche_SFI_earned[token_epoch][uint256(token_info.tranche)].mul(dsec_percent) / 1 ether; tranche_interest_earned[token_epoch][uint256(token_info.tranche)] = tranche_interest_earned[token_epoch][uint256(token_info.tranche)].sub(interest_owned); tranche_SFI_earned[token_epoch][uint256(token_info.tranche)] = tranche_SFI_earned[token_epoch][uint256(token_info.tranche)].sub(SFI_earn); tranche_total_dsec[token_epoch][uint256(token_info.tranche)] = tranche_total_dsec[token_epoch][uint256(token_info.tranche)].sub(dsec_amount); pool_interest = pool_interest.sub(interest_owned); } // Update state for removal via principal token if (principal_token_address != address(0x0) && principal_amount > 0) { // Get info about the v1 dsec token from its address and check that it exists SaffronLPTokenInfo memory token_info = saffron_LP_token_info[principal_token_address]; require(token_info.exists, "balance token info lookup failed"); SaffronLPBalanceToken sbt = SaffronLPBalanceToken(principal_token_address); require(sbt.balanceOf(msg.sender) >= principal_amount, "insufficient principal balance"); // Token epoch must be a past epoch uint256 token_epoch = token_info.epoch; require(token_info.token_type == LPTokenType.principal, "bad balance token address"); require(token_epoch == 3, "v1.3: bal token epoch must be 3"); require(epoch_wound_down[token_epoch], "can't remove from wound up epoch"); tranche_total_principal[token_epoch][uint256(token_info.tranche)] = tranche_total_principal[token_epoch][uint256(token_info.tranche)].sub(principal_amount); epoch_principal[token_epoch] = epoch_principal[token_epoch].sub(principal_amount); pool_principal = pool_principal.sub(principal_amount); adapter_total_principal = adapter_total_principal.sub(principal_amount); if (token_info.tranche == Tranche.A) SFI_return = principal_amount / SFI_ratio; } // Transfer if (dsec_token_address != address(0x0) && dsec_amount > 0) { SaffronLPBalanceToken sbt = SaffronLPBalanceToken(dsec_token_address); require(sbt.balanceOf(msg.sender) >= dsec_amount, "insufficient dsec balance"); sbt.burn(msg.sender, dsec_amount); best_adapter.return_capital(interest_owned, msg.sender); IERC20(SFI_address).safeTransfer(msg.sender, SFI_earn); emit RemoveLiquidityDsec(dsec_percent, interest_owned, SFI_earn); } if (principal_token_address != address(0x0) && principal_amount > 0) { SaffronLPBalanceToken sbt = SaffronLPBalanceToken(principal_token_address); require(sbt.balanceOf(msg.sender) >= principal_amount, "insufficient principal balance"); sbt.burn(msg.sender, principal_amount); best_adapter.return_capital(principal_amount, msg.sender); IERC20(SFI_address).safeTransfer(msg.sender, SFI_return); emit RemoveLiquidityPrincipal(principal_amount); } require((dsec_token_address != address(0x0) && dsec_amount > 0) || (principal_token_address != address(0x0) && principal_amount > 0), "no action performed"); } // Strategy contract calls this to deploy capital to platforms event StrategicDeploy(address adapter_address, uint256 amount, uint256 epoch); function hourly_strategy(address adapter_address) external override { require(msg.sender == strategy, "must be strategy"); require(!_shutdown, "pool shutdown"); uint256 epoch = get_current_epoch(); best_adapter_address = adapter_address; ISaffronAdapter best_adapter = ISaffronAdapter(adapter_address); uint256 amount = IERC20(base_asset_address).balanceOf(address(this)); // Update utilized/unutilized epoch-tranche state tranche_total_utilized[epoch][uint256(Tranche.S)] = tranche_total_utilized[epoch][uint256(Tranche.S)].add(tranche_total_unutilized[epoch][uint256(Tranche.S)]); tranche_total_utilized[epoch][uint256(Tranche.A)] = tranche_total_utilized[epoch][uint256(Tranche.A)].add(tranche_total_unutilized[epoch][uint256(Tranche.A)]); tranche_S_virtual_utilized[epoch][uint256(Tranche.AA)] = tranche_S_virtual_utilized[epoch][uint256(Tranche.AA)].add(tranche_S_virtual_unutilized[epoch][uint256(Tranche.AA)]); tranche_total_unutilized[epoch][uint256(Tranche.S)] = 0; tranche_total_unutilized[epoch][uint256(Tranche.A)] = 0; tranche_S_virtual_unutilized[epoch][uint256(Tranche.AA)] = 0; // Add principal to adapter total adapter_total_principal = adapter_total_principal.add(amount); emit StrategicDeploy(adapter_address, amount, epoch); // Move base assets to adapter and deploy IERC20(base_asset_address).safeTransfer(adapter_address, amount); best_adapter.deploy_capital(amount); } function shutdown() external override { require(msg.sender == strategy, "must be strategy"); require(block.timestamp > get_epoch_end(1) - 1 days, "trying to shutdown too early"); _shutdown = true; } /*** GOVERNANCE ***/ function set_governance(address to) external override { require(msg.sender == governance, "must be governance"); governance = to; } function set_best_adapter(address to) external { require(msg.sender == governance, "must be governance"); best_adapter_address = to; } /*** TIME UTILITY FUNCTIONS ***/ function get_epoch_end(uint256 epoch) public view returns (uint256) { return epoch_cycle.start_date.add(epoch.add(1).mul(epoch_cycle.duration)); } function get_current_epoch() public view returns (uint256) { require(block.timestamp > epoch_cycle.start_date, "before epoch 0"); return (block.timestamp - epoch_cycle.start_date) / epoch_cycle.duration; } function get_seconds_until_epoch_end(uint256 epoch) public view returns (uint256) { return epoch_cycle.start_date.add(epoch.add(1).mul(epoch_cycle.duration)).sub(block.timestamp); } /*** GETTERS ***/ function get_available_S_balances() public view returns(uint256, uint256) { uint256 epoch = get_current_epoch(); uint256 AA_A_utilized = tranche_S_virtual_utilized[epoch][uint256(Tranche.A)].add(tranche_S_virtual_utilized[epoch][uint256(Tranche.AA)]); uint256 AA_A_unutilized = tranche_S_virtual_unutilized[epoch][uint256(Tranche.A)].add(tranche_S_virtual_unutilized[epoch][uint256(Tranche.AA)]); uint256 S_utilized = tranche_total_utilized[epoch][uint256(Tranche.S)]; uint256 S_unutilized = tranche_total_unutilized[epoch][uint256(Tranche.S)]; return ((S_utilized > AA_A_utilized ? S_utilized - AA_A_utilized : 0), (S_unutilized > AA_A_unutilized ? S_unutilized - AA_A_unutilized : 0)); } function get_epoch_cycle_params() external view override returns (uint256, uint256) { return (epoch_cycle.start_date, epoch_cycle.duration); } function get_base_asset_address() external view override returns(address) { return base_asset_address; } //***** ADAPTER FUNCTIONS *****// // Delete adapters (v0: for v0 wind-down) function delete_adapters() external { require(msg.sender == governance, "must be governance"); require(block.timestamp > epoch_cycle.start_date + 10 weeks, "too soon"); delete adapters; } event ErcSwept(address who, address to, address token, uint256 amount); function erc_sweep(address _token, address _to) public { require(msg.sender == governance, "must be governance"); require(_token != base_asset_address && _token != SFI_address, "cannot sweep pool assets"); IERC20 tkn = IERC20(_token); uint256 tBal = tkn.balanceOf(address(this)); tkn.safeTransfer(_to, tBal); emit ErcSwept(msg.sender, _to, _token, tBal); } event Swept(address who, address to, uint256 sfiBal, uint256 baseBal); function sweep(address _to) public { require(msg.sender == governance, "must be governance"); IERC20 tkn = IERC20(address(SFI_address)); uint256 sfiBal = tkn.balanceOf(address(this)); tkn.safeTransfer(_to, sfiBal); IERC20 base = IERC20(address(base_asset_address)); uint256 baseBal = base.balanceOf(address(this)); base.safeTransfer(_to, baseBal); emit Swept(msg.sender, _to, sfiBal, baseBal); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"address","name":"_base_asset","type":"address"},{"internalType":"address","name":"_SFI_address","type":"address"},{"internalType":"bool","name":"epoch_cycle_reset","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"new_pool_principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"new_epoch_principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"new_eternal_balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"new_tranche_principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"new_tranche_dsec","type":"uint256"}],"name":"AddLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time_remaining","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dsec","type":"uint256"},{"indexed":false,"internalType":"address","name":"dsec_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche","type":"uint256"},{"indexed":false,"internalType":"address","name":"user_address","type":"address"},{"indexed":false,"internalType":"address","name":"principal_token_addr","type":"address"}],"name":"DsecGeneration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"who","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ErcSwept","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dsec_percent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"interest_owned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"SFI_owned","type":"uint256"}],"name":"RemoveLiquidityDsec","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"principal","type":"uint256"}],"name":"RemoveLiquidityPrincipal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"adapter_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"StrategicDeploy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"who","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"sfiBal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseBal","type":"uint256"}],"name":"Swept","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tranche","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capacity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"change","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"consumed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"utilized_consumed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unutilized_consumed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"available_utilized","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"available_unutilized","type":"uint256"}],"name":"TrancheBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previous_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"S_SFI","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"AA_SFI","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"A_SFI","type":"uint256"}],"name":"WindDownEpochSFI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_S_interest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_AA_interest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_A_interest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_SFI_earnings_S","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_SFI_earnings_AA","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_SFI_earnings_A","type":"uint256"}],"name":"WindDownEpochState","type":"event"},{"inputs":[],"name":"SFI_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SFI_ratio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANCHE_SFI_MULTIPLIER","outputs":[{"internalType":"uint256","name":"S","type":"uint256"},{"internalType":"uint256","name":"AA","type":"uint256"},{"internalType":"uint256","name":"A","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_shutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adapter_total_principal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum ISaffronBase.Tranche","name":"tranche","type":"uint8"}],"name":"add_liquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"base_asset_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"best_adapter_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delete_adapters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"dsec_token_addresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch_cycle","outputs":[{"internalType":"uint256","name":"start_date","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epoch_principal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epoch_wound_down","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"erc_sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"get_available_S_balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_base_asset_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_current_epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_epoch_cycle_params","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"get_epoch_end","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"get_seconds_until_epoch_end","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter_address","type":"address"}],"name":"hourly_strategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address[]","name":"saffron_LP_dsec_token_addresses","type":"address[]"},{"internalType":"address[]","name":"saffron_LP_principal_token_addresses","type":"address[]"}],"name":"new_epoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool_interest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool_principal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"principal_token_addresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dsec_token_address","type":"address"},{"internalType":"uint256","name":"dsec_amount","type":"uint256"},{"internalType":"address","name":"principal_token_address","type":"address"},{"internalType":"uint256","name":"principal_amount","type":"uint256"}],"name":"remove_liquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"set_best_adapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"set_governance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tranche_A_multiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_SFI_earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_S_virtual_unutilized","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_S_virtual_utilized","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_interest_earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_total_dsec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_total_principal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_total_unutilized","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_total_utilized","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"amount_sfi","type":"uint256"}],"name":"wind_down_epoch","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6007805460ff19169055635f9ebf6060808190526212750060a0819052600c91909155600d5561012060405262015f9060c0819052600060e0819052612710610100819052601a92909255601b55601c553480156200005d57600080fd5b506040516200513138038062005131833981810160405260808110156200008357600080fd5b5080516020820151604083015160609093015160008054336001600160a01b0319918216179091556001805482166001600160a01b0380861691909117909155600b8054831682871617905560028054909216908616179055600a6005556101f46006559192909180620000fb5762127500620000ff565b6104b05b62ffffff16600d55806200011857635f9ebf6062000121565b600d5460030242035b600c5550505050614ff980620001386000396000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637425ffec11610186578063ac3dbb12116100e3578063df4cbfd811610097578063ebd485fc11610071578063ebd485fc1461086d578063f034c18d1461088a578063fc0e74d114610892576102de565b8063df4cbfd814610840578063dfe537961461085d578063e653be7414610865576102de565b8063bc87f62c116100c8578063bc87f62c146107f2578063c6b483ab14610815578063d2e7a1bb1461081d576102de565b8063ac3dbb12146107e2578063bc4ce844146107ea576102de565b80639b53e3661161013a578063a684b5991161011f578063a684b599146107b5578063a72b6c30146107d2578063a8c62e76146107da576102de565b80639b53e3661461076c578063a20f527214610792576102de565b8063837a9bc71161016b578063837a9bc71461071e57806384518744146107265780639392f6f214610749576102de565b80637425ffec146106d857806380e0f15f146106fb576102de565b806348373cc61161023f5780635b1caa2f116101f35780636bd6f696116101cd5780636bd6f6961461068a57806370cdf476146106ad57806370d4ac4e146106d0576102de565b80635b1caa2f1461050d5780636120f0dc146105545780636acc25be14610682576102de565b806354d0c8a01161022457806354d0c8a0146104da578063580f346f146104e25780635aa6e67514610505576102de565b806348373cc61461048b5780634c1a4259146104a7576102de565b80630f78dac31161029657806322cef9d31161027b57806322cef9d3146104405780632a0ccc88146104485780632b666fcf14610450576102de565b80630f78dac3146103f95780631816f3141461041f576102de565b8063070313fa116102c7578063070313fa1461034b5780630bbb0c581461037e5780630efb8dbd146103ca576102de565b806301681a62146102e357806302b6215914610318575b600080fd5b610316600480360360208110156102f957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661089a565b005b6103166004803603602081101561032e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610b0d565b6103166004803603602081101561036157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610bdf565b6103a16004803603604081101561039457600080fd5b5080359060200135610cac565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103e7600480360360208110156103e057600080fd5b5035610cf7565b60408051918252519081900360200190f35b6103166004803603604081101561040f57600080fd5b508035906020013560ff16610d25565b6104276116b0565b6040805192835260208301919091528051918290030190f35b6103a16116b9565b6103a16116da565b6103166004803603604081101561046657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166116f6565b610493611950565b604080519115158252519081900360200190f35b610316600480360360208110156104bd57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611959565b6103a1611db0565b6103e7600480360360408110156104f857600080fd5b5080359060200135611dcc565b6103a1611e01565b6103166004803603608081101561052357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135916040820135169060600135611e1d565b6103166004803603606081101561056a57600080fd5b8135919081019060408101602082013564010000000081111561058c57600080fd5b82018360208201111561059e57600080fd5b803590602001918460208302840111640100000000831117156105c057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561061057600080fd5b82018360208201111561062257600080fd5b8035906020019184602083028401116401000000008311171561064457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612f2e945050505050565b6103e7613b0e565b6103e7600480360360408110156106a057600080fd5b5080359060200135613b14565b6103a1600480360360408110156106c357600080fd5b5080359060200135613b24565b6103e7613b34565b6103e7600480360360408110156106ee57600080fd5b5080359060200135613b3a565b6103166004803603604081101561071157600080fd5b5080359060200135613b4a565b6103e76141e2565b6103e76004803603604081101561073c57600080fd5b508035906020013561426a565b6103e76004803603604081101561075f57600080fd5b508035906020013561427a565b61077461428a565b60408051938452602084019290925282820152519081900360600190f35b6103e7600480360360408110156107a857600080fd5b5080359060200135614296565b610493600480360360208110156107cb57600080fd5b50356142a6565b6103a16142bb565b6103a16142d7565b6103e76142f3565b6103e76142f9565b6103e76004803603604081101561080857600080fd5b50803590602001356142ff565b6103e761430f565b6103e76004803603604081101561083357600080fd5b5080359060200135614315565b6103e76004803603602081101561085657600080fd5b5035614325565b610427614351565b610316614441565b6103e76004803603602081101561088357600080fd5b503561454a565b61042761456b565b610316614575565b60005473ffffffffffffffffffffffffffffffffffffffff16331461092057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600254604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b15801561099657600080fd5b505afa1580156109aa573d6000803e3d6000fd5b505050506040513d60208110156109c057600080fd5b505190506109e573ffffffffffffffffffffffffffffffffffffffff831684836146a4565b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b158015610a5b57600080fd5b505afa158015610a6f573d6000803e3d6000fd5b505050506040513d6020811015610a8557600080fd5b50519050610aaa73ffffffffffffffffffffffffffffffffffffffff831686836146a4565b6040805133815273ffffffffffffffffffffffffffffffffffffffff871660208201528082018590526060810183905290517f8496dda4d04919fec296be83f4d7d178dafb7c0d3abe1553c092f1466e8f29289181900360800190a15050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b9357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b6007805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c6557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60108281548110610cbc57600080fd5b90600052602060002090600302018160038110610cd857600080fd5b015473ffffffffffffffffffffffffffffffffffffffff169150829050565b600d54600090610d1f90610d1690610d10856001614736565b906147b1565b600c5490614736565b92915050565b60075460ff1615610d9757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000816002811115610da557fe5b1480610dbc57506002816002811115610dba57fe5b145b610e11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180614f736027913960400191505060405180910390fd5b6000610e1b6141e2565b905082610e8957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f63616e2774206164642030000000000000000000000000000000000000000000604482015290519081900360640190fd5b80600314610ef857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f76312e333a206d7573742062652065706f63682033206f6e6c79000000000000604482015290519081900360640190fd5b610f00614da3565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509050610f4c614351565b60e083015260c08201526000836002811115610f6457fe5b1415610fc157610f9e8460158481548110610f7b57fe5b600091825260208220600390910201905b60038110610f9657fe5b015490614736565b60158381548110610fab57fe5b6000918252602082206003919091020101558381525b6002836002811115610fcf57fe5b141561110557610ffc600554610ff68360e001518460c0015161473690919063ffffffff16565b90614824565b602082018190528410611013578060200151611015565b835b80825260055461102591906147b1565b6060820181905260c08201511061104557606081015160808201526110b3565b60c081015160808201819052606082015161105f91614866565b60a08201819052601780546110919291908590811061107a57fe5b600091825260209091206003909102016001610f8c565b6017838154811061109e57fe5b60009182526020909120600390910201600101555b6110c881608001516016848154811061107a57fe5b601683815481106110d557fe5b600091825260209091206003909102016001015580518411156111055780516110ff908590614866565b60408201525b600061111b61111384614325565b8351906147b1565b825160035491925061112d9190614736565b6003558151600e805461115f9291908690811061114657fe5b906000526020600020015461473690919063ffffffff16565b600e848154811061116c57fe5b90600052602060002001819055506111a5816012858154811061118b57fe5b9060005260206000209060030201866002811115610f8c57fe5b601284815481106111b257fe5b90600052602060002090600302018560028111156111cc57fe5b600381106111d657fe5b01558151601380546111ee9291908690811061118b57fe5b601384815481106111fb57fe5b906000526020600020906003020185600281111561121557fe5b6003811061121f57fe5b0155815160015461124c9173ffffffffffffffffffffffffffffffffffffffff90911690339030906148a8565b600284600281111561125a57fe5b141561129757611297333060065485600001518161127457fe5b60025473ffffffffffffffffffffffffffffffffffffffff1693929190046148a8565b601083815481106112a457fe5b90600052602060002090600302018460028111156112be57fe5b600381106112c857fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101849052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b15801561134057600080fd5b505af1158015611354573d6000803e3d6000fd5b505050506011838154811061136557fe5b906000526020600020906003020184600281111561137f57fe5b6003811061138957fe5b01548251604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101929092525173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b15801561140357600080fd5b505af1158015611417573d6000803e3d6000fd5b505050507f058587cdc5efcef45583dc39e6884e853b5c5aef182afe72ca96db6fa1c85c2184600281111561144857fe5b8360000151846000015185602001518660400151876060015188608001518960a001518a60c001518b60e00151604051808b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a17fc7d2d1a5a726dc6005e76316c12eb5ee642296cc38c1b996651599995a480f3c6114f384614325565b8360000151836010878154811061150657fe5b906000526020600020906003020188600281111561152057fe5b6003811061152a57fe5b015473ffffffffffffffffffffffffffffffffffffffff168789600281111561154f57fe5b3360118b8154811061155d57fe5b90600052602060002090600302018c600281111561157757fe5b6003811061158157fe5b01546040805198895260208901979097528787019590955273ffffffffffffffffffffffffffffffffffffffff9384166060880152608087019290925260a0860152811660c08501521660e083015251908190036101000190a17f1d69fb63e4692a6ae9a9b249224c389569da92d8e2e96243d71fd6b3bc3055d9600354600e858154811061160c57fe5b906000526020600020015460006013878154811061162657fe5b906000526020600020906003020188600281111561164057fe5b6003811061164a57fe5b01546012888154811061165957fe5b906000526020600020906003020189600281111561167357fe5b6003811061167d57fe5b01546040805195865260208601949094528484019290925260608401526080830152519081900360a00190a15050505050565b600c54600d5482565b600754610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461177c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff8381169116148015906117c2575060025473ffffffffffffffffffffffffffffffffffffffff838116911614155b61182d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616e6e6f7420737765657020706f6f6c206173736574730000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051839160009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561189e57600080fd5b505afa1580156118b2573d6000803e3d6000fd5b505050506040513d60208110156118c857600080fd5b505190506118ed73ffffffffffffffffffffffffffffffffffffffff831684836146a4565b6040805133815273ffffffffffffffffffffffffffffffffffffffff80861660208301528616818301526060810183905290517f2c4e64c7c0957a81c0076a0a3f3c7d9f0a5d6158292071c794436f829d12cfb79181900360800190a150505050565b60075460ff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff1633146119df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b60075460ff1615611a5157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000611a5b6141e2565b6007805473ffffffffffffffffffffffffffffffffffffffff808616610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff90921691909117909155600154604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051939450859360009392909216916370a0823191602480820192602092909190829003018186803b158015611b0b57600080fd5b505afa158015611b1f573d6000803e3d6000fd5b505050506040513d6020811015611b3557600080fd5b505160158054919250611b6b9185908110611b4c57fe5b60009182526020822060039190910201015460148581548110610f7b57fe5b60148481548110611b7857fe5b600091825260208220600391909102010181905550611bd560158481548110611b9d57fe5b600091825260209091206003909102016002015460148581548110611bbe57fe5b600091825260209091206003909102016002610f8c565b60148481548110611be257fe5b6000918252602090912060039091020160020181905550611c2a60178481548110611c0957fe5b60009182526020909120600390910201600101546016858154811061107a57fe5b60168481548110611c3757fe5b600091825260208220600160039092020101919091556015805485908110611c5b57fe5b60009182526020822060039190910201919091556015805485908110611c7d57fe5b600091825260208220600260039092020101919091556017805485908110611ca157fe5b6000918252602090912060039091020160010155600854611cc29082614736565b6008556040805173ffffffffffffffffffffffffffffffffffffffff861681526020810183905280820185905290517ffc2f950130d4b652317d4d65735fe2c28b9b137f09199cc20367042dedafb6d59181900360600190a1600154611d3f9073ffffffffffffffffffffffffffffffffffffffff1685836146a4565b8173ffffffffffffffffffffffffffffffffffffffff16631d2e62d9826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611d9257600080fd5b505af1158015611da6573d6000803e3d6000fd5b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60128281548110611ddc57600080fd5b90600052602060002090600302018160038110611df857600080fd5b01549150829050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6000831180611e2c5750600081115b611e9757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63616e27742072656d6f76652030000000000000000000000000000000000000604482015290519081900360640190fd5b60075473ffffffffffffffffffffffffffffffffffffffff610100909104811690600090819081908190891615801590611ed15750600088115b1561246157611ede614de8565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601d60209081526040918290208251608081018452815460ff9081161515825260018301549382019390935260028083015491949293928501929190911690811115611f4257fe5b6002811115611f4d57fe5b81526020016002820160019054906101000a900460ff166001811115611f6f57fe5b6001811115611f7a57fe5b9052508051909150611fed57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f62616c616e636520746f6b656e206c6f6f6b7570206661696c65640000000000604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518b918b9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561205d57600080fd5b505afa158015612071573d6000803e3d6000fd5b505050506040513d602081101561208757600080fd5b505110156120f657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b602082015160008360600151600181111561210d57fe5b1461217957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6261642064736563206164647265737300000000000000000000000000000000604482015290519081900360640190fd5b806003146121e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f76312e333a2062616c20746f6b656e2065706f6368206d757374206265203300604482015290519081900360640190fd5b6000818152600f602052604090205460ff1661226557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b60006012828154811061227457fe5b90600052602060002090600302018460400151600281111561229257fe5b6003811061229c57fe5b0154905080156122c1576122bc81610ff68e670de0b6b3a76400006147b1565b6122c4565b60005b9450670de0b6b3a764000061231086601885815481106122e057fe5b9060005260206000209060030201876040015160028111156122fe57fe5b6003811061230857fe5b0154906147b1565b8161231757fe5b049750670de0b6b3a764000061233486601985815481106122e057fe5b8161233b57fe5b04965061237f886018848154811061234f57fe5b90600052602060002090600302018660400151600281111561236d57fe5b6003811061237757fe5b015490614866565b6018838154811061238c57fe5b9060005260206000209060030201856040015160028111156123aa57fe5b600381106123b457fe5b01819055506123ca876019848154811061234f57fe5b601983815481106123d757fe5b9060005260206000209060030201856040015160028111156123f557fe5b600381106123ff57fe5b01819055506124158c6012848154811061234f57fe5b6012838154811061242257fe5b90600052602060002090600302018560400151600281111561244057fe5b6003811061244a57fe5b01556004546124599089614866565b600455505050505b73ffffffffffffffffffffffffffffffffffffffff8716158015906124865750600086115b1561291157612493614de8565b73ffffffffffffffffffffffffffffffffffffffff88166000908152601d60209081526040918290208251608081018452815460ff90811615158252600183015493820193909352600280830154919492939285019291909116908111156124f757fe5b600281111561250257fe5b81526020016002820160019054906101000a900460ff16600181111561252457fe5b600181111561252f57fe5b90525080519091506125a257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f62616c616e636520746f6b656e20696e666f206c6f6f6b7570206661696c6564604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518991899173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561261257600080fd5b505afa158015612626573d6000803e3d6000fd5b505050506040513d602081101561263c57600080fd5b505110156126ab57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b60208201516001836060015160018111156126c257fe5b1461272e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6261642062616c616e636520746f6b656e206164647265737300000000000000604482015290519081900360640190fd5b8060031461279d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f76312e333a2062616c20746f6b656e2065706f6368206d757374206265203300604482015290519081900360640190fd5b6000818152600f602052604090205460ff1661281a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b612849896013838154811061282b57fe5b90600052602060002090600302018560400151600281111561236d57fe5b6013828154811061285657fe5b90600052602060002090600302018460400151600281111561287457fe5b6003811061287e57fe5b01819055506128ad89600e838154811061289457fe5b906000526020600020015461486690919063ffffffff16565b600e82815481106128ba57fe5b6000918252602090912001556003546128d3908a614866565b6003556008546128e3908a614866565b6008556002836040015160028111156128f857fe5b141561290d57600654898161290957fe5b0494505b5050505b73ffffffffffffffffffffffffffffffffffffffff8916158015906129365750600088115b15612bc357604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518a918a9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156129ab57600080fd5b505afa1580156129bf573d6000803e3d6000fd5b505050506040513d60208110156129d557600080fd5b50511015612a4457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b604080517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b9052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612ab857600080fd5b505af1158015612acc573d6000803e3d6000fd5b5050604080517f96728a7200000000000000000000000000000000000000000000000000000000815260048101899052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612b4457600080fd5b505af1158015612b58573d6000803e3d6000fd5b5050600254612b81925073ffffffffffffffffffffffffffffffffffffffff16905033866146a4565b604080518381526020810187905280820186905290517f45d0d3545b4cb7d20e6d592c7158c445e3acda72c55074ab88b0027aa9c2d2789181900360600190a1505b73ffffffffffffffffffffffffffffffffffffffff871615801590612be85750600086115b15612e6857604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518891889173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015612c5d57600080fd5b505afa158015612c71573d6000803e3d6000fd5b505050506040513d6020811015612c8757600080fd5b50511015612cf657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b604080517f9dc29fac00000000000000000000000000000000000000000000000000000000815233600482015260248101899052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612d6a57600080fd5b505af1158015612d7e573d6000803e3d6000fd5b5050604080517f96728a72000000000000000000000000000000000000000000000000000000008152600481018b9052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612df657600080fd5b505af1158015612e0a573d6000803e3d6000fd5b5050600254612e33925073ffffffffffffffffffffffffffffffffffffffff16905033856146a4565b6040805188815290517ffbcc912eee8a56d51e3708fe32ba15f4191e6f92b2ccae4f00bbb544dba49f029181900360200190a1505b73ffffffffffffffffffffffffffffffffffffffff891615801590612e8d5750600088115b80612eb8575073ffffffffffffffffffffffffffffffffffffffff871615801590612eb85750600086115b612f2357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6e6f20616374696f6e20706572666f726d656400000000000000000000000000604482015290519081900360640190fd5b505050505050505050565b6013548314612f9e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696d70726f706572206e65772065706f63680000000000000000000000000000604482015290519081900360640190fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461302457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600e8054600181810190925560007fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90910181905560408051606081018252828152602081018390529081018290526012805493840181559091526130b19160039081027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444019190614e0f565b506040805160608101825260008082526020820181905291810182905260138054600181018255925261310c9160039081027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090019190614e0f565b50604080516060810182526000808252602082018190529181018290526014805460018101825592526131679160039081027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec019190614e0f565b50604080516060810182526000808252602082018190529181018290526015805460018101825592526131c29160039081027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475019190614e0f565b506040805160608101825260008082526020820181905291810182905260168054600181018255925261321d9160039081027fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b5124289019190614e0f565b50604080516060810182526000808252602082018190529181018290526017805460018101825592526132789160039081027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15019190614e0f565b50604080516060810182526000808252602082018190529181018290526018805460018101825592526132d39160039081027fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e019190614e0f565b506040805160608101825260008082526020820181905291810182905260198054600181018255925261332e9160039081027f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695019190614e0f565b506040805160608101909152601090808460008151811061334b57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460018151811061337d57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825201846002815181106133af57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206133f69260039081029091019190614e52565b506040805160608101909152601190808360008151811061341357fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360018151811061344557fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360028151811061347757fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206134be9260039081029091019190614e52565b506040805160808101825260018152602081018590529081016000815260200160009052601d60008481815181106134f257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561358257fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156135c357fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160009052601d60008460018151811061360057fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561369057fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156136d157fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160009052601d60008460028151811061370c57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561379c57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137dd57fe5b021790555050604080516080810182526001815260208101869052915081016000815260200160019052601d600083818151811061381757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360028111156138a757fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156138e857fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160019052601d60008360018151811061392557fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360028111156139b557fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156139f657fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160019052601d600083600281518110613a3157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836002811115613ac157fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115613b0257fe5b02179055505050505050565b60055481565b60188281548110611ddc57600080fd5b60118281548110610cbc57600080fd5b60045481565b60148281548110611ddc57600080fd5b600b5473ffffffffffffffffffffffffffffffffffffffff163314613bd057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b6000828152600f602052604090205460ff1615613c4e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f65706f636820616c726561647920776f756e6420646f776e0000000000000000604482015290519081900360640190fd5b6000613c586141e2565b9050808310613cc857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e6e6f742077696e6420646f776e206675747572652065706f6368000000604482015290519081900360640190fd5b613cd0614ebf565b506040805160c081018252600060208201819052918101829052606081018290526080810182905260a08101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201808252613d2f90610cf7565b421015613d9d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e27742063616c6c206265666f72652065706f636820656e646564000000604482015290519081900360640190fd5b601a54613db390620186a090610ff690866147b1565b60198581548110613dc057fe5b600091825260208220600391909102010155601b54613de890620186a090610ff690866147b1565b60198581548110613df557fe5b6000918252602090912060039091020160010155601c54613e1f90620186a090610ff690866147b1565b60198581548110613e2c57fe5b60009182526020909120600390910201600201558051601980547f02ac5b59c8ff91aed9818435a4a06bf88afedae653001d8d7086f29057eca88c92919087908110613e7457fe5b60009182526020822060039190910201015460198781548110613e9357fe5b600091825260209091206003909102016001015460198881548110613eb457fe5b6000918252602090912060039091020160020154604080519485526020850193909352838301919091526060830152519081900360800190a1600754600854604080517f1a2b383200000000000000000000000000000000000000000000000000000000815260048101929092525161010090920473ffffffffffffffffffffffffffffffffffffffff16918291631a2b38329160248083019260209291908290030181600087803b158015613f6957600080fd5b505af1158015613f7d573d6000803e3d6000fd5b505050506040513d6020811015613f9357600080fd5b505160208301819052600454613fa891614736565b600481905550613fdf60128681548110613fbe57fe5b600091825260209091206003909102016002015460128781548110610f7b57fe5b8260400181815250506140208260400151610ff6670de0b6b3a76400006012898154811061400957fe5b6000918252602090912060039091020160026122fe565b60608301819052600554602084015161404b92610d1091670de0b6b3a764000091610ff691906147b1565b60808301819052602083015161406091614866565b60a08301819052601880548790811061407557fe5b6000918252602082206003919091020191909155601880548790811061409757fe5b6000918252602090912060039091020160010155608082015160188054879081106140be57fe5b60009182526020909120600390910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858360a001516000856080015160198a8154811061411057fe5b60009182526020822060039190910201015460198b8154811061412f57fe5b600091825260209091206003909102016001015460198c8154811061415057fe5b6000918252602090912060039091020160020154604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190a16000858152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556141da614ebf565b505050505050565b600c54600090421161425557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6265666f72652065706f63682030000000000000000000000000000000000000604482015290519081900360640190fd5b600d54600c5442038161426457fe5b04905090565b60198281548110611ddc57600080fd5b60138281548110611ddc57600080fd5b601a54601b54601c5483565b60178281548110611ddc57600080fd5b600f6020526000908152604090205460ff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b600b5473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b60085481565b60168281548110611ddc57600080fd5b60035481565b60158281548110611ddc57600080fd5b6000610d1f4261434b610d16600c60010154610d1060018861473690919063ffffffff16565b90614866565b600080600061435e6141e2565b905060006143936016838154811061437257fe5b600091825260209091206003909102016001015460168481548110611bbe57fe5b905060006143c8601784815481106143a757fe5b600091825260209091206003909102016001015460178581548110611bbe57fe5b90506000601484815481106143d957fe5b60009182526020822060039190910201015490506000601585815481106143fc57fe5b600091825260208220600391909102010154905083821161441e576000614422565b8382035b838211614430576000614434565b8382035b9650965050505050509091565b60005473ffffffffffffffffffffffffffffffffffffffff1633146144c757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600c54625c490001421161453c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f746f6f20736f6f6e000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61454860096000614ef5565b565b600e818154811061455a57600080fd5b600091825260209091200154905081565b600c54600d549091565b600b5473ffffffffffffffffffffffffffffffffffffffff1633146145fb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b620151806146096001610cf7565b03421161467757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f747279696e6720746f2073687574646f776e20746f6f206561726c7900000000604482015290519081900360640190fd5b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052614731908490614943565b505050565b6000828201838110156147aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000826147c057506000610d1f565b828202828482816147cd57fe5b04146147aa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614f526021913960400191505060405180910390fd5b60006147aa83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a1b565b60006147aa83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614ad7565b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261493d908590614943565b50505050565b60606149a5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614b4b9092919063ffffffff16565b805190915015614731578080602001905160208110156149c457600080fd5b5051614731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614f9a602a913960400191505060405180910390fd5b60008183614ac1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614a86578181015183820152602001614a6e565b50505050905090810190601f168015614ab35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614acd57fe5b0495945050505050565b60008184841115614b43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315614a86578181015183820152602001614a6e565b505050900390565b6060614b5a8484600085614b62565b949350505050565b606082471015614bbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614f2c6026913960400191505060405180910390fd5b614bc685614d1d565b614c3157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310614c9b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614c5e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614cfd576040519150601f19603f3d011682016040523d82523d6000602084013e614d02565b606091505b5091509150614d12828286614d23565b979650505050505050565b3b151590565b60608315614d325750816147aa565b825115614d425782518084602001fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451859391928392604401919085019080838360008315614a86578181015183820152602001614a6e565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60408051608081018252600080825260208201819052909182019081526020016000905290565b8260038101928215614e42579160200282015b82811115614e42578251829060ff16905591602001919060010190614e22565b50614e4e929150614f16565b5090565b8260038101928215614e42579160200282015b82811115614e4257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614e65565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5080546000825590600052602060002090810190614f139190614f16565b50565b5b80821115614e4e5760008155600101614f1756fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7776313a2063616e2774206164645f6c697175696469747920696e746f204141207472616e6368655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212206aa2cb9fcd16e399176f627215467b79f952c69d823080c7d6f473ed1d97dd4264736f6c63430007040033000000000000000000000000f4aa3b60ead8df9768816f20710a99bbf372393c0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102de5760003560e01c80637425ffec11610186578063ac3dbb12116100e3578063df4cbfd811610097578063ebd485fc11610071578063ebd485fc1461086d578063f034c18d1461088a578063fc0e74d114610892576102de565b8063df4cbfd814610840578063dfe537961461085d578063e653be7414610865576102de565b8063bc87f62c116100c8578063bc87f62c146107f2578063c6b483ab14610815578063d2e7a1bb1461081d576102de565b8063ac3dbb12146107e2578063bc4ce844146107ea576102de565b80639b53e3661161013a578063a684b5991161011f578063a684b599146107b5578063a72b6c30146107d2578063a8c62e76146107da576102de565b80639b53e3661461076c578063a20f527214610792576102de565b8063837a9bc71161016b578063837a9bc71461071e57806384518744146107265780639392f6f214610749576102de565b80637425ffec146106d857806380e0f15f146106fb576102de565b806348373cc61161023f5780635b1caa2f116101f35780636bd6f696116101cd5780636bd6f6961461068a57806370cdf476146106ad57806370d4ac4e146106d0576102de565b80635b1caa2f1461050d5780636120f0dc146105545780636acc25be14610682576102de565b806354d0c8a01161022457806354d0c8a0146104da578063580f346f146104e25780635aa6e67514610505576102de565b806348373cc61461048b5780634c1a4259146104a7576102de565b80630f78dac31161029657806322cef9d31161027b57806322cef9d3146104405780632a0ccc88146104485780632b666fcf14610450576102de565b80630f78dac3146103f95780631816f3141461041f576102de565b8063070313fa116102c7578063070313fa1461034b5780630bbb0c581461037e5780630efb8dbd146103ca576102de565b806301681a62146102e357806302b6215914610318575b600080fd5b610316600480360360208110156102f957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661089a565b005b6103166004803603602081101561032e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610b0d565b6103166004803603602081101561036157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610bdf565b6103a16004803603604081101561039457600080fd5b5080359060200135610cac565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103e7600480360360208110156103e057600080fd5b5035610cf7565b60408051918252519081900360200190f35b6103166004803603604081101561040f57600080fd5b508035906020013560ff16610d25565b6104276116b0565b6040805192835260208301919091528051918290030190f35b6103a16116b9565b6103a16116da565b6103166004803603604081101561046657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166116f6565b610493611950565b604080519115158252519081900360200190f35b610316600480360360208110156104bd57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611959565b6103a1611db0565b6103e7600480360360408110156104f857600080fd5b5080359060200135611dcc565b6103a1611e01565b6103166004803603608081101561052357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135916040820135169060600135611e1d565b6103166004803603606081101561056a57600080fd5b8135919081019060408101602082013564010000000081111561058c57600080fd5b82018360208201111561059e57600080fd5b803590602001918460208302840111640100000000831117156105c057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561061057600080fd5b82018360208201111561062257600080fd5b8035906020019184602083028401116401000000008311171561064457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612f2e945050505050565b6103e7613b0e565b6103e7600480360360408110156106a057600080fd5b5080359060200135613b14565b6103a1600480360360408110156106c357600080fd5b5080359060200135613b24565b6103e7613b34565b6103e7600480360360408110156106ee57600080fd5b5080359060200135613b3a565b6103166004803603604081101561071157600080fd5b5080359060200135613b4a565b6103e76141e2565b6103e76004803603604081101561073c57600080fd5b508035906020013561426a565b6103e76004803603604081101561075f57600080fd5b508035906020013561427a565b61077461428a565b60408051938452602084019290925282820152519081900360600190f35b6103e7600480360360408110156107a857600080fd5b5080359060200135614296565b610493600480360360208110156107cb57600080fd5b50356142a6565b6103a16142bb565b6103a16142d7565b6103e76142f3565b6103e76142f9565b6103e76004803603604081101561080857600080fd5b50803590602001356142ff565b6103e761430f565b6103e76004803603604081101561083357600080fd5b5080359060200135614315565b6103e76004803603602081101561085657600080fd5b5035614325565b610427614351565b610316614441565b6103e76004803603602081101561088357600080fd5b503561454a565b61042761456b565b610316614575565b60005473ffffffffffffffffffffffffffffffffffffffff16331461092057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600254604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b15801561099657600080fd5b505afa1580156109aa573d6000803e3d6000fd5b505050506040513d60208110156109c057600080fd5b505190506109e573ffffffffffffffffffffffffffffffffffffffff831684836146a4565b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b158015610a5b57600080fd5b505afa158015610a6f573d6000803e3d6000fd5b505050506040513d6020811015610a8557600080fd5b50519050610aaa73ffffffffffffffffffffffffffffffffffffffff831686836146a4565b6040805133815273ffffffffffffffffffffffffffffffffffffffff871660208201528082018590526060810183905290517f8496dda4d04919fec296be83f4d7d178dafb7c0d3abe1553c092f1466e8f29289181900360800190a15050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b9357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b6007805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c6557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60108281548110610cbc57600080fd5b90600052602060002090600302018160038110610cd857600080fd5b015473ffffffffffffffffffffffffffffffffffffffff169150829050565b600d54600090610d1f90610d1690610d10856001614736565b906147b1565b600c5490614736565b92915050565b60075460ff1615610d9757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000816002811115610da557fe5b1480610dbc57506002816002811115610dba57fe5b145b610e11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180614f736027913960400191505060405180910390fd5b6000610e1b6141e2565b905082610e8957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f63616e2774206164642030000000000000000000000000000000000000000000604482015290519081900360640190fd5b80600314610ef857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f76312e333a206d7573742062652065706f63682033206f6e6c79000000000000604482015290519081900360640190fd5b610f00614da3565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509050610f4c614351565b60e083015260c08201526000836002811115610f6457fe5b1415610fc157610f9e8460158481548110610f7b57fe5b600091825260208220600390910201905b60038110610f9657fe5b015490614736565b60158381548110610fab57fe5b6000918252602082206003919091020101558381525b6002836002811115610fcf57fe5b141561110557610ffc600554610ff68360e001518460c0015161473690919063ffffffff16565b90614824565b602082018190528410611013578060200151611015565b835b80825260055461102591906147b1565b6060820181905260c08201511061104557606081015160808201526110b3565b60c081015160808201819052606082015161105f91614866565b60a08201819052601780546110919291908590811061107a57fe5b600091825260209091206003909102016001610f8c565b6017838154811061109e57fe5b60009182526020909120600390910201600101555b6110c881608001516016848154811061107a57fe5b601683815481106110d557fe5b600091825260209091206003909102016001015580518411156111055780516110ff908590614866565b60408201525b600061111b61111384614325565b8351906147b1565b825160035491925061112d9190614736565b6003558151600e805461115f9291908690811061114657fe5b906000526020600020015461473690919063ffffffff16565b600e848154811061116c57fe5b90600052602060002001819055506111a5816012858154811061118b57fe5b9060005260206000209060030201866002811115610f8c57fe5b601284815481106111b257fe5b90600052602060002090600302018560028111156111cc57fe5b600381106111d657fe5b01558151601380546111ee9291908690811061118b57fe5b601384815481106111fb57fe5b906000526020600020906003020185600281111561121557fe5b6003811061121f57fe5b0155815160015461124c9173ffffffffffffffffffffffffffffffffffffffff90911690339030906148a8565b600284600281111561125a57fe5b141561129757611297333060065485600001518161127457fe5b60025473ffffffffffffffffffffffffffffffffffffffff1693929190046148a8565b601083815481106112a457fe5b90600052602060002090600302018460028111156112be57fe5b600381106112c857fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101849052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b15801561134057600080fd5b505af1158015611354573d6000803e3d6000fd5b505050506011838154811061136557fe5b906000526020600020906003020184600281111561137f57fe5b6003811061138957fe5b01548251604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101929092525173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b15801561140357600080fd5b505af1158015611417573d6000803e3d6000fd5b505050507f058587cdc5efcef45583dc39e6884e853b5c5aef182afe72ca96db6fa1c85c2184600281111561144857fe5b8360000151846000015185602001518660400151876060015188608001518960a001518a60c001518b60e00151604051808b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a17fc7d2d1a5a726dc6005e76316c12eb5ee642296cc38c1b996651599995a480f3c6114f384614325565b8360000151836010878154811061150657fe5b906000526020600020906003020188600281111561152057fe5b6003811061152a57fe5b015473ffffffffffffffffffffffffffffffffffffffff168789600281111561154f57fe5b3360118b8154811061155d57fe5b90600052602060002090600302018c600281111561157757fe5b6003811061158157fe5b01546040805198895260208901979097528787019590955273ffffffffffffffffffffffffffffffffffffffff9384166060880152608087019290925260a0860152811660c08501521660e083015251908190036101000190a17f1d69fb63e4692a6ae9a9b249224c389569da92d8e2e96243d71fd6b3bc3055d9600354600e858154811061160c57fe5b906000526020600020015460006013878154811061162657fe5b906000526020600020906003020188600281111561164057fe5b6003811061164a57fe5b01546012888154811061165957fe5b906000526020600020906003020189600281111561167357fe5b6003811061167d57fe5b01546040805195865260208601949094528484019290925260608401526080830152519081900360a00190a15050505050565b600c54600d5482565b600754610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461177c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff8381169116148015906117c2575060025473ffffffffffffffffffffffffffffffffffffffff838116911614155b61182d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616e6e6f7420737765657020706f6f6c206173736574730000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051839160009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561189e57600080fd5b505afa1580156118b2573d6000803e3d6000fd5b505050506040513d60208110156118c857600080fd5b505190506118ed73ffffffffffffffffffffffffffffffffffffffff831684836146a4565b6040805133815273ffffffffffffffffffffffffffffffffffffffff80861660208301528616818301526060810183905290517f2c4e64c7c0957a81c0076a0a3f3c7d9f0a5d6158292071c794436f829d12cfb79181900360800190a150505050565b60075460ff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff1633146119df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b60075460ff1615611a5157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000611a5b6141e2565b6007805473ffffffffffffffffffffffffffffffffffffffff808616610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff90921691909117909155600154604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051939450859360009392909216916370a0823191602480820192602092909190829003018186803b158015611b0b57600080fd5b505afa158015611b1f573d6000803e3d6000fd5b505050506040513d6020811015611b3557600080fd5b505160158054919250611b6b9185908110611b4c57fe5b60009182526020822060039190910201015460148581548110610f7b57fe5b60148481548110611b7857fe5b600091825260208220600391909102010181905550611bd560158481548110611b9d57fe5b600091825260209091206003909102016002015460148581548110611bbe57fe5b600091825260209091206003909102016002610f8c565b60148481548110611be257fe5b6000918252602090912060039091020160020181905550611c2a60178481548110611c0957fe5b60009182526020909120600390910201600101546016858154811061107a57fe5b60168481548110611c3757fe5b600091825260208220600160039092020101919091556015805485908110611c5b57fe5b60009182526020822060039190910201919091556015805485908110611c7d57fe5b600091825260208220600260039092020101919091556017805485908110611ca157fe5b6000918252602090912060039091020160010155600854611cc29082614736565b6008556040805173ffffffffffffffffffffffffffffffffffffffff861681526020810183905280820185905290517ffc2f950130d4b652317d4d65735fe2c28b9b137f09199cc20367042dedafb6d59181900360600190a1600154611d3f9073ffffffffffffffffffffffffffffffffffffffff1685836146a4565b8173ffffffffffffffffffffffffffffffffffffffff16631d2e62d9826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611d9257600080fd5b505af1158015611da6573d6000803e3d6000fd5b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60128281548110611ddc57600080fd5b90600052602060002090600302018160038110611df857600080fd5b01549150829050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6000831180611e2c5750600081115b611e9757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63616e27742072656d6f76652030000000000000000000000000000000000000604482015290519081900360640190fd5b60075473ffffffffffffffffffffffffffffffffffffffff610100909104811690600090819081908190891615801590611ed15750600088115b1561246157611ede614de8565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601d60209081526040918290208251608081018452815460ff9081161515825260018301549382019390935260028083015491949293928501929190911690811115611f4257fe5b6002811115611f4d57fe5b81526020016002820160019054906101000a900460ff166001811115611f6f57fe5b6001811115611f7a57fe5b9052508051909150611fed57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f62616c616e636520746f6b656e206c6f6f6b7570206661696c65640000000000604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518b918b9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561205d57600080fd5b505afa158015612071573d6000803e3d6000fd5b505050506040513d602081101561208757600080fd5b505110156120f657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b602082015160008360600151600181111561210d57fe5b1461217957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6261642064736563206164647265737300000000000000000000000000000000604482015290519081900360640190fd5b806003146121e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f76312e333a2062616c20746f6b656e2065706f6368206d757374206265203300604482015290519081900360640190fd5b6000818152600f602052604090205460ff1661226557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b60006012828154811061227457fe5b90600052602060002090600302018460400151600281111561229257fe5b6003811061229c57fe5b0154905080156122c1576122bc81610ff68e670de0b6b3a76400006147b1565b6122c4565b60005b9450670de0b6b3a764000061231086601885815481106122e057fe5b9060005260206000209060030201876040015160028111156122fe57fe5b6003811061230857fe5b0154906147b1565b8161231757fe5b049750670de0b6b3a764000061233486601985815481106122e057fe5b8161233b57fe5b04965061237f886018848154811061234f57fe5b90600052602060002090600302018660400151600281111561236d57fe5b6003811061237757fe5b015490614866565b6018838154811061238c57fe5b9060005260206000209060030201856040015160028111156123aa57fe5b600381106123b457fe5b01819055506123ca876019848154811061234f57fe5b601983815481106123d757fe5b9060005260206000209060030201856040015160028111156123f557fe5b600381106123ff57fe5b01819055506124158c6012848154811061234f57fe5b6012838154811061242257fe5b90600052602060002090600302018560400151600281111561244057fe5b6003811061244a57fe5b01556004546124599089614866565b600455505050505b73ffffffffffffffffffffffffffffffffffffffff8716158015906124865750600086115b1561291157612493614de8565b73ffffffffffffffffffffffffffffffffffffffff88166000908152601d60209081526040918290208251608081018452815460ff90811615158252600183015493820193909352600280830154919492939285019291909116908111156124f757fe5b600281111561250257fe5b81526020016002820160019054906101000a900460ff16600181111561252457fe5b600181111561252f57fe5b90525080519091506125a257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f62616c616e636520746f6b656e20696e666f206c6f6f6b7570206661696c6564604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518991899173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561261257600080fd5b505afa158015612626573d6000803e3d6000fd5b505050506040513d602081101561263c57600080fd5b505110156126ab57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b60208201516001836060015160018111156126c257fe5b1461272e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6261642062616c616e636520746f6b656e206164647265737300000000000000604482015290519081900360640190fd5b8060031461279d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f76312e333a2062616c20746f6b656e2065706f6368206d757374206265203300604482015290519081900360640190fd5b6000818152600f602052604090205460ff1661281a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b612849896013838154811061282b57fe5b90600052602060002090600302018560400151600281111561236d57fe5b6013828154811061285657fe5b90600052602060002090600302018460400151600281111561287457fe5b6003811061287e57fe5b01819055506128ad89600e838154811061289457fe5b906000526020600020015461486690919063ffffffff16565b600e82815481106128ba57fe5b6000918252602090912001556003546128d3908a614866565b6003556008546128e3908a614866565b6008556002836040015160028111156128f857fe5b141561290d57600654898161290957fe5b0494505b5050505b73ffffffffffffffffffffffffffffffffffffffff8916158015906129365750600088115b15612bc357604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518a918a9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156129ab57600080fd5b505afa1580156129bf573d6000803e3d6000fd5b505050506040513d60208110156129d557600080fd5b50511015612a4457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b604080517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b9052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612ab857600080fd5b505af1158015612acc573d6000803e3d6000fd5b5050604080517f96728a7200000000000000000000000000000000000000000000000000000000815260048101899052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612b4457600080fd5b505af1158015612b58573d6000803e3d6000fd5b5050600254612b81925073ffffffffffffffffffffffffffffffffffffffff16905033866146a4565b604080518381526020810187905280820186905290517f45d0d3545b4cb7d20e6d592c7158c445e3acda72c55074ab88b0027aa9c2d2789181900360600190a1505b73ffffffffffffffffffffffffffffffffffffffff871615801590612be85750600086115b15612e6857604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518891889173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015612c5d57600080fd5b505afa158015612c71573d6000803e3d6000fd5b505050506040513d6020811015612c8757600080fd5b50511015612cf657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b604080517f9dc29fac00000000000000000000000000000000000000000000000000000000815233600482015260248101899052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612d6a57600080fd5b505af1158015612d7e573d6000803e3d6000fd5b5050604080517f96728a72000000000000000000000000000000000000000000000000000000008152600481018b9052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612df657600080fd5b505af1158015612e0a573d6000803e3d6000fd5b5050600254612e33925073ffffffffffffffffffffffffffffffffffffffff16905033856146a4565b6040805188815290517ffbcc912eee8a56d51e3708fe32ba15f4191e6f92b2ccae4f00bbb544dba49f029181900360200190a1505b73ffffffffffffffffffffffffffffffffffffffff891615801590612e8d5750600088115b80612eb8575073ffffffffffffffffffffffffffffffffffffffff871615801590612eb85750600086115b612f2357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6e6f20616374696f6e20706572666f726d656400000000000000000000000000604482015290519081900360640190fd5b505050505050505050565b6013548314612f9e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696d70726f706572206e65772065706f63680000000000000000000000000000604482015290519081900360640190fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461302457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600e8054600181810190925560007fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90910181905560408051606081018252828152602081018390529081018290526012805493840181559091526130b19160039081027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444019190614e0f565b506040805160608101825260008082526020820181905291810182905260138054600181018255925261310c9160039081027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090019190614e0f565b50604080516060810182526000808252602082018190529181018290526014805460018101825592526131679160039081027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec019190614e0f565b50604080516060810182526000808252602082018190529181018290526015805460018101825592526131c29160039081027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475019190614e0f565b506040805160608101825260008082526020820181905291810182905260168054600181018255925261321d9160039081027fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b5124289019190614e0f565b50604080516060810182526000808252602082018190529181018290526017805460018101825592526132789160039081027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15019190614e0f565b50604080516060810182526000808252602082018190529181018290526018805460018101825592526132d39160039081027fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e019190614e0f565b506040805160608101825260008082526020820181905291810182905260198054600181018255925261332e9160039081027f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695019190614e0f565b506040805160608101909152601090808460008151811061334b57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460018151811061337d57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825201846002815181106133af57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206133f69260039081029091019190614e52565b506040805160608101909152601190808360008151811061341357fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360018151811061344557fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360028151811061347757fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206134be9260039081029091019190614e52565b506040805160808101825260018152602081018590529081016000815260200160009052601d60008481815181106134f257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561358257fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156135c357fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160009052601d60008460018151811061360057fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561369057fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156136d157fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160009052601d60008460028151811061370c57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561379c57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137dd57fe5b021790555050604080516080810182526001815260208101869052915081016000815260200160019052601d600083818151811061381757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360028111156138a757fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156138e857fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160019052601d60008360018151811061392557fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360028111156139b557fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156139f657fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160019052601d600083600281518110613a3157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836002811115613ac157fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115613b0257fe5b02179055505050505050565b60055481565b60188281548110611ddc57600080fd5b60118281548110610cbc57600080fd5b60045481565b60148281548110611ddc57600080fd5b600b5473ffffffffffffffffffffffffffffffffffffffff163314613bd057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b6000828152600f602052604090205460ff1615613c4e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f65706f636820616c726561647920776f756e6420646f776e0000000000000000604482015290519081900360640190fd5b6000613c586141e2565b9050808310613cc857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e6e6f742077696e6420646f776e206675747572652065706f6368000000604482015290519081900360640190fd5b613cd0614ebf565b506040805160c081018252600060208201819052918101829052606081018290526080810182905260a08101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201808252613d2f90610cf7565b421015613d9d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e27742063616c6c206265666f72652065706f636820656e646564000000604482015290519081900360640190fd5b601a54613db390620186a090610ff690866147b1565b60198581548110613dc057fe5b600091825260208220600391909102010155601b54613de890620186a090610ff690866147b1565b60198581548110613df557fe5b6000918252602090912060039091020160010155601c54613e1f90620186a090610ff690866147b1565b60198581548110613e2c57fe5b60009182526020909120600390910201600201558051601980547f02ac5b59c8ff91aed9818435a4a06bf88afedae653001d8d7086f29057eca88c92919087908110613e7457fe5b60009182526020822060039190910201015460198781548110613e9357fe5b600091825260209091206003909102016001015460198881548110613eb457fe5b6000918252602090912060039091020160020154604080519485526020850193909352838301919091526060830152519081900360800190a1600754600854604080517f1a2b383200000000000000000000000000000000000000000000000000000000815260048101929092525161010090920473ffffffffffffffffffffffffffffffffffffffff16918291631a2b38329160248083019260209291908290030181600087803b158015613f6957600080fd5b505af1158015613f7d573d6000803e3d6000fd5b505050506040513d6020811015613f9357600080fd5b505160208301819052600454613fa891614736565b600481905550613fdf60128681548110613fbe57fe5b600091825260209091206003909102016002015460128781548110610f7b57fe5b8260400181815250506140208260400151610ff6670de0b6b3a76400006012898154811061400957fe5b6000918252602090912060039091020160026122fe565b60608301819052600554602084015161404b92610d1091670de0b6b3a764000091610ff691906147b1565b60808301819052602083015161406091614866565b60a08301819052601880548790811061407557fe5b6000918252602082206003919091020191909155601880548790811061409757fe5b6000918252602090912060039091020160010155608082015160188054879081106140be57fe5b60009182526020909120600390910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858360a001516000856080015160198a8154811061411057fe5b60009182526020822060039190910201015460198b8154811061412f57fe5b600091825260209091206003909102016001015460198c8154811061415057fe5b6000918252602090912060039091020160020154604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190a16000858152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556141da614ebf565b505050505050565b600c54600090421161425557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6265666f72652065706f63682030000000000000000000000000000000000000604482015290519081900360640190fd5b600d54600c5442038161426457fe5b04905090565b60198281548110611ddc57600080fd5b60138281548110611ddc57600080fd5b601a54601b54601c5483565b60178281548110611ddc57600080fd5b600f6020526000908152604090205460ff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b600b5473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b60085481565b60168281548110611ddc57600080fd5b60035481565b60158281548110611ddc57600080fd5b6000610d1f4261434b610d16600c60010154610d1060018861473690919063ffffffff16565b90614866565b600080600061435e6141e2565b905060006143936016838154811061437257fe5b600091825260209091206003909102016001015460168481548110611bbe57fe5b905060006143c8601784815481106143a757fe5b600091825260209091206003909102016001015460178581548110611bbe57fe5b90506000601484815481106143d957fe5b60009182526020822060039190910201015490506000601585815481106143fc57fe5b600091825260208220600391909102010154905083821161441e576000614422565b8382035b838211614430576000614434565b8382035b9650965050505050509091565b60005473ffffffffffffffffffffffffffffffffffffffff1633146144c757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600c54625c490001421161453c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f746f6f20736f6f6e000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61454860096000614ef5565b565b600e818154811061455a57600080fd5b600091825260209091200154905081565b600c54600d549091565b600b5473ffffffffffffffffffffffffffffffffffffffff1633146145fb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b620151806146096001610cf7565b03421161467757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f747279696e6720746f2073687574646f776e20746f6f206561726c7900000000604482015290519081900360640190fd5b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052614731908490614943565b505050565b6000828201838110156147aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000826147c057506000610d1f565b828202828482816147cd57fe5b04146147aa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614f526021913960400191505060405180910390fd5b60006147aa83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a1b565b60006147aa83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614ad7565b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261493d908590614943565b50505050565b60606149a5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614b4b9092919063ffffffff16565b805190915015614731578080602001905160208110156149c457600080fd5b5051614731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614f9a602a913960400191505060405180910390fd5b60008183614ac1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614a86578181015183820152602001614a6e565b50505050905090810190601f168015614ab35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614acd57fe5b0495945050505050565b60008184841115614b43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315614a86578181015183820152602001614a6e565b505050900390565b6060614b5a8484600085614b62565b949350505050565b606082471015614bbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614f2c6026913960400191505060405180910390fd5b614bc685614d1d565b614c3157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310614c9b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614c5e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614cfd576040519150601f19603f3d011682016040523d82523d6000602084013e614d02565b606091505b5091509150614d12828286614d23565b979650505050505050565b3b151590565b60608315614d325750816147aa565b825115614d425782518084602001fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451859391928392604401919085019080838360008315614a86578181015183820152602001614a6e565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60408051608081018252600080825260208201819052909182019081526020016000905290565b8260038101928215614e42579160200282015b82811115614e42578251829060ff16905591602001919060010190614e22565b50614e4e929150614f16565b5090565b8260038101928215614e42579160200282015b82811115614e4257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614e65565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5080546000825590600052602060002090810190614f139190614f16565b50565b5b80821115614e4e5760008155600101614f1756fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7776313a2063616e2774206164645f6c697175696469747920696e746f204141207472616e6368655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212206aa2cb9fcd16e399176f627215467b79f952c69d823080c7d6f473ed1d97dd4264736f6c63430007040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f4aa3b60ead8df9768816f20710a99bbf372393c0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _strategy (address): 0xF4aA3b60eaD8DF9768816F20710a99bBF372393c
Arg [1] : _base_asset (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [2] : _SFI_address (address): 0xb753428af26E81097e7fD17f40c88aaA3E04902c
Arg [3] : epoch_cycle_reset (bool): False
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f4aa3b60ead8df9768816f20710a99bbf372393c
Arg [1] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [2] : 000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
36251:26652:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62456:444;;;;;;;;;;;;;;;;-1:-1:-1;62456:444:0;;;;:::i;:::-;;59822:147;;;;;;;;;;;;;;;;-1:-1:-1;59822:147:0;;;;:::i;59672:144::-;;;;;;;;;;;;;;;;-1:-1:-1;59672:144:0;;;;:::i;38098:40::-;;;;;;;;;;;;;;;;-1:-1:-1;38098:40:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;60011:154;;;;;;;;;;;;;;;;-1:-1:-1;60011:154:0;;:::i;:::-;;;;;;;;;;;;;;;;44964:4127;;;;;;;;;;;;;;;;-1:-1:-1;44964:4127:0;;;;;;;;;:::i;37562:164::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;37118:35;;;:::i;36545:26::-;;;:::i;61983:393::-;;;;;;;;;;;;;;;;-1:-1:-1;61983:393:0;;;;;;;;;;;:::i;36967:29::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;57923:1497;;;;;;;;;;;;;;;;-1:-1:-1;57923:1497:0;;;;:::i;36451:33::-;;;:::i;38271:38::-;;;;;;;;;;;;;;;;-1:-1:-1;38271:38:0;;;;;;;:::i;36357:25::-;;;:::i;52954:4815::-;;;;;;;;;;;;;;;;-1:-1:-1;52954:4815:0;;;;;;;;;;;;;;;;;;;;;:::i;41047:2743::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41047:2743:0;;;;;;;;-1:-1:-1;41047:2743:0;;-1:-1:-1;;41047:2743:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41047:2743:0;;-1:-1:-1;41047:2743:0;;-1:-1:-1;;;;;41047:2743:0:i;36785:35::-;;;:::i;38898:43::-;;;;;;;;;;;;;;;;-1:-1:-1;38898:43:0;;;;;;;:::i;38182:45::-;;;;;;;;;;;;;;;;-1:-1:-1;38182:45:0;;;;;;;:::i;36689:28::-;;;:::i;38446:42::-;;;;;;;;;;;;;;;;-1:-1:-1;38446:42:0;;;;;;;:::i;49642:3157::-;;;;;;;;;;;;;;;;-1:-1:-1;49642:3157:0;;;;;;;:::i;60171:218::-;;;:::i;39002:38::-;;;;;;;;;;;;;;;;-1:-1:-1;39002:38:0;;;;;;;:::i;38355:43::-;;;;;;;;;;;;;;;;-1:-1:-1;38355:43:0;;;;;;;:::i;39371:115::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;38767:48;;;;;;;;;;;;;;;;-1:-1:-1;38767:48:0;;;;;;;:::i;37873:46::-;;;;;;;;;;;;;;;;-1:-1:-1;37873:46:0;;:::i;61497:112::-;;;:::i;37510:23::-;;;:::i;36867:24::-;;;:::i;37216:38::-;;;:::i;38638:46::-;;;;;;;;;;;;;;;;-1:-1:-1;38638:46:0;;;;;;;:::i;36598:29::-;;;:::i;38541:44::-;;;;;;;;;;;;;;;;-1:-1:-1;38541:44:0;;;;;;;:::i;60395:189::-;;;;;;;;;;;;;;;;-1:-1:-1;60395:189:0;;:::i;60611:722::-;;;:::i;61697:205::-;;;:::i;37770:32::-;;;;;;;;;;;;;;;;-1:-1:-1;37770:32:0;;:::i;61341:150::-;;;:::i;59426:216::-;;;:::i;62456:444::-;62520:10;;;;62506;:24;62498:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62590:11;;62627:28;;;;;;62649:4;62627:28;;;;;;62590:11;;;;;62562:10;;62590:11;;62627:13;;:28;;;;;;;;;;;;;;;62590:11;62627:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62627:28:0;;-1:-1:-1;62662:29:0;:16;;;62679:3;62627:28;62662:16;:29::i;:::-;62729:18;;62774:29;;;;;;62797:4;62774:29;;;;;;62729:18;;;;;62700:11;;62729:18;;62774:14;;:29;;;;;;;;;;;;;;;62729:18;62774:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62774:29:0;;-1:-1:-1;62810:31:0;:17;;;62828:3;62774:29;62810:17;:31::i;:::-;62855:39;;;62861:10;62855:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62456:444;;;;;:::o;59822:147::-;59898:10;;;;59884;:24;59876:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59938:20;:25;;;;;;;;;;;;;;;;;;59822:147::o;59672:144::-;59755:10;;;;59741;:24;59733:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59795:10;:15;;;;;;;;;;;;;;;59672:144::o;38098:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38098:40:0;;-1:-1:-1;38098:40:0:o;60011:154::-;60137:20;;60070:7;;60093:66;;60120:38;;:12;:5;60137:20;60120:9;:12::i;:::-;:16;;:38::i;:::-;60093:11;:22;;:26;:66::i;:::-;60086:73;60011:154;-1:-1:-1;;60011:154:0:o;44964:4127::-;45054:9;;;;45053:10;45045:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45107:9;45096:7;:20;;;;;;;;;:44;;;-1:-1:-1;45131:9:0;45120:7;:20;;;;;;;;;45096:44;45088:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45191:13;45207:19;:17;:19::i;:::-;45191:35;-1:-1:-1;45241:11:0;45233:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45283:5;45292:1;45283:10;45275:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45331:21;;:::i;:::-;45355:222;;;;;;;;45385:1;45355:222;;;;45406:1;45355:222;;;;45424:1;45355:222;;;;45446:1;45355:222;;;;45475:1;45355:222;;;;45506:1;45355:222;;;;45536:1;45355:222;;;;45568:1;45355:222;;;45331:246;;45635:26;:24;:26::i;:::-;45608:23;;;45584:77;45585:21;;;45584:77;-1:-1:-1;45674:7:0;:20;;;;;;;;;45670:188;;;45759:63;45815:6;45759:24;45784:5;45759:31;;;;;;;;;;;;;;;;;;;;;45791:18;45759:51;;;;;;;;;;:55;:63::i;:::-;45705:24;45730:5;45705:31;;;;;;;;;;;;;;;;;;;;;:51;:117;45831:19;;;45670:188;45974:9;45963:7;:20;;;;;;;;;45959:1265;;;46170:78;46227:20;;46171:50;46197:2;:23;;;46171:2;:21;;;:25;;:50;;;;:::i;:::-;46170:56;;:78::i;:::-;46156:11;;;:92;;;46273:20;;46272:45;;46306:2;:11;;;46272:45;;;46297:6;46272:45;46258:59;;;46355:20;;46340:36;;46258:59;46340:14;:36::i;:::-;46326:11;;;:50;;;46404:21;;;;-1:-1:-1;46385:618:0;;46557:11;;;;46534:20;;;:34;46385:618;;;46745:21;;;;46722:20;;;:44;;;46802:11;;;;:37;;:15;:37::i;:::-;46777:22;;;:62;;;46909:28;:35;;:84;;46777:62;46909:28;46938:5;;46909:35;;;;;;;;;;;;;;;;;;;46953:10;46945:19;;46909:84;46850:28;46879:5;46850:35;;;;;;;;;;;;;;;;;;;;;46894:10;46850:56;:143;46385:618;47068:80;47127:2;:20;;;47068:26;47095:5;47068:33;;;;;;;:80;47011:26;47038:5;47011:33;;;;;;;;;;;;;;;;;;;;;47053:10;47011:54;:137;47161:10;;:19;-1:-1:-1;47157:59:0;;;47205:10;;47194:22;;:6;;:10;:22::i;:::-;47182:9;;;:34;47157:59;47277:12;47292:50;47307:34;47335:5;47307:27;:34::i;:::-;47292:10;;;:14;:50::i;:::-;47441:10;;47422:14;;47277:65;;-1:-1:-1;47422:30:0;;:14;:18;:30::i;:::-;47405:14;:47;47558:10;;47531:15;:22;;:38;;47558:10;47531:15;47547:5;;47531:22;;;;;;;;;;;;;;:26;;:38;;;;:::i;:::-;47506:15;47522:5;47506:22;;;;;;;;;;;;;;;:63;;;;47707:53;47755:4;47707:18;47726:5;47707:25;;;;;;;;;;;;;;;;;;47741:7;47733:16;;;;;;;47707:53;47661:18;47680:5;47661:25;;;;;;;;;;;;;;;;;;47695:7;47687:16;;;;;;;;47661:43;;;;;;;;:99;47871:10;;47818:23;:30;;:64;;47871:10;47818:23;47842:5;;47818:30;;;;;:64;47767:23;47791:5;47767:30;;;;;;;;;;;;;;;;;;47806:7;47798:16;;;;;;;;47767:48;;;;;;;;:115;47999:10;;47935:18;;47928:82;;47935:18;;;;;47972:10;;47992:4;;47928:43;:82::i;:::-;48032:9;48021:7;:20;;;;;;;;;48017:113;;;48043:87;48080:10;48100:4;48120:9;;48107:2;:10;;;:22;;;;;48050:11;;;;;48043:87;;48107:22;;48043:36;:87::i;:::-;48241:20;48262:5;48241:27;;;;;;;;;;;;;;;;;;48277:7;48269:16;;;;;;;;48241:45;;;;;;;;;48219:91;;;;;;48293:10;48219:91;;;;;;;;;;;;48241:45;;;;;48219:73;;:91;;;;;48241:45;;48219:91;;;;;;;;48241:45;;48219:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48426:25;48452:5;48426:32;;;;;;;;;;;;;;;;;;48467:7;48459:16;;;;;;;;48426:50;;;;;;;;;48495:10;;48404:102;;;;;;48483:10;48404:102;;;;;;;;;;;;48426:50;;;;;48404:78;;:102;;;;;48426:50;;48404:102;;;;;;;;48426:50;;48404:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48520:187;48543:7;48535:16;;;;;;;;48553:2;:10;;;48565:2;:10;;;48577:2;:11;;;48590:2;:9;;;48601:2;:11;;;48614:2;:20;;;48636:2;:22;;;48660:2;:21;;;48683:2;:23;;;48520:187;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48719:204;48734:34;48762:5;48734:27;:34::i;:::-;48770:2;:10;;;48782:4;48788:20;48809:5;48788:27;;;;;;;;;;;;;;;;;;48824:7;48816:16;;;;;;;;48788:45;;;;;;;;;;;48835:5;48850:7;48842:16;;;;;;;;48860:10;48872:25;48898:5;48872:32;;;;;;;;;;;;;;;;;;48913:7;48905:16;;;;;;;;48872:50;;;;;;;;;48719:204;;;;;;;;;;;;;;;;;;;;48872:50;48719:204;;;;;;;;;;;;;;;;;;;;;;;;48872:50;48719:204;;;;;;;;;48872:50;48719:204;;;48935:150;48948:14;;48964:15;48980:5;48964:22;;;;;;;;;;;;;;;;48988:1;48991:23;49015:5;48991:30;;;;;;;;;;;;;;;;;;49030:7;49022:16;;;;;;;;48991:48;;;;;;;;;49041:18;49060:5;49041:25;;;;;;;;;;;;;;;;;;49075:7;49067:16;;;;;;;;49041:43;;;;;;;;;48935:150;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44964:4127;;;;;:::o;37562:164::-;;;;;;:::o;37118:35::-;;;;;;;;;:::o;36545:26::-;;;;;;:::o;61983:393::-;62067:10;;;;62053;:24;62045:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62125:18;;;62115:28;;;62125:18;;62115:28;;;;:53;;-1:-1:-1;62157:11:0;;;62147:21;;;62157:11;;62147:21;;62115:53;62107:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62255:28;;;;;;62277:4;62255:28;;;;;;62226:6;;62206:10;;62255:13;;;;;;:28;;;;;;;;;;;;;;:13;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62255:28:0;;-1:-1:-1;62290:27:0;:16;;;62307:3;62255:28;62290:16;:27::i;:::-;62331:39;;;62340:10;62331:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61983:393;;;;:::o;36967:29::-;;;;;;:::o;57923:1497::-;58020:8;;;;58006:10;:22;57998:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58065:9;;;;58064:10;58056:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58099:13;58115:19;:17;:19::i;:::-;58141:20;:38;;;;;;;;;;;;;;;;;;;:20;58280:18;58273:51;;;;;;58318:4;58273:51;;;;;;58099:35;;-1:-1:-1;58164:15:0;;-1:-1:-1;;58280:18:0;;;;;58273:36;;:51;;;;;;;;;;;;;;;58280:18;58273:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58273:51:0;58494:24;:31;;58273:51;;-1:-1:-1;58440:106:0;;58519:5;;58494:31;;;;;;;;;;;;;;;;;;;:51;;58440:22;58463:5;58440:29;;;;;;;:106;58388:22;58411:5;58388:29;;;;;;;;;;;;;;;;;;;;;:49;:158;;;;58605:106;58659:24;58684:5;58659:31;;;;;;;;;;;;;;;;;;;;;58699:9;58659:51;;58605:22;58628:5;58605:29;;;;;;;;;;;;;;;;;;;;;58643:9;58635:18;;58605:106;58553:22;58576:5;58553:29;;;;;;;;;;;;;;;;;;;;;58591:9;58553:49;:158;;;;58775:116;58834:28;58863:5;58834:35;;;;;;;;;;;;;;;;;;;;;58878:10;58834:56;;58775:26;58802:5;58775:33;;;;;;;:116;58718:26;58745:5;58718:33;;;;;;;;;;;;;;;58760:10;58718:33;;;;;:54;:173;;;;58900:24;:31;;58925:5;;58900:31;;;;;;;;;;;;;;;;;;;:55;;;;58962:24;:31;;58987:5;;58962:31;;;;;;;;;;;;;59002:9;58962:31;;;;;:51;:55;;;;59024:28;:35;;59053:5;;59024:35;;;;;;;;;;;;;;;;;;;59068:10;59024:56;:60;59158:23;;:35;;59186:6;59158:27;:35::i;:::-;59132:23;:61;59205:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59315:18;;59308:64;;59315:18;;59348:15;59365:6;59308:39;:64::i;:::-;59379:12;:27;;;59407:6;59379:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57923:1497;;;;:::o;36451:33::-;;;;;;:::o;38271:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38271:38:0;;-1:-1:-1;38271:38:0:o;36357:25::-;;;;;;:::o;52954:4815::-;53135:1;53121:11;:15;:39;;;;53159:1;53140:16;:20;53121:39;53113:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53233:20;;;;;;;;;;53186:28;;;;;;;;53419:34;;;;;;:53;;;53471:1;53457:11;:15;53419:53;53415:1798;;;53568:36;;:::i;:::-;53607:41;;;;;;;:21;:41;;;;;;;;;53568:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53607:41;;53568:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53665:17:0;;53568:80;;-1:-1:-1;53657:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53809:25;;;;;;53823:10;53809:25;;;;;;53773:18;;53838:11;;53809:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53809:25:0;:40;;53801:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53955:16;;;;53933:19;53988:10;:21;;;:41;;;;;;;;;53980:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54067:11;54082:1;54067:16;54059:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54136:29;;;;:16;:29;;;;;;;;54128:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54211:20;54234:18;54253:11;54234:31;;;;;;;;;;;;;;;;;;54274:10;:18;;;54266:27;;;;;;;;54234:60;;;;;;;;;;-1:-1:-1;54394:17:0;;54393:68;;54419:42;54448:12;54419:24;:11;54435:7;54419:15;:24::i;:42::-;54393:68;;;54415:1;54393:68;54378:83;;54573:7;54487:83;54557:12;54487:23;54511:11;54487:36;;;;;;;;;;;;;;;;;;54532:10;:18;;;54524:27;;;;;;;;54487:65;;;;;;;;;;:69;:83::i;:::-;:93;;;;;;54470:110;;54681:7;54600:78;54665:12;54600:18;54619:11;54600:31;;;;;;;:78;:88;;;;;;54589:99;;54767:85;54837:14;54767:23;54791:11;54767:36;;;;;;;;;;;;;;;;;;54812:10;:18;;;54804:27;;;;;;;;54767:65;;;;;;;;;;:69;:85::i;:::-;54699:23;54723:11;54699:36;;;;;;;;;;;;;;;;;;54744:10;:18;;;54736:27;;;;;;;;54699:65;;;;;;;;:153;;;;54924:74;54989:8;54924:18;54943:11;54924:31;;;;;;;:74;54861:18;54880:11;54861:31;;;;;;;;;;;;;;;;;;54901:10;:18;;;54893:27;;;;;;;;54861:60;;;;;;;;:137;;;;55070:77;55135:11;55070:18;55089:11;55070:31;;;;;;;:77;55007:18;55026:11;55007:31;;;;;;;;;;;;;;;;;;55047:10;:18;;;55039:27;;;;;;;;55007:60;;;;;;;;:140;55172:13;;:33;;55190:14;55172:17;:33::i;:::-;55156:13;:49;-1:-1:-1;;;;53415:1798:0;55278:39;;;;;;;:63;;;55340:1;55321:16;:20;55278:63;55274:1329;;;55437:36;;:::i;:::-;55476:46;;;;;;;:21;:46;;;;;;;;;55437:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55476:46;;55437:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55539:17:0;;55437:85;;-1:-1:-1;55531:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55693:25;;;;;;55707:10;55693:25;;;;;;55652:23;;55722:16;;55693:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55693:25:0;:45;;55685:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55849:16;;;;55907:21;55882:10;:21;;;:46;;;;;;;;;55874:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55975:11;55990:1;55975:16;55967:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56044:29;;;;:16;:29;;;;;;;;56036:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56189:87;56259:16;56189:23;56213:11;56189:36;;;;;;;;;;;;;;;;;;56234:10;:18;;;56226:27;;;;;;;56189:87;56121:23;56145:11;56121:36;;;;;;;;;;;;;;;;;;56166:10;:18;;;56158:27;;;;;;;;56121:65;;;;;;;;:155;;;;56316:50;56349:16;56316:15;56332:11;56316:28;;;;;;;;;;;;;;;;:32;;:50;;;;:::i;:::-;56285:15;56301:11;56285:28;;;;;;;;;;;;;;;;;:81;56392:14;;:36;;56411:16;56392:18;:36::i;:::-;56375:14;:53;56463:23;;:45;;56491:16;56463:27;:45::i;:::-;56437:23;:71;56543:9;56521:10;:18;;;:31;;;;;;;;;56517:78;;;56586:9;;56567:16;:28;;;;;;56554:41;;56517:78;55274:1329;;;;56632:34;;;;;;;:53;;;56684:1;56670:11;:15;56632:53;56628:474;;;56782:25;;;;;;56796:10;56782:25;;;;;;56746:18;;56811:11;;56782:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56782:25:0;:40;;56774:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56861:33;;;;;;56870:10;56861:33;;;;;;;;;;;;:8;;;;;;:33;;;;;-1:-1:-1;;56861:33:0;;;;;;;-1:-1:-1;56861:8:0;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56903:55:0;;;;;;;;;;;;56947:10;56903:55;;;;;;:27;;;;-1:-1:-1;56903:27:0;;-1:-1:-1;56903:55:0;;;;;-1:-1:-1;;56903:55:0;;;;;;;-1:-1:-1;56903:27:0;:55;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56974:11:0;;56967:54;;-1:-1:-1;56974:11:0;;;-1:-1:-1;57000:10:0;57012:8;56967:32;:54::i;:::-;57035:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56628:474;;57112:39;;;;;;;:63;;;57174:1;57155:16;:20;57112:63;57108:491;;;57277:25;;;;;;57291:10;57277:25;;;;;;57236:23;;57306:16;;57277:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57277:25:0;:45;;57269:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57366:38;;;;;;57375:10;57366:38;;;;;;;;;;;;:8;;;;;;:38;;;;;-1:-1:-1;;57366:38:0;;;;;;;-1:-1:-1;57366:8:0;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57413:57:0;;;;;;;;;;;;57459:10;57413:57;;;;;;:27;;;;-1:-1:-1;57413:27:0;;-1:-1:-1;57413:57:0;;;;;-1:-1:-1;;57413:57:0;;;;;;;-1:-1:-1;57413:27:0;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57486:11:0;;57479:56;;-1:-1:-1;57486:11:0;;;-1:-1:-1;57512:10:0;57524;57479:32;:56::i;:::-;57549:42;;;;;;;;;;;;;;;;;57108:491;;57616:34;;;;;;;:53;;;57668:1;57654:11;:15;57616:53;57615:124;;;-1:-1:-1;57675:39:0;;;;;;;:63;;;57737:1;57718:16;:20;57675:63;57607:156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52954:4815;;;;;;;;;:::o;41047:2743::-;41208:23;:30;:39;;41200:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41285:10;;:24;:10;41299;41285:24;41277:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41341:15;:23;;;;;;;;;41362:1;41341:23;;;;;;;41371:32;;;;;;;;;;;41341:23;41371:32;;;;;;;;;;;:18;:32;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41410:37:0;;;;;;;;-1:-1:-1;41410:37:0;;;;;;;;;;;;;;;:23;:37;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41454:36:0;;;;;;;;-1:-1:-1;41454:36:0;;;;;;;;;;;;;;;:22;:36;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41497:38:0;;;;;;;;-1:-1:-1;41497:38:0;;;;;;;;;;;;;;;:24;:38;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41542:40:0;;;;;;;;-1:-1:-1;41542:40:0;;;;;;;;;;;;;;;:26;:40;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41589:42:0;;;;;;;;-1:-1:-1;41589:42:0;;;;;;;;;;;;;;;:28;:42;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41638:37:0;;;;;;;;-1:-1:-1;41638:37:0;;;;;;;;;;;;;;;:23;:37;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41682:32:0;;;;;;;;-1:-1:-1;41682:32:0;;;;;;;;;;;;;;;:18;:32;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41723:252:0;;;;;;;;;:20;;:252;41795:31;-1:-1:-1;41795:51:0;;;;;;;;;;;;;;;;;;;41723:252;;;;;41855:31;41895:10;41855:52;;;;;;;;;;;;;;;;;;;41723:252;;;;;41916:31;41956:9;41916:51;;;;;;;;;;;;;;;;;;;41723:252;;;;;;;;;;;;-1:-1:-1;41723:252:0;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41984:272:0;;;;;;;;;:25;;:272;42061:36;-1:-1:-1;42061:56:0;;;;;;;;;;;;;;;;;;;41984:272;;;;;42126:36;42171:10;42126:57;;;;;;;;;;;;;;;;;;;41984:272;;;;;42192:36;42237:9;42192:56;;;;;;;;;;;;;;;;;;;41984:272;;;;;;;;;;;;-1:-1:-1;41984:272:0;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;42435:133:0;;;;;;;;42471:4;42435:133;;;;;;;;;;;-1:-1:-1;42435:133:0;;;;42544:16;42435:133;;42358:21;:74;42380:31;42358:74;42380:51;;;;;;;;;;;;;;42358:74;;;;;;;;;;;;;;;:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42358:210:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42655:134:0;;;;;;;;42691:4;42655:134;;;;;;;;;;;-1:-1:-1;42655:134:0;;;;;;;;42765:16;42655:134;;42577:21;:75;42599:31;42639:10;42599:52;;;;;;;;;;;;;;42577:75;;;;;;;;;;;;;;;:212;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42577:212:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42875:133:0;;;;;;;;42911:4;42875:133;;;;;;;;;-1:-1:-1;42875:133:0;;42954:9;42875:133;;;;42984:16;42875:133;;42798:21;:74;42820:31;42860:9;42820:51;;;;;;;;;;;;;;42798:74;;;;;;;;;;;;;;;:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42798:210:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43186:138:0;;;;;;;;43222:4;43186:138;;;;;;;;;-1:-1:-1;43186:138:0;;-1:-1:-1;43186:138:0;;;;43295:21;43186:138;;43104:21;:79;43126:36;43104:79;43126:56;;;;;;;;;;;;;;43104:79;;;;;;;;;;;;;;;:220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43104:220:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43416:139:0;;;;;;;;43452:4;43416:139;;;;;;;;;;;-1:-1:-1;43416:139:0;;;;;;;;43526:21;43416:139;;43333:21;:80;43355:36;43400:10;43355:57;;;;;;;;;;;;;;43333:80;;;;;;;;;;;;;;;:222;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43333:222:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43646:138:0;;;;;;;;43682:4;43646:138;;;;;;;;;-1:-1:-1;43646:138:0;;43725:9;43646:138;;;;43755:21;43646:138;;43564:21;:79;43586:36;43631:9;43586:56;;;;;;;;;;;;;;43564:79;;;;;;;;;;;;;;;:220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43564:220:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;41047:2743:0:o;36785:35::-;;;;:::o;38898:43::-;;;;;;;;;;;;38182:45;;;;;;;;;;;;36689:28;;;;:::o;38446:42::-;;;;;;;;;;;;49642:3157;49747:8;;;;49733:10;:22;49725:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49792:23;;;;:16;:23;;;;;;;;49791:24;49783:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49851:21;49875:19;:17;:19::i;:::-;49851:43;;49917:13;49909:5;:21;49901:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49971:29;;:::i;:::-;-1:-1:-1;50003:191:0;;;;;;;;-1:-1:-1;50003:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50228:17;;;50201:44;;;50279:39;;:13;:39::i;:::-;50260:15;:58;;50252:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50453:22;:24;:52;;50498:6;;50453:40;;50482:10;50453:28;:40::i;:52::-;50404:18;50423:5;50404:25;;;;;;;;;;;;;;;;;;;;;:45;:101;50561:25;;:53;;50607:6;;50561:41;;50591:10;50561:29;:41::i;:53::-;50512:18;50531:5;50512:25;;;;;;;;;;;;;;;;;;;;;50546:10;50512:46;:102;50670:24;;:52;;50715:6;;50670:40;;50699:10;50670:28;:40::i;:52::-;50621:18;50640:5;50621:25;;;;;;;;;;;;;;;;;;;;;50655:9;50621:45;:101;50753:24;;50779:18;:25;;50736:184;;50753:24;50779:18;50798:5;;50779:25;;;;;;;;;;;;;;;;;;;:45;;50826:18;50845:5;50826:25;;;;;;;;;;;;;;;;;;;;;50860:10;50826:46;;50874:18;50893:5;50874:25;;;;;;;;;;;;;;;;;;;;;50908:9;50874:45;;50736:184;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51308:20;;51384:23;;51363:45;;;;;;;;;;;;;;51308:20;;;;;;;;;51363;;:45;;;;;;;;;;;;;;-1:-1:-1;51308:20:0;51363:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51363:45:0;;51336:24;;:72;;;51431:13;;:43;;:17;:43::i;:::-;51415:13;:59;;;;51579:96;51629:18;51648:5;51629:25;;;;;;;;;;;;;;;;;;;;;51663:9;51629:45;;51579:18;51598:5;51579:25;;;;;;;:96;51556:9;:20;;:119;;;;;51719:84;51782:9;:20;;;51719:58;51769:7;51719:18;51738:5;51719:25;;;;;;;;;;;;;;;;;;;;;51753:9;51745:18;;51719:84;51682:34;;;:121;;;51971:20;;51888:24;;;;51887:105;;51888:77;;51957:7;;51888:64;;:24;:28;:64::i;51887:105::-;51856:28;;;:136;;;52030:24;;;;:58;;:28;:58::i;:::-;51999:28;;;:89;;;52139:23;:30;;52163:5;;52139:30;;;;;;;;;;;;;;;;;;;:82;;;;52228:23;:30;;52252:5;;52228:30;;;;;;;;;;;;;;;;;;;52267:10;52228:51;:55;52344:28;;;;52290:23;:30;;52314:5;;52290:30;;;;;;;;;;;;;;;;;;;52329:9;52290:50;:82;;;;52476:257;52495:5;52502:9;:28;;;52532:1;52535:9;:28;;;52573:18;52592:5;52573:25;;;;;;;;;;;;;;;;;;;;;:45;;52629:18;52648:5;52629:25;;;;;;;;;;;;;;;;;;;;;52663:10;52629:46;;52686:18;52705:5;52686:25;;;;;;;;;;;;;;;;;;;;;52720:9;52686:45;;52476:257;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52740:23;;;;:16;:23;;;;;:30;;;;52766:4;52740:30;;;52777:16;;:::i;:::-;-1:-1:-1;;;;;;49642:3157:0:o;60171:218::-;60263:11;:22;60221:7;;60245:15;:40;60237:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60363:20;;:11;60337:22;60319:15;:40;60363:20;60318:65;;;;;60311:72;;60171:218;:::o;39002:38::-;;;;;;;;;;;;38355:43;;;;;;;;;;;;39371:115;;;;;;;;:::o;38767:48::-;;;;;;;;;;;;37873:46;;;;;;;;;;;;;;;:::o;61497:112::-;61585:18;;;;61497:112;:::o;37510:23::-;;;;;;:::o;36867:24::-;;;;:::o;37216:38::-;;;;:::o;38638:46::-;;;;;;;;;;;;36598:29;;;;:::o;38541:44::-;;;;;;;;;;;;60395:189;60468:7;60491:87;60562:15;60491:66;60518:38;60535:11;:20;;;60518:12;60528:1;60518:5;:9;;:12;;;;:::i;60491:66::-;:70;;:87::i;60611:722::-;60667:7;60676;60692:13;60708:19;:17;:19::i;:::-;60692:35;;60734:21;60758:113;60816:26;60843:5;60816:33;;;;;;;;;;;;;;;;;;;;;60858:10;60816:54;;60758:26;60785:5;60758:33;;;;;;;:113;60734:137;;60878:23;60904:117;60964:28;60993:5;60964:35;;;;;;;;;;;;;;;;;;;;;61008:10;60964:56;;60904:28;60933:5;60904:35;;;;;;;:117;60878:143;;61028:18;61049:22;61072:5;61049:29;;;;;;;;;;;;;;;;;;;;;:49;;61028:70;;61105:20;61128:24;61153:5;61128:31;;;;;;;;;;;;;;;;;;;;;:51;;61105:74;;61208:13;61195:10;:26;:59;;61253:1;61195:59;;;61237:13;61224:10;:26;61195:59;61273:15;61258:12;:30;:67;;61324:1;61258:67;;;61306:15;61291:12;:30;61258:67;61186:141;;;;;;;;;60611:722;;:::o;61697:205::-;61762:10;;;;61748;:24;61740:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61828:11;:22;61853:8;61828:33;61810:15;:51;61802:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61881:15;61888:8;;61881:15;:::i;:::-;61697:205::o;37770:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37770:32:0;:::o;61341:150::-;61440:11;:22;61464:20;;61341:150;;:::o;59426:216::-;59493:8;;;;59479:10;:22;59471:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59574:6;59555:16;59569:1;59555:13;:16::i;:::-;:25;59537:15;:43;59529:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59620:9;:16;;;;59632:4;59620:16;;;59426:216::o;31129:171::-;31235:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31258:23;31235:58;;;31208:86;;31228:5;;31208:19;:86::i;:::-;31129:171;;;:::o;3309:181::-;3367:7;3399:5;;;3423:6;;;;3415:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3481:1;3309:181;-1:-1:-1;;;3309:181:0:o;4663:471::-;4721:7;4966:6;4962:47;;-1:-1:-1;4996:1:0;4989:8;;4962:47;5033:5;;;5037:1;5033;:5;:1;5057:5;;;;;:10;5049:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5610:132;5668:7;5695:39;5699:1;5702;5695:39;;;;;;;;;;;;;;;;;:3;:39::i;3773:136::-;3831:7;3858:43;3862:1;3865;3858:43;;;;;;;;;;;;;;;;;:3;:43::i;31306:199::-;31430:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31453:27;31430:68;;;31403:96;;31423:5;;31403:19;:96::i;:::-;31306:199;;;;:::o;33330:723::-;33738:23;33764:69;33792:4;33764:69;;;;;;;;;;;;;;;;;33772:5;33764:27;;;;:69;;;;;:::i;:::-;33844:17;;33738:95;;-1:-1:-1;33844:21:0;33840:208;;33974:10;33963:30;;;;;;;;;;;;;;;-1:-1:-1;33963:30:0;33955:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6238:278;6324:7;6359:12;6352:5;6344:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6383:9;6399:1;6395;:5;;;;;;;6238:278;-1:-1:-1;;;;;6238:278:0:o;4212:192::-;4298:7;4334:12;4326:6;;;;4318:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4370:5:0;;;4212:192::o;15180:195::-;15283:12;15315:52;15337:6;15345:4;15351:1;15354:12;15315:21;:52::i;:::-;15308:59;15180:195;-1:-1:-1;;;;15180:195:0:o;16232:530::-;16359:12;16417:5;16392:21;:30;;16384:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16484:18;16495:6;16484:10;:18::i;:::-;16476:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16610:12;16624:23;16651:6;:11;;16671:5;16679:4;16651:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16609:75;;;;16702:52;16720:7;16729:10;16741:12;16702:17;:52::i;:::-;16695:59;16232:530;-1:-1:-1;;;;;;;16232:530:0:o;12260:422::-;12627:20;12666:8;;;12260:422::o;18772:742::-;18887:12;18916:7;18912:595;;;-1:-1:-1;18947:10:0;18940:17;;18912:595;19061:17;;:21;19057:439;;19324:10;19318:17;19385:15;19372:10;19368:2;19364:19;19357:44;19272:148;19460:20;;;;;;;;;;;;;;;;;;;;19467:12;;19460:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;
Swarm Source
ipfs://6aa2cb9fcd16e399176f627215467b79f952c69d823080c7d6f473ed1d97dd42
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $24.06 | 5.0049 | $120.42 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.