Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 962 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Add_liquidity | 13352083 | 1177 days ago | IN | 0 ETH | 0.00141878 | ||||
Sweep | 11718747 | 1430 days ago | IN | 0 ETH | 0.0042678 | ||||
Add_liquidity | 11485689 | 1466 days ago | IN | 0 ETH | 0.00198 | ||||
Add_liquidity | 11453009 | 1471 days ago | IN | 0 ETH | 0.00124015 | ||||
Add_liquidity | 11452928 | 1471 days ago | IN | 0 ETH | 0.0008437 | ||||
Add_liquidity | 11452902 | 1471 days ago | IN | 0 ETH | 0.00085779 | ||||
Remove_liquidity | 11375906 | 1483 days ago | IN | 0 ETH | 0.00060604 | ||||
Remove_liquidity | 11375857 | 1483 days ago | IN | 0 ETH | 0.00087997 | ||||
Remove_liquidity | 11375761 | 1483 days ago | IN | 0 ETH | 0.00095216 | ||||
Remove_liquidity | 11375535 | 1483 days ago | IN | 0 ETH | 0.00074797 | ||||
Remove_liquidity | 11375477 | 1483 days ago | IN | 0 ETH | 0.0060744 | ||||
Remove_liquidity | 11375463 | 1483 days ago | IN | 0 ETH | 0.0007569 | ||||
Remove_liquidity | 11375445 | 1483 days ago | IN | 0 ETH | 0.00124175 | ||||
Remove_liquidity | 11375441 | 1483 days ago | IN | 0 ETH | 0.00085008 | ||||
Remove_liquidity | 11375440 | 1483 days ago | IN | 0 ETH | 0.00136674 | ||||
Remove_liquidity | 11375434 | 1483 days ago | IN | 0 ETH | 0.00153538 | ||||
Remove_liquidity | 11375415 | 1483 days ago | IN | 0 ETH | 0.0007593 | ||||
Remove_liquidity | 11375361 | 1483 days ago | IN | 0 ETH | 0.00127562 | ||||
Remove_liquidity | 11369429 | 1484 days ago | IN | 0 ETH | 0.00069828 | ||||
Remove_liquidity | 11369225 | 1484 days ago | IN | 0 ETH | 0.0007593 | ||||
Remove_liquidity | 11368840 | 1484 days ago | IN | 0 ETH | 0.00048766 | ||||
Remove_liquidity | 11368840 | 1484 days ago | IN | 0 ETH | 0.00046585 | ||||
Set_best_adapter | 11365414 | 1484 days ago | IN | 0 ETH | 0.00300382 | ||||
Remove_liquidity | 11362915 | 1485 days ago | IN | 0 ETH | 0.00100227 | ||||
Remove_liquidity | 11362651 | 1485 days ago | IN | 0 ETH | 0.00108494 |
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-11-15 */ // 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: 95000, AA: 0, A: 5000 }); /**** 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) { 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 = 1000; // v1: constant ratio } 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"); 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 == 1, "v1: must be epoch 1 only"); // v1: can't add liquidity after epoch 0 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 == 1, "v1: bal token epoch must be 1"); 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 == 1, "v1: bal token epoch must be 1"); 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 + 5 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"); require(block.timestamp > epoch_cycle.start_date + 12 weeks, "v1: must be completed"); 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"}],"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
6007805460ff19169055635f9ebf6060808190526212750060a0819052600c91909155600d556101206040526201731860c0819052600060e0819052611388610100819052601a92909255601b55601c5534801561005c57600080fd5b50604051620050dc380380620050dc8339818101604052606081101561008157600080fd5b508051602082015160409092015160008054336001600160a01b03199182161782556001805482166001600160a01b03968716179055600b80548216948616949094179093556002805490931693909116929092179055600a6005556103e8600655614fe8908190620000f490396000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637425ffec11610186578063ac3dbb12116100e3578063df4cbfd811610097578063ebd485fc11610071578063ebd485fc1461086d578063f034c18d1461088a578063fc0e74d114610892576102de565b8063df4cbfd814610840578063dfe537961461085d578063e653be7414610865576102de565b8063bc87f62c116100c8578063bc87f62c146107f2578063c6b483ab14610815578063d2e7a1bb1461081d576102de565b8063ac3dbb12146107e2578063bc4ce844146107ea576102de565b80639b53e3661161013a578063a684b5991161011f578063a684b599146107b5578063a72b6c30146107d2578063a8c62e76146107da576102de565b80639b53e3661461076c578063a20f527214610792576102de565b8063837a9bc71161016b578063837a9bc71461071e57806384518744146107265780639392f6f214610749576102de565b80637425ffec146106d857806380e0f15f146106fb576102de565b806348373cc61161023f5780635b1caa2f116101f35780636bd6f696116101cd5780636bd6f6961461068a57806370cdf476146106ad57806370d4ac4e146106d0576102de565b80635b1caa2f1461050d5780636120f0dc146105545780636acc25be14610682576102de565b806354d0c8a01161022457806354d0c8a0146104da578063580f346f146104e25780635aa6e67514610505576102de565b806348373cc61461048b5780634c1a4259146104a7576102de565b80630f78dac31161029657806322cef9d31161027b57806322cef9d3146104405780632a0ccc88146104485780632b666fcf14610450576102de565b80630f78dac3146103f95780631816f3141461041f576102de565b8063070313fa116102c7578063070313fa1461034b5780630bbb0c581461037e5780630efb8dbd146103ca576102de565b806301681a62146102e357806302b6215914610318575b600080fd5b610316600480360360208110156102f957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661089a565b005b6103166004803603602081101561032e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610b82565b6103166004803603602081101561036157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c54565b6103a16004803603604081101561039457600080fd5b5080359060200135610d21565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103e7600480360360208110156103e057600080fd5b5035610d6c565b60408051918252519081900360200190f35b6103166004803603604081101561040f57600080fd5b508035906020013560ff16610d9a565b610427611725565b6040805192835260208301919091528051918290030190f35b6103a161172e565b6103a161174f565b6103166004803603604081101561046657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661176b565b6104936119c5565b604080519115158252519081900360200190f35b610316600480360360208110156104bd57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166119ce565b6103a1611e25565b6103e7600480360360408110156104f857600080fd5b5080359060200135611e41565b6103a1611e76565b6103166004803603608081101561052357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135916040820135169060600135611e92565b6103166004803603606081101561056a57600080fd5b8135919081019060408101602082013564010000000081111561058c57600080fd5b82018360208201111561059e57600080fd5b803590602001918460208302840111640100000000831117156105c057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561061057600080fd5b82018360208201111561062257600080fd5b8035906020019184602083028401116401000000008311171561064457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612fa3945050505050565b6103e7613afd565b6103e7600480360360408110156106a057600080fd5b5080359060200135613b03565b6103a1600480360360408110156106c357600080fd5b5080359060200135613b13565b6103e7613b23565b6103e7600480360360408110156106ee57600080fd5b5080359060200135613b29565b6103166004803603604081101561071157600080fd5b5080359060200135613b39565b6103e76141d1565b6103e76004803603604081101561073c57600080fd5b5080359060200135614259565b6103e76004803603604081101561075f57600080fd5b5080359060200135614269565b610774614279565b60408051938452602084019290925282820152519081900360600190f35b6103e7600480360360408110156107a857600080fd5b5080359060200135614285565b610493600480360360208110156107cb57600080fd5b5035614295565b6103a16142aa565b6103a16142c6565b6103e76142e2565b6103e76142e8565b6103e76004803603604081101561080857600080fd5b50803590602001356142ee565b6103e76142fe565b6103e76004803603604081101561083357600080fd5b5080359060200135614304565b6103e76004803603602081101561085657600080fd5b5035614314565b610427614340565b610316614430565b6103e76004803603602081101561088357600080fd5b5035614539565b61042761455a565b610316614564565b60005473ffffffffffffffffffffffffffffffffffffffff16331461092057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600c54626ebe0001421161099557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f76313a206d75737420626520636f6d706c657465640000000000000000000000604482015290519081900360640190fd5b600254604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b158015610a0b57600080fd5b505afa158015610a1f573d6000803e3d6000fd5b505050506040513d6020811015610a3557600080fd5b50519050610a5a73ffffffffffffffffffffffffffffffffffffffff83168483614693565b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b158015610ad057600080fd5b505afa158015610ae4573d6000803e3d6000fd5b505050506040513d6020811015610afa57600080fd5b50519050610b1f73ffffffffffffffffffffffffffffffffffffffff83168683614693565b6040805133815273ffffffffffffffffffffffffffffffffffffffff871660208201528082018590526060810183905290517f8496dda4d04919fec296be83f4d7d178dafb7c0d3abe1553c092f1466e8f29289181900360800190a15050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c0857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b6007805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cda57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60108281548110610d3157600080fd5b90600052602060002090600302018160038110610d4d57600080fd5b015473ffffffffffffffffffffffffffffffffffffffff169150829050565b600d54600090610d9490610d8b90610d85856001614725565b906147a0565b600c5490614725565b92915050565b60075460ff1615610e0c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000816002811115610e1a57fe5b1480610e3157506002816002811115610e2f57fe5b145b610e86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180614f626027913960400191505060405180910390fd5b6000610e906141d1565b905082610efe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f63616e2774206164642030000000000000000000000000000000000000000000604482015290519081900360640190fd5b80600114610f6d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f76313a206d7573742062652065706f63682031206f6e6c790000000000000000604482015290519081900360640190fd5b610f75614d92565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509050610fc1614340565b60e083015260c08201526000836002811115610fd957fe5b1415611036576110138460158481548110610ff057fe5b600091825260208220600390910201905b6003811061100b57fe5b015490614725565b6015838154811061102057fe5b6000918252602082206003919091020101558381525b600283600281111561104457fe5b141561117a5761107160055461106b8360e001518460c0015161472590919063ffffffff16565b90614813565b60208201819052841061108857806020015161108a565b835b80825260055461109a91906147a0565b6060820181905260c0820151106110ba5760608101516080820152611128565b60c08101516080820181905260608201516110d491614855565b60a0820181905260178054611106929190859081106110ef57fe5b600091825260209091206003909102016001611001565b6017838154811061111357fe5b60009182526020909120600390910201600101555b61113d8160800151601684815481106110ef57fe5b6016838154811061114a57fe5b6000918252602090912060039091020160010155805184111561117a578051611174908590614855565b60408201525b600061119061118884614314565b8351906147a0565b82516003549192506111a29190614725565b6003558151600e80546111d4929190869081106111bb57fe5b906000526020600020015461472590919063ffffffff16565b600e84815481106111e157fe5b906000526020600020018190555061121a816012858154811061120057fe5b906000526020600020906003020186600281111561100157fe5b6012848154811061122757fe5b906000526020600020906003020185600281111561124157fe5b6003811061124b57fe5b01558151601380546112639291908690811061120057fe5b6013848154811061127057fe5b906000526020600020906003020185600281111561128a57fe5b6003811061129457fe5b015581516001546112c19173ffffffffffffffffffffffffffffffffffffffff9091169033903090614897565b60028460028111156112cf57fe5b141561130c5761130c33306006548560000151816112e957fe5b60025473ffffffffffffffffffffffffffffffffffffffff169392919004614897565b6010838154811061131957fe5b906000526020600020906003020184600281111561133357fe5b6003811061133d57fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101849052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b1580156113b557600080fd5b505af11580156113c9573d6000803e3d6000fd5b50505050601183815481106113da57fe5b90600052602060002090600302018460028111156113f457fe5b600381106113fe57fe5b01548251604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101929092525173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b15801561147857600080fd5b505af115801561148c573d6000803e3d6000fd5b505050507f058587cdc5efcef45583dc39e6884e853b5c5aef182afe72ca96db6fa1c85c218460028111156114bd57fe5b8360000151846000015185602001518660400151876060015188608001518960a001518a60c001518b60e00151604051808b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a17fc7d2d1a5a726dc6005e76316c12eb5ee642296cc38c1b996651599995a480f3c61156884614314565b8360000151836010878154811061157b57fe5b906000526020600020906003020188600281111561159557fe5b6003811061159f57fe5b015473ffffffffffffffffffffffffffffffffffffffff16878960028111156115c457fe5b3360118b815481106115d257fe5b90600052602060002090600302018c60028111156115ec57fe5b600381106115f657fe5b01546040805198895260208901979097528787019590955273ffffffffffffffffffffffffffffffffffffffff9384166060880152608087019290925260a0860152811660c08501521660e083015251908190036101000190a17f1d69fb63e4692a6ae9a9b249224c389569da92d8e2e96243d71fd6b3bc3055d9600354600e858154811061168157fe5b906000526020600020015460006013878154811061169b57fe5b90600052602060002090600302018860028111156116b557fe5b600381106116bf57fe5b0154601288815481106116ce57fe5b90600052602060002090600302018960028111156116e857fe5b600381106116f257fe5b01546040805195865260208601949094528484019290925260608401526080830152519081900360a00190a15050505050565b600c54600d5482565b600754610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff838116911614801590611837575060025473ffffffffffffffffffffffffffffffffffffffff838116911614155b6118a257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616e6e6f7420737765657020706f6f6c206173736574730000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051839160009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561191357600080fd5b505afa158015611927573d6000803e3d6000fd5b505050506040513d602081101561193d57600080fd5b5051905061196273ffffffffffffffffffffffffffffffffffffffff83168483614693565b6040805133815273ffffffffffffffffffffffffffffffffffffffff80861660208301528616818301526060810183905290517f2c4e64c7c0957a81c0076a0a3f3c7d9f0a5d6158292071c794436f829d12cfb79181900360800190a150505050565b60075460ff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff163314611a5457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b60075460ff1615611ac657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000611ad06141d1565b6007805473ffffffffffffffffffffffffffffffffffffffff808616610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff90921691909117909155600154604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051939450859360009392909216916370a0823191602480820192602092909190829003018186803b158015611b8057600080fd5b505afa158015611b94573d6000803e3d6000fd5b505050506040513d6020811015611baa57600080fd5b505160158054919250611be09185908110611bc157fe5b60009182526020822060039190910201015460148581548110610ff057fe5b60148481548110611bed57fe5b600091825260208220600391909102010181905550611c4a60158481548110611c1257fe5b600091825260209091206003909102016002015460148581548110611c3357fe5b600091825260209091206003909102016002611001565b60148481548110611c5757fe5b6000918252602090912060039091020160020181905550611c9f60178481548110611c7e57fe5b6000918252602090912060039091020160010154601685815481106110ef57fe5b60168481548110611cac57fe5b600091825260208220600160039092020101919091556015805485908110611cd057fe5b60009182526020822060039190910201919091556015805485908110611cf257fe5b600091825260208220600260039092020101919091556017805485908110611d1657fe5b6000918252602090912060039091020160010155600854611d379082614725565b6008556040805173ffffffffffffffffffffffffffffffffffffffff861681526020810183905280820185905290517ffc2f950130d4b652317d4d65735fe2c28b9b137f09199cc20367042dedafb6d59181900360600190a1600154611db49073ffffffffffffffffffffffffffffffffffffffff168583614693565b8173ffffffffffffffffffffffffffffffffffffffff16631d2e62d9826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611e0757600080fd5b505af1158015611e1b573d6000803e3d6000fd5b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60128281548110611e5157600080fd5b90600052602060002090600302018160038110611e6d57600080fd5b01549150829050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6000831180611ea15750600081115b611f0c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63616e27742072656d6f76652030000000000000000000000000000000000000604482015290519081900360640190fd5b60075473ffffffffffffffffffffffffffffffffffffffff610100909104811690600090819081908190891615801590611f465750600088115b156124d657611f53614dd7565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601d60209081526040918290208251608081018452815460ff9081161515825260018301549382019390935260028083015491949293928501929190911690811115611fb757fe5b6002811115611fc257fe5b81526020016002820160019054906101000a900460ff166001811115611fe457fe5b6001811115611fef57fe5b905250805190915061206257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f62616c616e636520746f6b656e206c6f6f6b7570206661696c65640000000000604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518b918b9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156120d257600080fd5b505afa1580156120e6573d6000803e3d6000fd5b505050506040513d60208110156120fc57600080fd5b5051101561216b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b602082015160008360600151600181111561218257fe5b146121ee57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6261642064736563206164647265737300000000000000000000000000000000604482015290519081900360640190fd5b8060011461225d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76313a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff166122da57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b6000601282815481106122e957fe5b90600052602060002090600302018460400151600281111561230757fe5b6003811061231157fe5b015490508015612336576123318161106b8e670de0b6b3a76400006147a0565b612339565b60005b9450670de0b6b3a7640000612385866018858154811061235557fe5b90600052602060002090600302018760400151600281111561237357fe5b6003811061237d57fe5b0154906147a0565b8161238c57fe5b049750670de0b6b3a76400006123a9866019858154811061235557fe5b816123b057fe5b0496506123f488601884815481106123c457fe5b9060005260206000209060030201866040015160028111156123e257fe5b600381106123ec57fe5b015490614855565b6018838154811061240157fe5b90600052602060002090600302018560400151600281111561241f57fe5b6003811061242957fe5b018190555061243f87601984815481106123c457fe5b6019838154811061244c57fe5b90600052602060002090600302018560400151600281111561246a57fe5b6003811061247457fe5b018190555061248a8c601284815481106123c457fe5b6012838154811061249757fe5b9060005260206000209060030201856040015160028111156124b557fe5b600381106124bf57fe5b01556004546124ce9089614855565b600455505050505b73ffffffffffffffffffffffffffffffffffffffff8716158015906124fb5750600086115b1561298657612508614dd7565b73ffffffffffffffffffffffffffffffffffffffff88166000908152601d60209081526040918290208251608081018452815460ff908116151582526001830154938201939093526002808301549194929392850192919091169081111561256c57fe5b600281111561257757fe5b81526020016002820160019054906101000a900460ff16600181111561259957fe5b60018111156125a457fe5b905250805190915061261757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f62616c616e636520746f6b656e20696e666f206c6f6f6b7570206661696c6564604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518991899173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561268757600080fd5b505afa15801561269b573d6000803e3d6000fd5b505050506040513d60208110156126b157600080fd5b5051101561272057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b602082015160018360600151600181111561273757fe5b146127a357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6261642062616c616e636520746f6b656e206164647265737300000000000000604482015290519081900360640190fd5b8060011461281257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76313a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff1661288f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b6128be89601383815481106128a057fe5b9060005260206000209060030201856040015160028111156123e257fe5b601382815481106128cb57fe5b9060005260206000209060030201846040015160028111156128e957fe5b600381106128f357fe5b018190555061292289600e838154811061290957fe5b906000526020600020015461485590919063ffffffff16565b600e828154811061292f57fe5b600091825260209091200155600354612948908a614855565b600355600854612958908a614855565b60085560028360400151600281111561296d57fe5b141561298257600654898161297e57fe5b0494505b5050505b73ffffffffffffffffffffffffffffffffffffffff8916158015906129ab5750600088115b15612c3857604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518a918a9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015612a2057600080fd5b505afa158015612a34573d6000803e3d6000fd5b505050506040513d6020811015612a4a57600080fd5b50511015612ab957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b604080517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b9052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612b2d57600080fd5b505af1158015612b41573d6000803e3d6000fd5b5050604080517f96728a7200000000000000000000000000000000000000000000000000000000815260048101899052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612bb957600080fd5b505af1158015612bcd573d6000803e3d6000fd5b5050600254612bf6925073ffffffffffffffffffffffffffffffffffffffff1690503386614693565b604080518381526020810187905280820186905290517f45d0d3545b4cb7d20e6d592c7158c445e3acda72c55074ab88b0027aa9c2d2789181900360600190a1505b73ffffffffffffffffffffffffffffffffffffffff871615801590612c5d5750600086115b15612edd57604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518891889173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015612cd257600080fd5b505afa158015612ce6573d6000803e3d6000fd5b505050506040513d6020811015612cfc57600080fd5b50511015612d6b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b604080517f9dc29fac00000000000000000000000000000000000000000000000000000000815233600482015260248101899052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612ddf57600080fd5b505af1158015612df3573d6000803e3d6000fd5b5050604080517f96728a72000000000000000000000000000000000000000000000000000000008152600481018b9052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612e6b57600080fd5b505af1158015612e7f573d6000803e3d6000fd5b5050600254612ea8925073ffffffffffffffffffffffffffffffffffffffff1690503385614693565b6040805188815290517ffbcc912eee8a56d51e3708fe32ba15f4191e6f92b2ccae4f00bbb544dba49f029181900360200190a1505b73ffffffffffffffffffffffffffffffffffffffff891615801590612f025750600088115b80612f2d575073ffffffffffffffffffffffffffffffffffffffff871615801590612f2d5750600086115b612f9857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6e6f20616374696f6e20706572666f726d656400000000000000000000000000604482015290519081900360640190fd5b505050505050505050565b601354831461301357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696d70726f706572206e65772065706f63680000000000000000000000000000604482015290519081900360640190fd5b600e8054600181810190925560007fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90910181905560408051606081018252828152602081018390529081018290526012805493840181559091526130a09160039081027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444019190614dfe565b50604080516060810182526000808252602082018190529181018290526013805460018101825592526130fb9160039081027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090019190614dfe565b50604080516060810182526000808252602082018190529181018290526014805460018101825592526131569160039081027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec019190614dfe565b50604080516060810182526000808252602082018190529181018290526015805460018101825592526131b19160039081027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475019190614dfe565b506040805160608101825260008082526020820181905291810182905260168054600181018255925261320c9160039081027fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b5124289019190614dfe565b50604080516060810182526000808252602082018190529181018290526017805460018101825592526132679160039081027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15019190614dfe565b50604080516060810182526000808252602082018190529181018290526018805460018101825592526132c29160039081027fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e019190614dfe565b506040805160608101825260008082526020820181905291810182905260198054600181018255925261331d9160039081027f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695019190614dfe565b506040805160608101909152601090808460008151811061333a57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460018151811061336c57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460028151811061339e57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206133e59260039081029091019190614e41565b506040805160608101909152601190808360008151811061340257fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360018151811061343457fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360028151811061346657fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206134ad9260039081029091019190614e41565b506040805160808101825260018152602081018590529081016000815260200160009052601d60008481815181106134e157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561357157fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156135b257fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160009052601d6000846001815181106135ef57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561367f57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156136c057fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160009052601d6000846002815181106136fb57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561378b57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137cc57fe5b021790555050604080516080810182526001815260208101869052915081016000815260200160019052601d600083818151811061380657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561389657fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156138d757fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160019052601d60008360018151811061391457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360028111156139a457fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156139e557fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160019052601d600083600281518110613a2057fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836002811115613ab057fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115613af157fe5b02179055505050505050565b60055481565b60188281548110611e5157600080fd5b60118281548110610d3157600080fd5b60045481565b60148281548110611e5157600080fd5b600b5473ffffffffffffffffffffffffffffffffffffffff163314613bbf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b6000828152600f602052604090205460ff1615613c3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f65706f636820616c726561647920776f756e6420646f776e0000000000000000604482015290519081900360640190fd5b6000613c476141d1565b9050808310613cb757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e6e6f742077696e6420646f776e206675747572652065706f6368000000604482015290519081900360640190fd5b613cbf614eae565b506040805160c081018252600060208201819052918101829052606081018290526080810182905260a08101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201808252613d1e90610d6c565b421015613d8c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e27742063616c6c206265666f72652065706f636820656e646564000000604482015290519081900360640190fd5b601a54613da290620186a09061106b90866147a0565b60198581548110613daf57fe5b600091825260208220600391909102010155601b54613dd790620186a09061106b90866147a0565b60198581548110613de457fe5b6000918252602090912060039091020160010155601c54613e0e90620186a09061106b90866147a0565b60198581548110613e1b57fe5b60009182526020909120600390910201600201558051601980547f02ac5b59c8ff91aed9818435a4a06bf88afedae653001d8d7086f29057eca88c92919087908110613e6357fe5b60009182526020822060039190910201015460198781548110613e8257fe5b600091825260209091206003909102016001015460198881548110613ea357fe5b6000918252602090912060039091020160020154604080519485526020850193909352838301919091526060830152519081900360800190a1600754600854604080517f1a2b383200000000000000000000000000000000000000000000000000000000815260048101929092525161010090920473ffffffffffffffffffffffffffffffffffffffff16918291631a2b38329160248083019260209291908290030181600087803b158015613f5857600080fd5b505af1158015613f6c573d6000803e3d6000fd5b505050506040513d6020811015613f8257600080fd5b505160208301819052600454613f9791614725565b600481905550613fce60128681548110613fad57fe5b600091825260209091206003909102016002015460128781548110610ff057fe5b82604001818152505061400f826040015161106b670de0b6b3a764000060128981548110613ff857fe5b600091825260209091206003909102016002612373565b60608301819052600554602084015161403a92610d8591670de0b6b3a76400009161106b91906147a0565b60808301819052602083015161404f91614855565b60a08301819052601880548790811061406457fe5b6000918252602082206003919091020191909155601880548790811061408657fe5b6000918252602090912060039091020160010155608082015160188054879081106140ad57fe5b60009182526020909120600390910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858360a001516000856080015160198a815481106140ff57fe5b60009182526020822060039190910201015460198b8154811061411e57fe5b600091825260209091206003909102016001015460198c8154811061413f57fe5b6000918252602090912060039091020160020154604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190a16000858152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556141c9614eae565b505050505050565b600c54600090421161424457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6265666f72652065706f63682030000000000000000000000000000000000000604482015290519081900360640190fd5b600d54600c5442038161425357fe5b04905090565b60198281548110611e5157600080fd5b60138281548110611e5157600080fd5b601a54601b54601c5483565b60178281548110611e5157600080fd5b600f6020526000908152604090205460ff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b600b5473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b60085481565b60168281548110611e5157600080fd5b60035481565b60158281548110611e5157600080fd5b6000610d944261433a610d8b600c60010154610d8560018861472590919063ffffffff16565b90614855565b600080600061434d6141d1565b905060006143826016838154811061436157fe5b600091825260209091206003909102016001015460168481548110611c3357fe5b905060006143b76017848154811061439657fe5b600091825260209091206003909102016001015460178581548110611c3357fe5b90506000601484815481106143c857fe5b60009182526020822060039190910201015490506000601585815481106143eb57fe5b600091825260208220600391909102010154905083821161440d576000614411565b8382035b83821161441f576000614423565b8382035b9650965050505050509091565b60005473ffffffffffffffffffffffffffffffffffffffff1633146144b657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600c54622e248001421161452b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f746f6f20736f6f6e000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61453760096000614ee4565b565b600e818154811061454957600080fd5b600091825260209091200154905081565b600c54600d549091565b600b5473ffffffffffffffffffffffffffffffffffffffff1633146145ea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b620151806145f86001610d6c565b03421161466657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f747279696e6720746f2073687574646f776e20746f6f206561726c7900000000604482015290519081900360640190fd5b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052614720908490614932565b505050565b60008282018381101561479957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000826147af57506000610d94565b828202828482816147bc57fe5b0414614799576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614f416021913960400191505060405180910390fd5b600061479983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a0a565b600061479983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614ac6565b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261492c908590614932565b50505050565b6060614994826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614b3a9092919063ffffffff16565b805190915015614720578080602001905160208110156149b357600080fd5b5051614720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614f89602a913960400191505060405180910390fd5b60008183614ab0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614a75578181015183820152602001614a5d565b50505050905090810190601f168015614aa25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614abc57fe5b0495945050505050565b60008184841115614b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315614a75578181015183820152602001614a5d565b505050900390565b6060614b498484600085614b51565b949350505050565b606082471015614bac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614f1b6026913960400191505060405180910390fd5b614bb585614d0c565b614c2057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310614c8a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614c4d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614cec576040519150601f19603f3d011682016040523d82523d6000602084013e614cf1565b606091505b5091509150614d01828286614d12565b979650505050505050565b3b151590565b60608315614d21575081614799565b825115614d315782518084602001fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451859391928392604401919085019080838360008315614a75578181015183820152602001614a5d565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60408051608081018252600080825260208201819052909182019081526020016000905290565b8260038101928215614e31579160200282015b82811115614e31578251829060ff16905591602001919060010190614e11565b50614e3d929150614f05565b5090565b8260038101928215614e31579160200282015b82811115614e3157825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614e54565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5080546000825590600052602060002090810190614f029190614f05565b50565b5b80821115614e3d5760008155600101614f0656fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7776313a2063616e2774206164645f6c697175696469747920696e746f204141207472616e6368655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a07ec068cfe82666ea6686f72accf698858cf6f7079a4522c940db620bea226364736f6c63430007040033000000000000000000000000257bbc6241cf0054b2307d01b2b326d235be8fa10000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102de5760003560e01c80637425ffec11610186578063ac3dbb12116100e3578063df4cbfd811610097578063ebd485fc11610071578063ebd485fc1461086d578063f034c18d1461088a578063fc0e74d114610892576102de565b8063df4cbfd814610840578063dfe537961461085d578063e653be7414610865576102de565b8063bc87f62c116100c8578063bc87f62c146107f2578063c6b483ab14610815578063d2e7a1bb1461081d576102de565b8063ac3dbb12146107e2578063bc4ce844146107ea576102de565b80639b53e3661161013a578063a684b5991161011f578063a684b599146107b5578063a72b6c30146107d2578063a8c62e76146107da576102de565b80639b53e3661461076c578063a20f527214610792576102de565b8063837a9bc71161016b578063837a9bc71461071e57806384518744146107265780639392f6f214610749576102de565b80637425ffec146106d857806380e0f15f146106fb576102de565b806348373cc61161023f5780635b1caa2f116101f35780636bd6f696116101cd5780636bd6f6961461068a57806370cdf476146106ad57806370d4ac4e146106d0576102de565b80635b1caa2f1461050d5780636120f0dc146105545780636acc25be14610682576102de565b806354d0c8a01161022457806354d0c8a0146104da578063580f346f146104e25780635aa6e67514610505576102de565b806348373cc61461048b5780634c1a4259146104a7576102de565b80630f78dac31161029657806322cef9d31161027b57806322cef9d3146104405780632a0ccc88146104485780632b666fcf14610450576102de565b80630f78dac3146103f95780631816f3141461041f576102de565b8063070313fa116102c7578063070313fa1461034b5780630bbb0c581461037e5780630efb8dbd146103ca576102de565b806301681a62146102e357806302b6215914610318575b600080fd5b610316600480360360208110156102f957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661089a565b005b6103166004803603602081101561032e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610b82565b6103166004803603602081101561036157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c54565b6103a16004803603604081101561039457600080fd5b5080359060200135610d21565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103e7600480360360208110156103e057600080fd5b5035610d6c565b60408051918252519081900360200190f35b6103166004803603604081101561040f57600080fd5b508035906020013560ff16610d9a565b610427611725565b6040805192835260208301919091528051918290030190f35b6103a161172e565b6103a161174f565b6103166004803603604081101561046657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661176b565b6104936119c5565b604080519115158252519081900360200190f35b610316600480360360208110156104bd57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166119ce565b6103a1611e25565b6103e7600480360360408110156104f857600080fd5b5080359060200135611e41565b6103a1611e76565b6103166004803603608081101561052357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135916040820135169060600135611e92565b6103166004803603606081101561056a57600080fd5b8135919081019060408101602082013564010000000081111561058c57600080fd5b82018360208201111561059e57600080fd5b803590602001918460208302840111640100000000831117156105c057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561061057600080fd5b82018360208201111561062257600080fd5b8035906020019184602083028401116401000000008311171561064457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612fa3945050505050565b6103e7613afd565b6103e7600480360360408110156106a057600080fd5b5080359060200135613b03565b6103a1600480360360408110156106c357600080fd5b5080359060200135613b13565b6103e7613b23565b6103e7600480360360408110156106ee57600080fd5b5080359060200135613b29565b6103166004803603604081101561071157600080fd5b5080359060200135613b39565b6103e76141d1565b6103e76004803603604081101561073c57600080fd5b5080359060200135614259565b6103e76004803603604081101561075f57600080fd5b5080359060200135614269565b610774614279565b60408051938452602084019290925282820152519081900360600190f35b6103e7600480360360408110156107a857600080fd5b5080359060200135614285565b610493600480360360208110156107cb57600080fd5b5035614295565b6103a16142aa565b6103a16142c6565b6103e76142e2565b6103e76142e8565b6103e76004803603604081101561080857600080fd5b50803590602001356142ee565b6103e76142fe565b6103e76004803603604081101561083357600080fd5b5080359060200135614304565b6103e76004803603602081101561085657600080fd5b5035614314565b610427614340565b610316614430565b6103e76004803603602081101561088357600080fd5b5035614539565b61042761455a565b610316614564565b60005473ffffffffffffffffffffffffffffffffffffffff16331461092057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600c54626ebe0001421161099557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f76313a206d75737420626520636f6d706c657465640000000000000000000000604482015290519081900360640190fd5b600254604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b158015610a0b57600080fd5b505afa158015610a1f573d6000803e3d6000fd5b505050506040513d6020811015610a3557600080fd5b50519050610a5a73ffffffffffffffffffffffffffffffffffffffff83168483614693565b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b158015610ad057600080fd5b505afa158015610ae4573d6000803e3d6000fd5b505050506040513d6020811015610afa57600080fd5b50519050610b1f73ffffffffffffffffffffffffffffffffffffffff83168683614693565b6040805133815273ffffffffffffffffffffffffffffffffffffffff871660208201528082018590526060810183905290517f8496dda4d04919fec296be83f4d7d178dafb7c0d3abe1553c092f1466e8f29289181900360800190a15050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c0857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b6007805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cda57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60108281548110610d3157600080fd5b90600052602060002090600302018160038110610d4d57600080fd5b015473ffffffffffffffffffffffffffffffffffffffff169150829050565b600d54600090610d9490610d8b90610d85856001614725565b906147a0565b600c5490614725565b92915050565b60075460ff1615610e0c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000816002811115610e1a57fe5b1480610e3157506002816002811115610e2f57fe5b145b610e86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180614f626027913960400191505060405180910390fd5b6000610e906141d1565b905082610efe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f63616e2774206164642030000000000000000000000000000000000000000000604482015290519081900360640190fd5b80600114610f6d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f76313a206d7573742062652065706f63682031206f6e6c790000000000000000604482015290519081900360640190fd5b610f75614d92565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509050610fc1614340565b60e083015260c08201526000836002811115610fd957fe5b1415611036576110138460158481548110610ff057fe5b600091825260208220600390910201905b6003811061100b57fe5b015490614725565b6015838154811061102057fe5b6000918252602082206003919091020101558381525b600283600281111561104457fe5b141561117a5761107160055461106b8360e001518460c0015161472590919063ffffffff16565b90614813565b60208201819052841061108857806020015161108a565b835b80825260055461109a91906147a0565b6060820181905260c0820151106110ba5760608101516080820152611128565b60c08101516080820181905260608201516110d491614855565b60a0820181905260178054611106929190859081106110ef57fe5b600091825260209091206003909102016001611001565b6017838154811061111357fe5b60009182526020909120600390910201600101555b61113d8160800151601684815481106110ef57fe5b6016838154811061114a57fe5b6000918252602090912060039091020160010155805184111561117a578051611174908590614855565b60408201525b600061119061118884614314565b8351906147a0565b82516003549192506111a29190614725565b6003558151600e80546111d4929190869081106111bb57fe5b906000526020600020015461472590919063ffffffff16565b600e84815481106111e157fe5b906000526020600020018190555061121a816012858154811061120057fe5b906000526020600020906003020186600281111561100157fe5b6012848154811061122757fe5b906000526020600020906003020185600281111561124157fe5b6003811061124b57fe5b01558151601380546112639291908690811061120057fe5b6013848154811061127057fe5b906000526020600020906003020185600281111561128a57fe5b6003811061129457fe5b015581516001546112c19173ffffffffffffffffffffffffffffffffffffffff9091169033903090614897565b60028460028111156112cf57fe5b141561130c5761130c33306006548560000151816112e957fe5b60025473ffffffffffffffffffffffffffffffffffffffff169392919004614897565b6010838154811061131957fe5b906000526020600020906003020184600281111561133357fe5b6003811061133d57fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101849052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b1580156113b557600080fd5b505af11580156113c9573d6000803e3d6000fd5b50505050601183815481106113da57fe5b90600052602060002090600302018460028111156113f457fe5b600381106113fe57fe5b01548251604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101929092525173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b15801561147857600080fd5b505af115801561148c573d6000803e3d6000fd5b505050507f058587cdc5efcef45583dc39e6884e853b5c5aef182afe72ca96db6fa1c85c218460028111156114bd57fe5b8360000151846000015185602001518660400151876060015188608001518960a001518a60c001518b60e00151604051808b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a17fc7d2d1a5a726dc6005e76316c12eb5ee642296cc38c1b996651599995a480f3c61156884614314565b8360000151836010878154811061157b57fe5b906000526020600020906003020188600281111561159557fe5b6003811061159f57fe5b015473ffffffffffffffffffffffffffffffffffffffff16878960028111156115c457fe5b3360118b815481106115d257fe5b90600052602060002090600302018c60028111156115ec57fe5b600381106115f657fe5b01546040805198895260208901979097528787019590955273ffffffffffffffffffffffffffffffffffffffff9384166060880152608087019290925260a0860152811660c08501521660e083015251908190036101000190a17f1d69fb63e4692a6ae9a9b249224c389569da92d8e2e96243d71fd6b3bc3055d9600354600e858154811061168157fe5b906000526020600020015460006013878154811061169b57fe5b90600052602060002090600302018860028111156116b557fe5b600381106116bf57fe5b0154601288815481106116ce57fe5b90600052602060002090600302018960028111156116e857fe5b600381106116f257fe5b01546040805195865260208601949094528484019290925260608401526080830152519081900360a00190a15050505050565b600c54600d5482565b600754610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff838116911614801590611837575060025473ffffffffffffffffffffffffffffffffffffffff838116911614155b6118a257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616e6e6f7420737765657020706f6f6c206173736574730000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051839160009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561191357600080fd5b505afa158015611927573d6000803e3d6000fd5b505050506040513d602081101561193d57600080fd5b5051905061196273ffffffffffffffffffffffffffffffffffffffff83168483614693565b6040805133815273ffffffffffffffffffffffffffffffffffffffff80861660208301528616818301526060810183905290517f2c4e64c7c0957a81c0076a0a3f3c7d9f0a5d6158292071c794436f829d12cfb79181900360800190a150505050565b60075460ff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff163314611a5457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b60075460ff1615611ac657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b6000611ad06141d1565b6007805473ffffffffffffffffffffffffffffffffffffffff808616610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff90921691909117909155600154604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051939450859360009392909216916370a0823191602480820192602092909190829003018186803b158015611b8057600080fd5b505afa158015611b94573d6000803e3d6000fd5b505050506040513d6020811015611baa57600080fd5b505160158054919250611be09185908110611bc157fe5b60009182526020822060039190910201015460148581548110610ff057fe5b60148481548110611bed57fe5b600091825260208220600391909102010181905550611c4a60158481548110611c1257fe5b600091825260209091206003909102016002015460148581548110611c3357fe5b600091825260209091206003909102016002611001565b60148481548110611c5757fe5b6000918252602090912060039091020160020181905550611c9f60178481548110611c7e57fe5b6000918252602090912060039091020160010154601685815481106110ef57fe5b60168481548110611cac57fe5b600091825260208220600160039092020101919091556015805485908110611cd057fe5b60009182526020822060039190910201919091556015805485908110611cf257fe5b600091825260208220600260039092020101919091556017805485908110611d1657fe5b6000918252602090912060039091020160010155600854611d379082614725565b6008556040805173ffffffffffffffffffffffffffffffffffffffff861681526020810183905280820185905290517ffc2f950130d4b652317d4d65735fe2c28b9b137f09199cc20367042dedafb6d59181900360600190a1600154611db49073ffffffffffffffffffffffffffffffffffffffff168583614693565b8173ffffffffffffffffffffffffffffffffffffffff16631d2e62d9826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611e0757600080fd5b505af1158015611e1b573d6000803e3d6000fd5b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60128281548110611e5157600080fd5b90600052602060002090600302018160038110611e6d57600080fd5b01549150829050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6000831180611ea15750600081115b611f0c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63616e27742072656d6f76652030000000000000000000000000000000000000604482015290519081900360640190fd5b60075473ffffffffffffffffffffffffffffffffffffffff610100909104811690600090819081908190891615801590611f465750600088115b156124d657611f53614dd7565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601d60209081526040918290208251608081018452815460ff9081161515825260018301549382019390935260028083015491949293928501929190911690811115611fb757fe5b6002811115611fc257fe5b81526020016002820160019054906101000a900460ff166001811115611fe457fe5b6001811115611fef57fe5b905250805190915061206257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f62616c616e636520746f6b656e206c6f6f6b7570206661696c65640000000000604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518b918b9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156120d257600080fd5b505afa1580156120e6573d6000803e3d6000fd5b505050506040513d60208110156120fc57600080fd5b5051101561216b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b602082015160008360600151600181111561218257fe5b146121ee57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6261642064736563206164647265737300000000000000000000000000000000604482015290519081900360640190fd5b8060011461225d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76313a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff166122da57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b6000601282815481106122e957fe5b90600052602060002090600302018460400151600281111561230757fe5b6003811061231157fe5b015490508015612336576123318161106b8e670de0b6b3a76400006147a0565b612339565b60005b9450670de0b6b3a7640000612385866018858154811061235557fe5b90600052602060002090600302018760400151600281111561237357fe5b6003811061237d57fe5b0154906147a0565b8161238c57fe5b049750670de0b6b3a76400006123a9866019858154811061235557fe5b816123b057fe5b0496506123f488601884815481106123c457fe5b9060005260206000209060030201866040015160028111156123e257fe5b600381106123ec57fe5b015490614855565b6018838154811061240157fe5b90600052602060002090600302018560400151600281111561241f57fe5b6003811061242957fe5b018190555061243f87601984815481106123c457fe5b6019838154811061244c57fe5b90600052602060002090600302018560400151600281111561246a57fe5b6003811061247457fe5b018190555061248a8c601284815481106123c457fe5b6012838154811061249757fe5b9060005260206000209060030201856040015160028111156124b557fe5b600381106124bf57fe5b01556004546124ce9089614855565b600455505050505b73ffffffffffffffffffffffffffffffffffffffff8716158015906124fb5750600086115b1561298657612508614dd7565b73ffffffffffffffffffffffffffffffffffffffff88166000908152601d60209081526040918290208251608081018452815460ff908116151582526001830154938201939093526002808301549194929392850192919091169081111561256c57fe5b600281111561257757fe5b81526020016002820160019054906101000a900460ff16600181111561259957fe5b60018111156125a457fe5b905250805190915061261757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f62616c616e636520746f6b656e20696e666f206c6f6f6b7570206661696c6564604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518991899173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561268757600080fd5b505afa15801561269b573d6000803e3d6000fd5b505050506040513d60208110156126b157600080fd5b5051101561272057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b602082015160018360600151600181111561273757fe5b146127a357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6261642062616c616e636520746f6b656e206164647265737300000000000000604482015290519081900360640190fd5b8060011461281257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76313a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff1661288f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b6128be89601383815481106128a057fe5b9060005260206000209060030201856040015160028111156123e257fe5b601382815481106128cb57fe5b9060005260206000209060030201846040015160028111156128e957fe5b600381106128f357fe5b018190555061292289600e838154811061290957fe5b906000526020600020015461485590919063ffffffff16565b600e828154811061292f57fe5b600091825260209091200155600354612948908a614855565b600355600854612958908a614855565b60085560028360400151600281111561296d57fe5b141561298257600654898161297e57fe5b0494505b5050505b73ffffffffffffffffffffffffffffffffffffffff8916158015906129ab5750600088115b15612c3857604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518a918a9173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015612a2057600080fd5b505afa158015612a34573d6000803e3d6000fd5b505050506040513d6020811015612a4a57600080fd5b50511015612ab957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b604080517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b9052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612b2d57600080fd5b505af1158015612b41573d6000803e3d6000fd5b5050604080517f96728a7200000000000000000000000000000000000000000000000000000000815260048101899052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612bb957600080fd5b505af1158015612bcd573d6000803e3d6000fd5b5050600254612bf6925073ffffffffffffffffffffffffffffffffffffffff1690503386614693565b604080518381526020810187905280820186905290517f45d0d3545b4cb7d20e6d592c7158c445e3acda72c55074ab88b0027aa9c2d2789181900360600190a1505b73ffffffffffffffffffffffffffffffffffffffff871615801590612c5d5750600086115b15612edd57604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518891889173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015612cd257600080fd5b505afa158015612ce6573d6000803e3d6000fd5b505050506040513d6020811015612cfc57600080fd5b50511015612d6b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b604080517f9dc29fac00000000000000000000000000000000000000000000000000000000815233600482015260248101899052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b158015612ddf57600080fd5b505af1158015612df3573d6000803e3d6000fd5b5050604080517f96728a72000000000000000000000000000000000000000000000000000000008152600481018b9052336024820152905173ffffffffffffffffffffffffffffffffffffffff8a1693506396728a729250604480830192600092919082900301818387803b158015612e6b57600080fd5b505af1158015612e7f573d6000803e3d6000fd5b5050600254612ea8925073ffffffffffffffffffffffffffffffffffffffff1690503385614693565b6040805188815290517ffbcc912eee8a56d51e3708fe32ba15f4191e6f92b2ccae4f00bbb544dba49f029181900360200190a1505b73ffffffffffffffffffffffffffffffffffffffff891615801590612f025750600088115b80612f2d575073ffffffffffffffffffffffffffffffffffffffff871615801590612f2d5750600086115b612f9857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6e6f20616374696f6e20706572666f726d656400000000000000000000000000604482015290519081900360640190fd5b505050505050505050565b601354831461301357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696d70726f706572206e65772065706f63680000000000000000000000000000604482015290519081900360640190fd5b600e8054600181810190925560007fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90910181905560408051606081018252828152602081018390529081018290526012805493840181559091526130a09160039081027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444019190614dfe565b50604080516060810182526000808252602082018190529181018290526013805460018101825592526130fb9160039081027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090019190614dfe565b50604080516060810182526000808252602082018190529181018290526014805460018101825592526131569160039081027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec019190614dfe565b50604080516060810182526000808252602082018190529181018290526015805460018101825592526131b19160039081027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475019190614dfe565b506040805160608101825260008082526020820181905291810182905260168054600181018255925261320c9160039081027fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b5124289019190614dfe565b50604080516060810182526000808252602082018190529181018290526017805460018101825592526132679160039081027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15019190614dfe565b50604080516060810182526000808252602082018190529181018290526018805460018101825592526132c29160039081027fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e019190614dfe565b506040805160608101825260008082526020820181905291810182905260198054600181018255925261331d9160039081027f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695019190614dfe565b506040805160608101909152601090808460008151811061333a57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460018151811061336c57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460028151811061339e57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206133e59260039081029091019190614e41565b506040805160608101909152601190808360008151811061340257fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360018151811061343457fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018360028151811061346657fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206134ad9260039081029091019190614e41565b506040805160808101825260018152602081018590529081016000815260200160009052601d60008481815181106134e157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561357157fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156135b257fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160009052601d6000846001815181106135ef57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561367f57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156136c057fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160009052601d6000846002815181106136fb57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561378b57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137cc57fe5b021790555050604080516080810182526001815260208101869052915081016000815260200160019052601d600083818151811061380657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600281111561389657fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156138d757fe5b0217905550506040805160808101825260018082526020820187905290925090820190815260200160019052601d60008360018151811061391457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360028111156139a457fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156139e557fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160019052601d600083600281518110613a2057fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836002811115613ab057fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115613af157fe5b02179055505050505050565b60055481565b60188281548110611e5157600080fd5b60118281548110610d3157600080fd5b60045481565b60148281548110611e5157600080fd5b600b5473ffffffffffffffffffffffffffffffffffffffff163314613bbf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b6000828152600f602052604090205460ff1615613c3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f65706f636820616c726561647920776f756e6420646f776e0000000000000000604482015290519081900360640190fd5b6000613c476141d1565b9050808310613cb757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e6e6f742077696e6420646f776e206675747572652065706f6368000000604482015290519081900360640190fd5b613cbf614eae565b506040805160c081018252600060208201819052918101829052606081018290526080810182905260a08101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201808252613d1e90610d6c565b421015613d8c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e27742063616c6c206265666f72652065706f636820656e646564000000604482015290519081900360640190fd5b601a54613da290620186a09061106b90866147a0565b60198581548110613daf57fe5b600091825260208220600391909102010155601b54613dd790620186a09061106b90866147a0565b60198581548110613de457fe5b6000918252602090912060039091020160010155601c54613e0e90620186a09061106b90866147a0565b60198581548110613e1b57fe5b60009182526020909120600390910201600201558051601980547f02ac5b59c8ff91aed9818435a4a06bf88afedae653001d8d7086f29057eca88c92919087908110613e6357fe5b60009182526020822060039190910201015460198781548110613e8257fe5b600091825260209091206003909102016001015460198881548110613ea357fe5b6000918252602090912060039091020160020154604080519485526020850193909352838301919091526060830152519081900360800190a1600754600854604080517f1a2b383200000000000000000000000000000000000000000000000000000000815260048101929092525161010090920473ffffffffffffffffffffffffffffffffffffffff16918291631a2b38329160248083019260209291908290030181600087803b158015613f5857600080fd5b505af1158015613f6c573d6000803e3d6000fd5b505050506040513d6020811015613f8257600080fd5b505160208301819052600454613f9791614725565b600481905550613fce60128681548110613fad57fe5b600091825260209091206003909102016002015460128781548110610ff057fe5b82604001818152505061400f826040015161106b670de0b6b3a764000060128981548110613ff857fe5b600091825260209091206003909102016002612373565b60608301819052600554602084015161403a92610d8591670de0b6b3a76400009161106b91906147a0565b60808301819052602083015161404f91614855565b60a08301819052601880548790811061406457fe5b6000918252602082206003919091020191909155601880548790811061408657fe5b6000918252602090912060039091020160010155608082015160188054879081106140ad57fe5b60009182526020909120600390910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858360a001516000856080015160198a815481106140ff57fe5b60009182526020822060039190910201015460198b8154811061411e57fe5b600091825260209091206003909102016001015460198c8154811061413f57fe5b6000918252602090912060039091020160020154604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190a16000858152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556141c9614eae565b505050505050565b600c54600090421161424457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6265666f72652065706f63682030000000000000000000000000000000000000604482015290519081900360640190fd5b600d54600c5442038161425357fe5b04905090565b60198281548110611e5157600080fd5b60138281548110611e5157600080fd5b601a54601b54601c5483565b60178281548110611e5157600080fd5b600f6020526000908152604090205460ff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b600b5473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b60085481565b60168281548110611e5157600080fd5b60035481565b60158281548110611e5157600080fd5b6000610d944261433a610d8b600c60010154610d8560018861472590919063ffffffff16565b90614855565b600080600061434d6141d1565b905060006143826016838154811061436157fe5b600091825260209091206003909102016001015460168481548110611c3357fe5b905060006143b76017848154811061439657fe5b600091825260209091206003909102016001015460178581548110611c3357fe5b90506000601484815481106143c857fe5b60009182526020822060039190910201015490506000601585815481106143eb57fe5b600091825260208220600391909102010154905083821161440d576000614411565b8382035b83821161441f576000614423565b8382035b9650965050505050509091565b60005473ffffffffffffffffffffffffffffffffffffffff1633146144b657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600c54622e248001421161452b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f746f6f20736f6f6e000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61453760096000614ee4565b565b600e818154811061454957600080fd5b600091825260209091200154905081565b600c54600d549091565b600b5473ffffffffffffffffffffffffffffffffffffffff1633146145ea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b620151806145f86001610d6c565b03421161466657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f747279696e6720746f2073687574646f776e20746f6f206561726c7900000000604482015290519081900360640190fd5b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052614720908490614932565b505050565b60008282018381101561479957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000826147af57506000610d94565b828202828482816147bc57fe5b0414614799576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614f416021913960400191505060405180910390fd5b600061479983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a0a565b600061479983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614ac6565b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261492c908590614932565b50505050565b6060614994826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614b3a9092919063ffffffff16565b805190915015614720578080602001905160208110156149b357600080fd5b5051614720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614f89602a913960400191505060405180910390fd5b60008183614ab0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614a75578181015183820152602001614a5d565b50505050905090810190601f168015614aa25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614abc57fe5b0495945050505050565b60008184841115614b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315614a75578181015183820152602001614a5d565b505050900390565b6060614b498484600085614b51565b949350505050565b606082471015614bac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614f1b6026913960400191505060405180910390fd5b614bb585614d0c565b614c2057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310614c8a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614c4d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614cec576040519150601f19603f3d011682016040523d82523d6000602084013e614cf1565b606091505b5091509150614d01828286614d12565b979650505050505050565b3b151590565b60608315614d21575081614799565b825115614d315782518084602001fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451859391928392604401919085019080838360008315614a75578181015183820152602001614a5d565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60408051608081018252600080825260208201819052909182019081526020016000905290565b8260038101928215614e31579160200282015b82811115614e31578251829060ff16905591602001919060010190614e11565b50614e3d929150614f05565b5090565b8260038101928215614e31579160200282015b82811115614e3157825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614e54565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5080546000825590600052602060002090810190614f029190614f05565b50565b5b80821115614e3d5760008155600101614f0656fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7776313a2063616e2774206164645f6c697175696469747920696e746f204141207472616e6368655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a07ec068cfe82666ea6686f72accf698858cf6f7079a4522c940db620bea226364736f6c63430007040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000257bbc6241cf0054b2307d01b2b326d235be8fa10000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c
-----Decoded View---------------
Arg [0] : _strategy (address): 0x257BBc6241cf0054B2307D01b2b326D235BE8FA1
Arg [1] : _base_asset (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [2] : _SFI_address (address): 0xb753428af26E81097e7fD17f40c88aaA3E04902c
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000257bbc6241cf0054b2307d01b2b326d235be8fa1
Arg [1] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [2] : 000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c
Deployed Bytecode Sourcemap
36251:26428:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62140:536;;;;;;;;;;;;;;;;-1:-1:-1;62140:536:0;;;;:::i;:::-;;59507:147;;;;;;;;;;;;;;;;-1:-1:-1;59507:147:0;;;;:::i;59357:144::-;;;;;;;;;;;;;;;;-1:-1:-1;59357:144:0;;;;:::i;38098:40::-;;;;;;;;;;;;;;;;-1:-1:-1;38098:40:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;59696:154;;;;;;;;;;;;;;;;-1:-1:-1;59696:154:0;;:::i;:::-;;;;;;;;;;;;;;;;44614:4166;;;;;;;;;;;;;;;;-1:-1:-1;44614:4166:0;;;;;;;;;:::i;37562:164::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;37118:35;;;:::i;36545:26::-;;;:::i;61667:393::-;;;;;;;;;;;;;;;;-1:-1:-1;61667:393:0;;;;;;;;;;;:::i;36967:29::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;57608:1497;;;;;;;;;;;;;;;;-1:-1:-1;57608:1497:0;;;;:::i;36451:33::-;;;:::i;38271:38::-;;;;;;;;;;;;;;;;-1:-1:-1;38271:38:0;;;;;;;:::i;36357:25::-;;;:::i;52643:4811::-;;;;;;;;;;;;;;;;-1:-1:-1;52643:4811:0;;;;;;;;;;;;;;;;;;;;;:::i;40759:2681::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40759:2681:0;;;;;;;;-1:-1:-1;40759:2681:0;;-1:-1:-1;;40759:2681:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40759:2681:0;;-1:-1:-1;40759:2681:0;;-1:-1:-1;;;;;40759:2681: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;49331:3157::-;;;;;;;;;;;;;;;;-1:-1:-1;49331:3157:0;;;;;;;:::i;59856:218::-;;;:::i;39002:38::-;;;;;;;;;;;;;;;;-1:-1:-1;39002:38:0;;;;;;;:::i;38355:43::-;;;;;;;;;;;;;;;;-1:-1:-1;38355:43:0;;;;;;;:::i;39371:114::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;38767:48;;;;;;;;;;;;;;;;-1:-1:-1;38767:48:0;;;;;;;:::i;37873:46::-;;;;;;;;;;;;;;;;-1:-1:-1;37873:46:0;;:::i;61182: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;60080:189::-;;;;;;;;;;;;;;;;-1:-1:-1;60080:189:0;;:::i;60296:722::-;;;:::i;61382:204::-;;;:::i;37770:32::-;;;;;;;;;;;;;;;;-1:-1:-1;37770:32:0;;:::i;61026:150::-;;;:::i;59111:216::-;;;:::i;62140:536::-;62204:10;;;;62190;:24;62182:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62270:11;:22;62295:8;62270:33;62252:15;:51;62244:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62366:11;;62403:28;;;;;;62425:4;62403:28;;;;;;62366:11;;;;;62338:10;;62366:11;;62403:13;;:28;;;;;;;;;;;;;;;62366:11;62403:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62403:28:0;;-1:-1:-1;62438:29:0;:16;;;62455:3;62403:28;62438:16;:29::i;:::-;62505:18;;62550:29;;;;;;62573:4;62550:29;;;;;;62505:18;;;;;62476:11;;62505:18;;62550:14;;:29;;;;;;;;;;;;;;;62505:18;62550:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62550:29:0;;-1:-1:-1;62586:31:0;:17;;;62604:3;62550:29;62586:17;:31::i;:::-;62631:39;;;62637:10;62631:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62140:536;;;;;:::o;59507:147::-;59583:10;;;;59569;:24;59561:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59623:20;:25;;;;;;;;;;;;;;;;;;59507:147::o;59357:144::-;59440:10;;;;59426;:24;59418:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59480:10;:15;;;;;;;;;;;;;;;59357:144::o;38098:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38098:40:0;;-1:-1:-1;38098:40:0:o;59696:154::-;59822:20;;59755:7;;59778:66;;59805:38;;:12;:5;59822:20;59805:9;:12::i;:::-;:16;;:38::i;:::-;59778:11;:22;;:26;:66::i;:::-;59771:73;59696:154;-1:-1:-1;;59696:154:0:o;44614:4166::-;44704:9;;;;44703:10;44695:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44757:9;44746:7;:20;;;;;;;;;:44;;;-1:-1:-1;44781:9:0;44770:7;:20;;;;;;;;;44746:44;44738:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44841:13;44857:19;:17;:19::i;:::-;44841:35;-1:-1:-1;44891:11:0;44883:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44933:5;44942:1;44933:10;44925:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45020:21;;:::i;:::-;45044:222;;;;;;;;45074:1;45044:222;;;;45095:1;45044:222;;;;45113:1;45044:222;;;;45135:1;45044:222;;;;45164:1;45044:222;;;;45195:1;45044:222;;;;45225:1;45044:222;;;;45257:1;45044:222;;;45020:246;;45324:26;:24;:26::i;:::-;45297:23;;;45273:77;45274:21;;;45273:77;-1:-1:-1;45363:7:0;:20;;;;;;;;;45359:188;;;45448:63;45504:6;45448:24;45473:5;45448:31;;;;;;;;;;;;;;;;;;;;;45480:18;45448:51;;;;;;;;;;:55;:63::i;:::-;45394:24;45419:5;45394:31;;;;;;;;;;;;;;;;;;;;;:51;:117;45520:19;;;45359:188;45663:9;45652:7;:20;;;;;;;;;45648:1265;;;45859:78;45916:20;;45860:50;45886:2;:23;;;45860:2;:21;;;:25;;:50;;;;:::i;:::-;45859:56;;:78::i;:::-;45845:11;;;:92;;;45962:20;;45961:45;;45995:2;:11;;;45961:45;;;45986:6;45961:45;45947:59;;;46044:20;;46029:36;;45947:59;46029:14;:36::i;:::-;46015:11;;;:50;;;46093:21;;;;-1:-1:-1;46074:618:0;;46246:11;;;;46223:20;;;:34;46074:618;;;46434:21;;;;46411:20;;;:44;;;46491:11;;;;:37;;:15;:37::i;:::-;46466:22;;;:62;;;46598:28;:35;;:84;;46466:62;46598:28;46627:5;;46598:35;;;;;;;;;;;;;;;;;;;46642:10;46634:19;;46598:84;46539:28;46568:5;46539:35;;;;;;;;;;;;;;;;;;;;;46583:10;46539:56;:143;46074:618;46757:80;46816:2;:20;;;46757:26;46784:5;46757:33;;;;;;;:80;46700:26;46727:5;46700:33;;;;;;;;;;;;;;;;;;;;;46742:10;46700:54;:137;46850:10;;:19;-1:-1:-1;46846:59:0;;;46894:10;;46883:22;;:6;;:10;:22::i;:::-;46871:9;;;:34;46846:59;46966:12;46981:50;46996:34;47024:5;46996:27;:34::i;:::-;46981:10;;;:14;:50::i;:::-;47130:10;;47111:14;;46966:65;;-1:-1:-1;47111:30:0;;:14;:18;:30::i;:::-;47094:14;:47;47247:10;;47220:15;:22;;:38;;47247:10;47220:15;47236:5;;47220:22;;;;;;;;;;;;;;:26;;:38;;;;:::i;:::-;47195:15;47211:5;47195:22;;;;;;;;;;;;;;;:63;;;;47396:53;47444:4;47396:18;47415:5;47396:25;;;;;;;;;;;;;;;;;;47430:7;47422:16;;;;;;;47396:53;47350:18;47369:5;47350:25;;;;;;;;;;;;;;;;;;47384:7;47376:16;;;;;;;;47350:43;;;;;;;;:99;47560:10;;47507:23;:30;;:64;;47560:10;47507:23;47531:5;;47507:30;;;;;:64;47456:23;47480:5;47456:30;;;;;;;;;;;;;;;;;;47495:7;47487:16;;;;;;;;47456:48;;;;;;;;:115;47688:10;;47624:18;;47617:82;;47624:18;;;;;47661:10;;47681:4;;47617:43;:82::i;:::-;47721:9;47710:7;:20;;;;;;;;;47706:113;;;47732:87;47769:10;47789:4;47809:9;;47796:2;:10;;;:22;;;;;47739:11;;;;;47732:87;;47796:22;;47732:36;:87::i;:::-;47930:20;47951:5;47930:27;;;;;;;;;;;;;;;;;;47966:7;47958:16;;;;;;;;47930:45;;;;;;;;;47908:91;;;;;;47982:10;47908:91;;;;;;;;;;;;47930:45;;;;;47908:73;;:91;;;;;47930:45;;47908:91;;;;;;;;47930:45;;47908:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48115:25;48141:5;48115:32;;;;;;;;;;;;;;;;;;48156:7;48148:16;;;;;;;;48115:50;;;;;;;;;48184:10;;48093:102;;;;;;48172:10;48093:102;;;;;;;;;;;;48115:50;;;;;48093:78;;:102;;;;;48115:50;;48093:102;;;;;;;;48115:50;;48093:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48209:187;48232:7;48224:16;;;;;;;;48242:2;:10;;;48254:2;:10;;;48266:2;:11;;;48279:2;:9;;;48290:2;:11;;;48303:2;:20;;;48325:2;:22;;;48349:2;:21;;;48372:2;:23;;;48209:187;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48408:204;48423:34;48451:5;48423:27;:34::i;:::-;48459:2;:10;;;48471:4;48477:20;48498:5;48477:27;;;;;;;;;;;;;;;;;;48513:7;48505:16;;;;;;;;48477:45;;;;;;;;;;;48524:5;48539:7;48531:16;;;;;;;;48549:10;48561:25;48587:5;48561:32;;;;;;;;;;;;;;;;;;48602:7;48594:16;;;;;;;;48561:50;;;;;;;;;48408:204;;;;;;;;;;;;;;;;;;;;48561:50;48408:204;;;;;;;;;;;;;;;;;;;;;;;;48561:50;48408:204;;;;;;;;;48561:50;48408:204;;;48624:150;48637:14;;48653:15;48669:5;48653:22;;;;;;;;;;;;;;;;48677:1;48680:23;48704:5;48680:30;;;;;;;;;;;;;;;;;;48719:7;48711:16;;;;;;;;48680:48;;;;;;;;;48730:18;48749:5;48730:25;;;;;;;;;;;;;;;;;;48764:7;48756:16;;;;;;;;48730:43;;;;;;;;;48624:150;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44614:4166;;;;;:::o;37562:164::-;;;;;;:::o;37118:35::-;;;;;;;;;:::o;36545:26::-;;;;;;:::o;61667:393::-;61751:10;;;;61737;:24;61729:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61809:18;;;61799:28;;;61809:18;;61799:28;;;;:53;;-1:-1:-1;61841:11:0;;;61831:21;;;61841:11;;61831:21;;61799:53;61791:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61939:28;;;;;;61961:4;61939:28;;;;;;61910:6;;61890:10;;61939:13;;;;;;:28;;;;;;;;;;;;;;:13;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61939:28:0;;-1:-1:-1;61974:27:0;:16;;;61991:3;61939:28;61974:16;:27::i;:::-;62015:39;;;62024:10;62015:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61667:393;;;;:::o;36967:29::-;;;;;;:::o;57608:1497::-;57705:8;;;;57691:10;:22;57683:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57750:9;;;;57749:10;57741:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57784:13;57800:19;:17;:19::i;:::-;57826:20;:38;;;;;;;;;;;;;;;;;;;:20;57965:18;57958:51;;;;;;58003:4;57958:51;;;;;;57784:35;;-1:-1:-1;57849:15:0;;-1:-1:-1;;57965:18:0;;;;;57958:36;;:51;;;;;;;;;;;;;;;57965:18;57958:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57958:51:0;58179:24;:31;;57958:51;;-1:-1:-1;58125:106:0;;58204:5;;58179:31;;;;;;;;;;;;;;;;;;;:51;;58125:22;58148:5;58125:29;;;;;;;:106;58073:22;58096:5;58073:29;;;;;;;;;;;;;;;;;;;;;:49;:158;;;;58290:106;58344:24;58369:5;58344:31;;;;;;;;;;;;;;;;;;;;;58384:9;58344:51;;58290:22;58313:5;58290:29;;;;;;;;;;;;;;;;;;;;;58328:9;58320:18;;58290:106;58238:22;58261:5;58238:29;;;;;;;;;;;;;;;;;;;;;58276:9;58238:49;:158;;;;58460:116;58519:28;58548:5;58519:35;;;;;;;;;;;;;;;;;;;;;58563:10;58519:56;;58460:26;58487:5;58460:33;;;;;;;:116;58403:26;58430:5;58403:33;;;;;;;;;;;;;;;58445:10;58403:33;;;;;:54;:173;;;;58585:24;:31;;58610:5;;58585:31;;;;;;;;;;;;;;;;;;;:55;;;;58647:24;:31;;58672:5;;58647:31;;;;;;;;;;;;;58687:9;58647:31;;;;;:51;:55;;;;58709:28;:35;;58738:5;;58709:35;;;;;;;;;;;;;;;;;;;58753:10;58709:56;:60;58843:23;;:35;;58871:6;58843:27;:35::i;:::-;58817:23;:61;58890:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59000:18;;58993:64;;59000:18;;59033:15;59050:6;58993:39;:64::i;:::-;59064:12;:27;;;59092:6;59064:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57608:1497;;;;:::o;36451:33::-;;;;;;:::o;38271:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38271:38:0;;-1:-1:-1;38271:38:0:o;36357:25::-;;;;;;:::o;52643:4811::-;52824:1;52810:11;:15;:39;;;;52848:1;52829:16;:20;52810:39;52802:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52922:20;;;;;;;;;;52875:28;;;;;;;;53108:34;;;;;;:53;;;53160:1;53146:11;:15;53108:53;53104:1796;;;53257:36;;:::i;:::-;53296:41;;;;;;;:21;:41;;;;;;;;;53257:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53296:41;;53257:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53354:17:0;;53257:80;;-1:-1:-1;53346:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53498:25;;;;;;53512:10;53498:25;;;;;;53462:18;;53527:11;;53498:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53498:25:0;:40;;53490:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53644:16;;;;53622:19;53677:10;:21;;;:41;;;;;;;;;53669:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53756:11;53771:1;53756:16;53748:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53823:29;;;;:16;:29;;;;;;;;53815:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53898:20;53921:18;53940:11;53921:31;;;;;;;;;;;;;;;;;;53961:10;:18;;;53953:27;;;;;;;;53921:60;;;;;;;;;;-1:-1:-1;54081:17:0;;54080:68;;54106:42;54135:12;54106:24;:11;54122:7;54106:15;:24::i;:42::-;54080:68;;;54102:1;54080:68;54065:83;;54260:7;54174:83;54244:12;54174:23;54198:11;54174:36;;;;;;;;;;;;;;;;;;54219:10;:18;;;54211:27;;;;;;;;54174:65;;;;;;;;;;:69;:83::i;:::-;:93;;;;;;54157:110;;54368:7;54287:78;54352:12;54287:18;54306:11;54287:31;;;;;;;:78;:88;;;;;;54276:99;;54454:85;54524:14;54454:23;54478:11;54454:36;;;;;;;;;;;;;;;;;;54499:10;:18;;;54491:27;;;;;;;;54454:65;;;;;;;;;;:69;:85::i;:::-;54386:23;54410:11;54386:36;;;;;;;;;;;;;;;;;;54431:10;:18;;;54423:27;;;;;;;;54386:65;;;;;;;;:153;;;;54611:74;54676:8;54611:18;54630:11;54611:31;;;;;;;:74;54548:18;54567:11;54548:31;;;;;;;;;;;;;;;;;;54588:10;:18;;;54580:27;;;;;;;;54548:60;;;;;;;;:137;;;;54757:77;54822:11;54757:18;54776:11;54757:31;;;;;;;:77;54694:18;54713:11;54694:31;;;;;;;;;;;;;;;;;;54734:10;:18;;;54726:27;;;;;;;;54694:60;;;;;;;;:140;54859:13;;:33;;54877:14;54859:17;:33::i;:::-;54843:13;:49;-1:-1:-1;;;;53104:1796:0;54965:39;;;;;;;:63;;;55027:1;55008:16;:20;54965:63;54961:1327;;;55124:36;;:::i;:::-;55163:46;;;;;;;:21;:46;;;;;;;;;55124:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55163:46;;55124:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55226:17:0;;55124:85;;-1:-1:-1;55218:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55380:25;;;;;;55394:10;55380:25;;;;;;55339:23;;55409:16;;55380:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55380:25:0;:45;;55372:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55536:16;;;;55594:21;55569:10;:21;;;:46;;;;;;;;;55561:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55662:11;55677:1;55662:16;55654:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55729:29;;;;:16;:29;;;;;;;;55721:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55874:87;55944:16;55874:23;55898:11;55874:36;;;;;;;;;;;;;;;;;;55919:10;:18;;;55911:27;;;;;;;55874:87;55806:23;55830:11;55806:36;;;;;;;;;;;;;;;;;;55851:10;:18;;;55843:27;;;;;;;;55806:65;;;;;;;;:155;;;;56001:50;56034:16;56001:15;56017:11;56001:28;;;;;;;;;;;;;;;;:32;;:50;;;;:::i;:::-;55970:15;55986:11;55970:28;;;;;;;;;;;;;;;;;:81;56077:14;;:36;;56096:16;56077:18;:36::i;:::-;56060:14;:53;56148:23;;:45;;56176:16;56148:27;:45::i;:::-;56122:23;:71;56228:9;56206:10;:18;;;:31;;;;;;;;;56202:78;;;56271:9;;56252:16;:28;;;;;;56239:41;;56202:78;54961:1327;;;;56317:34;;;;;;;:53;;;56369:1;56355:11;:15;56317:53;56313:474;;;56467:25;;;;;;56481:10;56467:25;;;;;;56431:18;;56496:11;;56467:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56467:25:0;:40;;56459:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56546:33;;;;;;56555:10;56546:33;;;;;;;;;;;;:8;;;;;;:33;;;;;-1:-1:-1;;56546:33:0;;;;;;;-1:-1:-1;56546:8:0;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56588:55:0;;;;;;;;;;;;56632:10;56588:55;;;;;;:27;;;;-1:-1:-1;56588:27:0;;-1:-1:-1;56588:55:0;;;;;-1:-1:-1;;56588:55:0;;;;;;;-1:-1:-1;56588:27:0;:55;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56659:11:0;;56652:54;;-1:-1:-1;56659:11:0;;;-1:-1:-1;56685:10:0;56697:8;56652:32;:54::i;:::-;56720:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56313:474;;56797:39;;;;;;;:63;;;56859:1;56840:16;:20;56797:63;56793:491;;;56962:25;;;;;;56976:10;56962:25;;;;;;56921:23;;56991:16;;56962:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56962:25:0;:45;;56954:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57051:38;;;;;;57060:10;57051:38;;;;;;;;;;;;:8;;;;;;:38;;;;;-1:-1:-1;;57051:38:0;;;;;;;-1:-1:-1;57051:8:0;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57098:57:0;;;;;;;;;;;;57144:10;57098:57;;;;;;:27;;;;-1:-1:-1;57098:27:0;;-1:-1:-1;57098:57:0;;;;;-1:-1:-1;;57098:57:0;;;;;;;-1:-1:-1;57098:27:0;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57171:11:0;;57164:56;;-1:-1:-1;57171:11:0;;;-1:-1:-1;57197:10:0;57209;57164:32;:56::i;:::-;57234:42;;;;;;;;;;;;;;;;;56793:491;;57301:34;;;;;;;:53;;;57353:1;57339:11;:15;57301:53;57300:124;;;-1:-1:-1;57360:39:0;;;;;;;:63;;;57422:1;57403:16;:20;57360:63;57292:156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52643:4811;;;;;;;;;:::o;40759:2681::-;40920:23;:30;:39;;40912:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40991:15;:23;;;;;;;;;41012:1;40991:23;;;;;;;41021:32;;;;;;;;;;;40991:23;41021:32;;;;;;;;;;;:18;:32;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41060:37:0;;;;;;;;-1:-1:-1;41060:37:0;;;;;;;;;;;;;;;:23;:37;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41104:36:0;;;;;;;;-1:-1:-1;41104:36:0;;;;;;;;;;;;;;;:22;:36;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41147:38:0;;;;;;;;-1:-1:-1;41147:38:0;;;;;;;;;;;;;;;:24;:38;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41192:40:0;;;;;;;;-1:-1:-1;41192:40:0;;;;;;;;;;;;;;;:26;:40;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41239:42:0;;;;;;;;-1:-1:-1;41239:42:0;;;;;;;;;;;;;;;:28;:42;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41288:37:0;;;;;;;;-1:-1:-1;41288:37:0;;;;;;;;;;;;;;;:23;:37;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41332:32:0;;;;;;;;-1:-1:-1;41332:32:0;;;;;;;;;;;;;;;:18;:32;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41373:252:0;;;;;;;;;:20;;:252;41445:31;-1:-1:-1;41445:51:0;;;;;;;;;;;;;;;;;;;41373:252;;;;;41505:31;41545:10;41505:52;;;;;;;;;;;;;;;;;;;41373:252;;;;;41566:31;41606:9;41566:51;;;;;;;;;;;;;;;;;;;41373:252;;;;;;;;;;;;-1:-1:-1;41373:252:0;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41634:272:0;;;;;;;;;:25;;:272;41711:36;-1:-1:-1;41711:56:0;;;;;;;;;;;;;;;;;;;41634:272;;;;;41776:36;41821:10;41776:57;;;;;;;;;;;;;;;;;;;41634:272;;;;;41842:36;41887:9;41842:56;;;;;;;;;;;;;;;;;;;41634:272;;;;;;;;;;;;-1:-1:-1;41634:272:0;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;42085:133:0;;;;;;;;42121:4;42085:133;;;;;;;;;;;-1:-1:-1;42085:133:0;;;;42194:16;42085:133;;42008:21;:74;42030:31;42008:74;42030:51;;;;;;;;;;;;;;42008:74;;;;;;;;;;;;;;;:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42008:210:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42305:134:0;;;;;;;;42341:4;42305:134;;;;;;;;;;;-1:-1:-1;42305:134:0;;;;;;;;42415:16;42305:134;;42227:21;:75;42249:31;42289:10;42249:52;;;;;;;;;;;;;;42227:75;;;;;;;;;;;;;;;:212;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42227:212:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42525:133:0;;;;;;;;42561:4;42525:133;;;;;;;;;-1:-1:-1;42525:133:0;;42604:9;42525:133;;;;42634:16;42525:133;;42448:21;:74;42470:31;42510:9;42470:51;;;;;;;;;;;;;;42448:74;;;;;;;;;;;;;;;:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42448:210:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42836:138:0;;;;;;;;42872:4;42836:138;;;;;;;;;-1:-1:-1;42836:138:0;;-1:-1:-1;42836:138:0;;;;42945:21;42836:138;;42754:21;:79;42776:36;42754:79;42776:56;;;;;;;;;;;;;;42754:79;;;;;;;;;;;;;;;:220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42754:220:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43066:139:0;;;;;;;;43102:4;43066:139;;;;;;;;;;;-1:-1:-1;43066:139:0;;;;;;;;43176:21;43066:139;;42983:21;:80;43005:36;43050:10;43005:57;;;;;;;;;;;;;;42983:80;;;;;;;;;;;;;;;:222;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42983:222:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43296:138:0;;;;;;;;43332:4;43296:138;;;;;;;;;-1:-1:-1;43296:138:0;;43375:9;43296:138;;;;43405:21;43296:138;;43214:21;:79;43236:36;43281:9;43236:56;;;;;;;;;;;;;;43214:79;;;;;;;;;;;;;;;:220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43214:220:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;40759:2681:0:o;36785:35::-;;;;:::o;38898:43::-;;;;;;;;;;;;38182:45;;;;;;;;;;;;36689:28;;;;:::o;38446:42::-;;;;;;;;;;;;49331:3157;49436:8;;;;49422:10;:22;49414:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49481:23;;;;:16;:23;;;;;;;;49480:24;49472:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49540:21;49564:19;:17;:19::i;:::-;49540:43;;49606:13;49598:5;:21;49590:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49660:29;;:::i;:::-;-1:-1:-1;49692:191:0;;;;;;;;-1:-1:-1;49692:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49917:17;;;49890:44;;;49968:39;;:13;:39::i;:::-;49949:15;:58;;49941:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50142:22;:24;:52;;50187:6;;50142:40;;50171:10;50142:28;:40::i;:52::-;50093:18;50112:5;50093:25;;;;;;;;;;;;;;;;;;;;;:45;:101;50250:25;;:53;;50296:6;;50250:41;;50280:10;50250:29;:41::i;:53::-;50201:18;50220:5;50201:25;;;;;;;;;;;;;;;;;;;;;50235:10;50201:46;:102;50359:24;;:52;;50404:6;;50359:40;;50388:10;50359:28;:40::i;:52::-;50310:18;50329:5;50310:25;;;;;;;;;;;;;;;;;;;;;50344:9;50310:45;:101;50442:24;;50468:18;:25;;50425:184;;50442:24;50468:18;50487:5;;50468:25;;;;;;;;;;;;;;;;;;;:45;;50515:18;50534:5;50515:25;;;;;;;;;;;;;;;;;;;;;50549:10;50515:46;;50563:18;50582:5;50563:25;;;;;;;;;;;;;;;;;;;;;50597:9;50563:45;;50425:184;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50997:20;;51073:23;;51052:45;;;;;;;;;;;;;;50997:20;;;;;;;;;51052;;:45;;;;;;;;;;;;;;-1:-1:-1;50997:20:0;51052:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51052:45:0;;51025:24;;:72;;;51120:13;;:43;;:17;:43::i;:::-;51104:13;:59;;;;51268:96;51318:18;51337:5;51318:25;;;;;;;;;;;;;;;;;;;;;51352:9;51318:45;;51268:18;51287:5;51268:25;;;;;;;:96;51245:9;:20;;:119;;;;;51408:84;51471:9;:20;;;51408:58;51458:7;51408:18;51427:5;51408:25;;;;;;;;;;;;;;;;;;;;;51442:9;51434:18;;51408:84;51371:34;;;:121;;;51660:20;;51577:24;;;;51576:105;;51577:77;;51646:7;;51577:64;;:24;:28;:64::i;51576:105::-;51545:28;;;:136;;;51719:24;;;;:58;;:28;:58::i;:::-;51688:28;;;:89;;;51828:23;:30;;51852:5;;51828:30;;;;;;;;;;;;;;;;;;;:82;;;;51917:23;:30;;51941:5;;51917:30;;;;;;;;;;;;;;;;;;;51956:10;51917:51;:55;52033:28;;;;51979:23;:30;;52003:5;;51979:30;;;;;;;;;;;;;;;;;;;52018:9;51979:50;:82;;;;52165:257;52184:5;52191:9;:28;;;52221:1;52224:9;:28;;;52262:18;52281:5;52262:25;;;;;;;;;;;;;;;;;;;;;:45;;52318:18;52337:5;52318:25;;;;;;;;;;;;;;;;;;;;;52352:10;52318:46;;52375:18;52394:5;52375:25;;;;;;;;;;;;;;;;;;;;;52409:9;52375:45;;52165:257;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52429:23;;;;:16;:23;;;;;:30;;;;52455:4;52429:30;;;52466:16;;:::i;:::-;-1:-1:-1;;;;;;49331:3157:0:o;59856:218::-;59948:11;:22;59906:7;;59930:15;:40;59922:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60048:20;;:11;60022:22;60004:15;:40;60048:20;60003:65;;;;;59996:72;;59856:218;:::o;39002:38::-;;;;;;;;;;;;38355:43;;;;;;;;;;;;39371:114;;;;;;;;:::o;38767:48::-;;;;;;;;;;;;37873:46;;;;;;;;;;;;;;;:::o;61182:112::-;61270:18;;;;61182:112;:::o;37510:23::-;;;;;;:::o;36867:24::-;;;;:::o;37216:38::-;;;;:::o;38638:46::-;;;;;;;;;;;;36598:29;;;;:::o;38541:44::-;;;;;;;;;;;;60080:189;60153:7;60176:87;60247:15;60176:66;60203:38;60220:11;:20;;;60203:12;60213:1;60203:5;:9;;:12;;;;:::i;60176:66::-;:70;;:87::i;60296:722::-;60352:7;60361;60377:13;60393:19;:17;:19::i;:::-;60377:35;;60419:21;60443:113;60501:26;60528:5;60501:33;;;;;;;;;;;;;;;;;;;;;60543:10;60501:54;;60443:26;60470:5;60443:33;;;;;;;:113;60419:137;;60563:23;60589:117;60649:28;60678:5;60649:35;;;;;;;;;;;;;;;;;;;;;60693:10;60649:56;;60589:28;60618:5;60589:35;;;;;;;:117;60563:143;;60713:18;60734:22;60757:5;60734:29;;;;;;;;;;;;;;;;;;;;;:49;;60713:70;;60790:20;60813:24;60838:5;60813:31;;;;;;;;;;;;;;;;;;;;;:51;;60790:74;;60893:13;60880:10;:26;:59;;60938:1;60880:59;;;60922:13;60909:10;:26;60880:59;60958:15;60943:12;:30;:67;;61009:1;60943:67;;;60991:15;60976:12;:30;60943:67;60871:141;;;;;;;;;60296:722;;:::o;61382:204::-;61447:10;;;;61433;:24;61425:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61513:11;:22;61538:7;61513:32;61495:15;:50;61487:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61565:15;61572:8;;61565:15;:::i;:::-;61382:204::o;37770:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37770:32:0;:::o;61026:150::-;61125:11;:22;61149:20;;61026:150;;:::o;59111:216::-;59178:8;;;;59164:10;:22;59156:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59259:6;59240:16;59254:1;59240:13;:16::i;:::-;:25;59222:15;:43;59214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59305:9;:16;;;;59317:4;59305:16;;;59111: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://a07ec068cfe82666ea6686f72accf698858cf6f7079a4522c940db620bea2263
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.