Latest 25 from a total of 1,078 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Remove_liquidity | 15155513 | 1331 days ago | IN | 0 ETH | 0.00444376 | ||||
| Remove_liquidity | 15155490 | 1331 days ago | IN | 0 ETH | 0.00628432 | ||||
| Remove_liquidity | 12223420 | 1792 days ago | IN | 0 ETH | 0.03295351 | ||||
| Remove_liquidity | 11970728 | 1831 days ago | IN | 0 ETH | 0.02911207 | ||||
| Remove_liquidity | 11707655 | 1871 days ago | IN | 0 ETH | 0.02480839 | ||||
| Remove_liquidity | 11701271 | 1872 days ago | IN | 0 ETH | 0.01518137 | ||||
| Remove_liquidity | 11615705 | 1885 days ago | IN | 0 ETH | 0.04515042 | ||||
| Remove_liquidity | 11557395 | 1894 days ago | IN | 0 ETH | 0.02060329 | ||||
| Remove_liquidity | 11556135 | 1895 days ago | IN | 0 ETH | 0.03433254 | ||||
| Remove_liquidity | 11544355 | 1896 days ago | IN | 0 ETH | 0.03080998 | ||||
| Remove_liquidity | 11533478 | 1898 days ago | IN | 0 ETH | 0.01574386 | ||||
| Remove_liquidity | 11527302 | 1899 days ago | IN | 0 ETH | 0.01234083 | ||||
| Remove_liquidity | 11504080 | 1903 days ago | IN | 0 ETH | 0.00307502 | ||||
| Remove_liquidity | 11451287 | 1911 days ago | IN | 0 ETH | 0.0284696 | ||||
| Remove_liquidity | 11447440 | 1911 days ago | IN | 0 ETH | 0.0167898 | ||||
| Remove_liquidity | 11447391 | 1911 days ago | IN | 0 ETH | 0.02510838 | ||||
| Remove_liquidity | 11446393 | 1911 days ago | IN | 0 ETH | 0.02918258 | ||||
| Remove_liquidity | 11413746 | 1916 days ago | IN | 0 ETH | 0.0424663 | ||||
| Remove_liquidity | 11407002 | 1917 days ago | IN | 0 ETH | 0.01213779 | ||||
| Remove_liquidity | 11400222 | 1919 days ago | IN | 0 ETH | 0.00913056 | ||||
| Remove_liquidity | 11388981 | 1920 days ago | IN | 0 ETH | 0.02464684 | ||||
| Remove_liquidity | 11383693 | 1921 days ago | IN | 0 ETH | 0.02306315 | ||||
| Remove_liquidity | 11378892 | 1922 days ago | IN | 0 ETH | 0.00216842 | ||||
| Remove_liquidity | 11378721 | 1922 days ago | IN | 0 ETH | 0.01033789 | ||||
| Remove_liquidity | 11378072 | 1922 days ago | IN | 0 ETH | 0.04176385 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SaffronPool
Compiler Version
v0.7.4+commit.3f05b770
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2020-10-31
*/
// File: contracts/interfaces/ISaffronBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.1;
interface ISaffronBase {
enum Tranche {S, AA, A, SAA, SA}
enum LPTokenType {dsec, principal}
// Store values (balances, dsec, vdsec) with TrancheUint256
struct TrancheUint256 {
uint256 S;
uint256 AA;
uint256 A;
uint256 SAA;
uint256 SA;
}
}
// File: contracts/interfaces/ISaffronStrategy.sol
pragma solidity ^0.7.1;
interface ISaffronStrategy {
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 hourly_strategy(address adapter_address) external;
function get_governance() external view returns(address);
function get_base_asset_address() external view returns(address);
function get_strategy_address() external view returns(address);
function delete_adapters() 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
address public team_address; // Team SFI address
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
bool public _shutdown = false; // v0 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: only one adapter
ISaffronAdapter[] private adapters; // v1: list of adapters
mapping(address=>uint256) private adapter_index; // v1: adapter contract address lookup for array indexes
/**** STRATEGY ****/
ISaffronStrategy private strategy;
/**** EPOCHS ****/
struct epoch_params {
uint256 start_date; // Time when the activity cycle begins (set to blocktime at contract deployment)
uint256 duration; // Duration of epoch
}
epoch_params public epoch_cycle = epoch_params({
start_date: 1604239200, // 11/01/2020 @ 2:00pm (UTC)
duration: 2 weeks // 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[5][] public tranche_total_dsec; // Total dsec (tokens + vdsec)
uint256[5][] public tranche_total_principal; // Total outstanding principal tokens
uint256[3][] public tranche_total_vdsec_AA; // Total AA vdsec
uint256[3][] public tranche_total_vdsec_A; // Total A vdsec
uint256[5][] public tranche_interest_earned; // Interest earned (calculated at wind_down_epoch)
uint256[5][] 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: 10,
AA: 80,
A: 10,
SAA: 0,
SA: 0
});
/**** TRANCHE BALANCES ****/
// (v0: S, AA, and A only)
// (v1: SAA and SA added)
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 V1 DSEC TOKENS ****/
// If we just have a token address then we can look up epoch and tranche balance tokens using a mapping(address=>SaffronV1dsecInfo)
struct SaffronV1TokenInfo {
bool exists;
uint256 epoch;
Tranche tranche;
LPTokenType token_type;
}
mapping(address=>SaffronV1TokenInfo) private saffron_v1_token_info;
constructor(address _strategy, address _base_asset, address _SFI_address, address _team_address) {
governance = msg.sender;
base_asset_address = _base_asset;
strategy = ISaffronStrategy(_strategy);
SFI_address = _SFI_address;
tranche_A_multiplier = 3;
team_address = _team_address;
}
function new_epoch(uint256 epoch, address[] memory saffron_v1_dsec_token_addresses, address[] memory saffron_v1_principal_token_addresses) public {
require(tranche_total_principal.length == epoch, "improper new epoch");
epoch_principal.push(0);
tranche_total_dsec.push([0,0,0,0,0]);
tranche_total_principal.push([0,0,0,0,0]);
tranche_total_vdsec_AA.push([0,0,0]);
tranche_total_vdsec_A.push([0,0,0]);
tranche_interest_earned.push([0,0,0,0,0]);
tranche_SFI_earned.push([0,0,0,0,0]);
dsec_token_addresses.push([ // Address for each dsec token
saffron_v1_dsec_token_addresses[uint256(Tranche.S)],
saffron_v1_dsec_token_addresses[uint256(Tranche.AA)],
saffron_v1_dsec_token_addresses[uint256(Tranche.A)]
]);
principal_token_addresses.push([ // Address for each principal token
saffron_v1_principal_token_addresses[uint256(Tranche.S)],
saffron_v1_principal_token_addresses[uint256(Tranche.AA)],
saffron_v1_principal_token_addresses[uint256(Tranche.A)]
]);
// Token info for looking up epoch and tranche of dsec tokens by token contract address
saffron_v1_token_info[saffron_v1_dsec_token_addresses[uint256(Tranche.S)]] = SaffronV1TokenInfo({
exists: true,
epoch: epoch,
tranche: Tranche.S,
token_type: LPTokenType.dsec
});
saffron_v1_token_info[saffron_v1_dsec_token_addresses[uint256(Tranche.AA)]] = SaffronV1TokenInfo({
exists: true,
epoch: epoch,
tranche: Tranche.AA,
token_type: LPTokenType.dsec
});
saffron_v1_token_info[saffron_v1_dsec_token_addresses[uint256(Tranche.A)]] = SaffronV1TokenInfo({
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_v1_token_info[saffron_v1_principal_token_addresses[uint256(Tranche.S)]] = SaffronV1TokenInfo({
exists: true,
epoch: epoch,
tranche: Tranche.S,
token_type: LPTokenType.principal
});
saffron_v1_token_info[saffron_v1_principal_token_addresses[uint256(Tranche.AA)]] = SaffronV1TokenInfo({
exists: true,
epoch: epoch,
tranche: Tranche.AA,
token_type: LPTokenType.principal
});
saffron_v1_token_info[saffron_v1_principal_token_addresses[uint256(Tranche.A)]] = SaffronV1TokenInfo({
exists: true,
epoch: epoch,
tranche: Tranche.A,
token_type: LPTokenType.principal
});
}
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 S only"); // v0: can't add to any tranche other than the S tranche
uint256 epoch = get_current_epoch();
require(amount != 0, "can't add 0");
//require(epoch_wound_down[epoch-1], "previous epoch must be wound down"); // v0: no epoch -1
require(epoch == 0, "v0: must be epoch 0 only"); // v0: can't add liquidity after epoch 0
// Calculate the dsec for this amount of DAI
// Tranche S dsec owners own proportional vdsec awarded to the S tranche when base assets in S are moved to the A or AA tranches
// Tranche S earns SFI rewards for A and AA based on vdsec as well
uint256 dsec = amount.mul(get_seconds_until_epoch_end(epoch));
pool_principal = pool_principal.add(amount); // Add DAI to principal totals
epoch_principal[epoch] = epoch_principal[epoch].add(amount); // Add DAI total balance for epoch
if (tranche == Tranche.S) eternal_unutilized_balances.S = eternal_unutilized_balances.S.add(amount); // Add to eternal balance of S tranche
// Update 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(amount);
// Transfer DAI from LP to pool
IERC20(base_asset_address).safeTransferFrom(msg.sender, address(this), amount);
// Mint Saffron V1 epoch 0 S dsec tokens and transfer them to sender
SaffronLPBalanceToken(dsec_token_addresses[epoch][uint256(tranche)]).mint(msg.sender, dsec);
// Mint Saffron V1 epoch 0 S principal tokens and transfer them to sender
SaffronLPBalanceToken(principal_token_addresses[epoch][uint256(tranche)]).mint(msg.sender, amount);
emit DsecGeneration(get_seconds_until_epoch_end(epoch), amount, 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], eternal_unutilized_balances.S, 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);
event WindDownEpochInterest(uint256 adapter_holdings, uint256 adapter_total_principal, uint256 epoch_interest_rate, uint256 epoch_principal, uint256 epoch_interest, uint256 tranche_A_interest, uint256 tranche_AA_interest);
struct WindDownVars {
uint256 previous_epoch;
uint256 SFI_rewards;
uint256 epoch_interest;
uint256 tranche_AA_interest;
uint256 tranche_A_interest;
uint256 tranche_S_share_of_AA_interest;
uint256 tranche_S_share_of_A_interest;
uint256 tranche_S_interest;
}
function wind_down_epoch(uint256 epoch) public {
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,
SFI_rewards: 0,
epoch_interest: 0,
tranche_AA_interest: 0,
tranche_A_interest: 0,
tranche_S_share_of_AA_interest: 0,
tranche_S_share_of_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
wind_down.SFI_rewards = (30000 * 1 ether) >> epoch; // v1: add plateau for ongoing generation
TrancheUint256 memory tranche_SFI_earnings = TrancheUint256({
S: TRANCHE_SFI_MULTIPLIER.S * wind_down.SFI_rewards / 100,
AA: TRANCHE_SFI_MULTIPLIER.AA * wind_down.SFI_rewards / 100,
A: TRANCHE_SFI_MULTIPLIER.A * wind_down.SFI_rewards / 100,
SAA: 0, SA: 0
});
emit WindDownEpochSFI(wind_down.previous_epoch, tranche_SFI_earnings.S, tranche_SFI_earnings.AA, tranche_SFI_earnings.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: 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);
// Calculate tranche share of interest
wind_down.tranche_A_interest = wind_down.epoch_interest.mul(tranche_A_multiplier.mul(1 ether)/(tranche_A_multiplier + 1)) / 1 ether;
wind_down.tranche_AA_interest = wind_down.epoch_interest - wind_down.tranche_A_interest;
emit WindDownEpochInterest(adapter.get_holdings(), adapter_total_principal, (((wind_down.epoch_interest.add(epoch_principal[epoch])).mul(1 ether)).div(epoch_principal[epoch])), epoch_principal[epoch], wind_down.epoch_interest, wind_down.tranche_A_interest, wind_down.tranche_AA_interest);
// Calculate how much of AA and A interest is owned by the S tranche and subtract from AA and A
wind_down.tranche_S_share_of_AA_interest = (tranche_total_vdsec_AA[epoch][uint256(Tranche.S)].div(tranche_total_dsec[epoch][uint256(Tranche.AA)])).mul(wind_down.tranche_AA_interest);
wind_down.tranche_S_share_of_A_interest = (tranche_total_vdsec_A[epoch][uint256(Tranche.S)].div(tranche_total_dsec[epoch][uint256(Tranche.A)])).mul(wind_down.tranche_A_interest);
wind_down.tranche_S_interest = wind_down.tranche_S_share_of_AA_interest.add(wind_down.tranche_S_share_of_A_interest);
wind_down.tranche_AA_interest = wind_down.tranche_AA_interest.sub(wind_down.tranche_S_share_of_AA_interest);
wind_down.tranche_A_interest = wind_down.tranche_A_interest.sub(wind_down.tranche_S_share_of_A_interest);
// Update state for remove_liquidity
tranche_interest_earned[epoch][uint256(Tranche.S)] = wind_down.tranche_S_interest; // v0: Tranche S owns all interest
tranche_interest_earned[epoch][uint256(Tranche.AA)] = wind_down.tranche_AA_interest; // v0: Should always be 0
tranche_interest_earned[epoch][uint256(Tranche.A)] = wind_down.tranche_A_interest; // v0: Should always be 0
emit WindDownEpochState(epoch, wind_down.tranche_S_interest, wind_down.tranche_AA_interest, wind_down.tranche_A_interest, uint256(tranche_SFI_earnings.S), uint256(tranche_SFI_earnings.AA), uint256(tranche_SFI_earnings.A));
tranche_SFI_earned[epoch][uint256(Tranche.S)] = tranche_SFI_earnings.S.add(tranche_total_vdsec_AA[epoch][uint256(Tranche.S)].div(tranche_total_dsec[epoch][uint256(Tranche.AA)]).mul(tranche_SFI_earnings.AA)).add(tranche_total_vdsec_A[epoch][uint256(Tranche.S)].div(tranche_total_dsec[epoch][uint256(Tranche.A)]).mul(tranche_SFI_earnings.A));
tranche_SFI_earned[epoch][uint256(Tranche.AA)] = tranche_SFI_earnings.AA.sub(tranche_total_vdsec_AA[epoch][uint256(Tranche.S)].div(tranche_total_dsec[epoch][uint256(Tranche.AA)]).mul(tranche_SFI_earnings.AA));
tranche_SFI_earned[epoch][uint256(Tranche.A)] = tranche_SFI_earnings.A.sub(tranche_total_vdsec_A[epoch][uint256(Tranche.S)].div(tranche_total_dsec[epoch][uint256(Tranche.A)]).mul(tranche_SFI_earnings.A));
// Distribute SFI earnings to S tranche based on S tranche % share of dsec via vdsec
emit WindDownEpochState(epoch, wind_down.tranche_S_interest, wind_down.tranche_AA_interest, 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;
// Mint SFI
SFI(SFI_address).mint_SFI(address(this), wind_down.SFI_rewards);
delete wind_down;
uint256 team_sfi = (10000 * 1 ether) >> epoch; // v1: add plateau for ongoing generation
SFI(SFI_address).mint_SFI(team_address, team_sfi);
}
event RemoveLiquidityDsec(uint256 dsec_percent, uint256 interest_owned, uint256 SFI_owned);
event RemoveLiquidityPrincipal(uint256 principal);
function remove_liquidity(address v1_dsec_token_address, uint256 dsec_amount, address v1_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_owned;
uint256 dsec_percent;
// Update state for removal via dsec token
if (v1_dsec_token_address != address(0x0) && dsec_amount > 0) {
// Get info about the v1 dsec token from its address and check that it exists
SaffronV1TokenInfo memory sv1_info = saffron_v1_token_info[v1_dsec_token_address];
require(sv1_info.exists, "balance token lookup failed");
require(sv1_info.tranche == Tranche.S, "v0: tranche must be S");
// Token epoch must be a past epoch
uint256 token_epoch = sv1_info.epoch;
require(sv1_info.token_type == LPTokenType.dsec, "bad dsec address");
require(token_epoch == 0, "v0: bal token epoch must be 1");
require(epoch_wound_down[token_epoch], "can't remove from wound up epoch");
// Dsec gives user claim over a tranche's earned SFI and interest
dsec_percent = dsec_amount.mul(1 ether).div(tranche_total_dsec[token_epoch][uint256(Tranche.S)]);
interest_owned = tranche_interest_earned[token_epoch][uint256(Tranche.S)].mul(dsec_percent) / 1 ether;
SFI_owned = tranche_SFI_earned[token_epoch][uint256(Tranche.S)].mul(dsec_percent) / 1 ether;
tranche_interest_earned[token_epoch][uint256(Tranche.S)] = tranche_interest_earned[token_epoch][uint256(Tranche.S)].sub(interest_owned);
tranche_SFI_earned[token_epoch][uint256(Tranche.S)] = tranche_SFI_earned[token_epoch][uint256(Tranche.S)].sub(SFI_owned);
tranche_total_dsec[token_epoch][uint256(Tranche.S)] = tranche_total_dsec[token_epoch][uint256(Tranche.S)].sub(dsec_amount);
pool_interest = pool_interest.sub(interest_owned);
}
// Update state for removal via principal token
if (v1_principal_token_address != address(0x0) && principal_amount > 0) {
// Get info about the v1 dsec token from its address and check that it exists
SaffronV1TokenInfo memory sv1_info = saffron_v1_token_info[v1_principal_token_address];
require(sv1_info.exists, "balance token info lookup failed");
require(sv1_info.tranche == Tranche.S, "v0: tranche must be S");
// Token epoch must be a past epoch
uint256 token_epoch = sv1_info.epoch;
require(sv1_info.token_type == LPTokenType.principal, "bad balance token address");
require(token_epoch == 0, "v0: 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(Tranche.S)] = tranche_total_principal[token_epoch][uint256(Tranche.S)].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);
}
// Transfer
if (v1_dsec_token_address != address(0x0) && dsec_amount > 0) {
SaffronLPBalanceToken sbt = SaffronLPBalanceToken(v1_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_owned);
emit RemoveLiquidityDsec(dsec_percent, interest_owned, SFI_owned);
}
if (v1_principal_token_address != address(0x0) && principal_amount > 0) {
SaffronLPBalanceToken sbt = SaffronLPBalanceToken(v1_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);
emit RemoveLiquidityPrincipal(principal_amount);
}
require((v1_dsec_token_address != address(0x0) && dsec_amount > 0) || (v1_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 == address(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));
// Get amount to add from S tranche to add to A and AA
uint256 new_A_amount = eternal_unutilized_balances.S / (tranche_A_multiplier+1);
// new_AA_amount is roughly 10x new_A_amount
uint256 new_AA_amount = eternal_unutilized_balances.S - new_A_amount;
// Store new balances (S tranche is wiped out into AA and A tranches)
eternal_unutilized_balances.S = 0;
eternal_utilized_balances.AA = eternal_utilized_balances.AA.add(new_AA_amount);
eternal_utilized_balances.A = eternal_utilized_balances.A.add(new_A_amount);
// Record vdsec for tranche S and new dsec for tranche AA and A
tranche_total_vdsec_AA[epoch][uint256(Tranche.S)] = tranche_total_vdsec_AA[epoch][uint256(Tranche.S)].add(get_seconds_until_epoch_end(epoch).mul(new_AA_amount)); // Total AA vdsec owned by tranche S
tranche_total_vdsec_A[epoch][uint256(Tranche.S)] = tranche_total_vdsec_A[epoch][uint256(Tranche.S)].add(get_seconds_until_epoch_end(epoch).mul(new_A_amount)); // Total A vdsec owned by tranche S
tranche_total_dsec[epoch][uint256(Tranche.AA)] = tranche_total_dsec[epoch][uint256(Tranche.AA)].add(get_seconds_until_epoch_end(epoch).mul(new_AA_amount)); // Total dsec for tranche AA
tranche_total_dsec[epoch][uint256(Tranche.A)] = tranche_total_dsec[epoch][uint256(Tranche.A)].add(get_seconds_until_epoch_end(epoch).mul(new_A_amount)); // Total dsec for tranche A
tranche_total_principal[epoch][uint256(Tranche.AA)] = tranche_total_principal[epoch][uint256(Tranche.AA)].add(new_AA_amount); // Add total principal for AA
tranche_total_principal[epoch][uint256(Tranche.A)] = tranche_total_principal[epoch][uint256(Tranche.A)].add(new_A_amount); // Add total principal for A
emit StrategicDeploy(adapter_address, amount, epoch);
// Add principal to adapter total
adapter_total_principal = adapter_total_principal.add(amount);
// 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 == address(strategy), "must be strategy");
require(block.timestamp > get_epoch_end(0) - 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;
}
/*** 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_epoch_cycle_params() external view override returns (uint256, uint256) {
return (epoch_cycle.start_date, epoch_cycle.duration);
}
function get_base_asset_address() external override view returns (address) {
return base_asset_address;
}
function get_governance() external override view returns (address) {
return governance;
}
function get_strategy_address() external override view returns (address) {
return address(strategy);
}
//***** ADAPTER FUNCTIONS *****//
// Delete adapters (v0: for v0 wind-down)
function delete_adapters() external override {
require(msg.sender == governance, "must be governance");
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, "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);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"address","name":"_base_asset","type":"address"},{"internalType":"address","name":"_SFI_address","type":"address"},{"internalType":"address","name":"_team_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":"uint256","name":"adapter_holdings","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"adapter_total_principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch_interest_rate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch_principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch_interest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_A_interest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tranche_AA_interest","type":"uint256"}],"name":"WindDownEpochInterest","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":"TRANCHE_SFI_MULTIPLIER","outputs":[{"internalType":"uint256","name":"S","type":"uint256"},{"internalType":"uint256","name":"AA","type":"uint256"},{"internalType":"uint256","name":"A","type":"uint256"},{"internalType":"uint256","name":"SAA","type":"uint256"},{"internalType":"uint256","name":"SA","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_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":[],"name":"get_governance","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"get_strategy_address","outputs":[{"internalType":"address","name":"","type":"address"}],"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_v1_dsec_token_addresses","type":"address[]"},{"internalType":"address[]","name":"saffron_v1_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":"v1_dsec_token_address","type":"address"},{"internalType":"uint256","name":"dsec_amount","type":"uint256"},{"internalType":"address","name":"v1_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_governance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"team_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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_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_vdsec_A","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tranche_total_vdsec_AA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"wind_down_epoch","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6007805460ff19169055635f9ebf6060808190526212750060a0819052600c91909155600d55610160604052600a60c0819052605060e081905261010082905260006101208190526101408190526018839055601991909155601a91909155601b819055601c5534801561007257600080fd5b50604051620049b6380380620049b68339818101604052608081101561009757600080fd5b5080516020820151604083015160609093015160008054336001600160a01b03199182161782556001805482166001600160a01b03958616179055600b80548216958516959095179094556002805485169584169590951790945560036006819055805490931691161790556148a29081906200011490396000f3fe608060405234801561001057600080fd5b50600436106102925760003560e01c806370d4ac4e11610160578063a72b6c30116100d8578063ebd485fc1161008c578063f04af65211610071578063f04af6521461077c578063f89e91bf14610799578063fc0e74d1146107a157610292565b8063ebd485fc14610757578063f034c18d1461077457610292565b8063c6b483ab116100bd578063c6b483ab1461072a578063df4cbfd814610732578063e653be741461074f57610292565b8063a72b6c301461071a578063bc4ce8441461072257610292565b80638f32cf0c1161012f578063947750071161011457806394775007146106a75780639b53e366146106ca578063a684b599146106fd57610292565b80638f32cf0c1461067c5780639392f6f21461068457610292565b806370d4ac4e14610626578063746c2e591461062e578063837a9bc714610651578063845187441461065957610292565b80634c1a42591161020e5780635b1caa2f116101c25780636acc25be116101a75780636acc25be146105d85780636bd6f696146105e057806370cdf4761461060357610292565b80635b1caa2f146104635780636120f0dc146104aa57610292565b806354e7ec80116101f357806354e7ec8014610430578063580f346f146104385780635aa6e6751461045b57610292565b80634c1a4259146103f557806354d0c8a01461042857610292565b80631816f314116102655780632a0ccc881161024a5780632a0ccc88146103965780632b666fcf1461039e57806348373cc6146103d957610292565b80631816f3141461036d57806322cef9d31461038e57610292565b8063070313fa146102975780630bbb0c58146102cc5780630efb8dbd146103185780630f78dac314610347575b600080fd5b6102ca600480360360208110156102ad57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166107a9565b005b6102ef600480360360408110156102e257600080fd5b5080359060200135610876565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103356004803603602081101561032e57600080fd5b50356108c1565b60408051918252519081900360200190f35b6102ca6004803603604081101561035d57600080fd5b508035906020013560ff166108ef565b610375610f97565b6040805192835260208301919091528051918290030190f35b6102ef610fa0565b6102ef610fc1565b6102ca600480360360408110156103b457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610fdd565b6103e1611210565b604080519115158252519081900360200190f35b6102ca6004803603602081101561040b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611219565b6102ef6116e2565b6102ef6116fe565b6103356004803603604081101561044e57600080fd5b508035906020013561171a565b6102ef61174f565b6102ca6004803603608081101561047957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013591604082013516906060013561176b565b6102ca600480360360608110156104c057600080fd5b813591908101906040810160208201356401000000008111156104e257600080fd5b8201836020820111156104f457600080fd5b8035906020019184602083028401116401000000008311171561051657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561056657600080fd5b82018360208201111561057857600080fd5b8035906020019184602083028401116401000000008311171561059a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612638945050505050565b610335613114565b610335600480360360408110156105f657600080fd5b508035906020013561311a565b6102ef6004803603604081101561061957600080fd5b508035906020013561312a565b61033561313a565b6103356004803603604081101561064457600080fd5b5080359060200135613140565b61033561316c565b6103356004803603604081101561066f57600080fd5b50803590602001356131f4565b6102ef613204565b6103356004803603604081101561069a57600080fd5b5080359060200135613220565b610335600480360360408110156106bd57600080fd5b5080359060200135613230565b6106d2613240565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6103e16004803603602081101561071357600080fd5b5035613252565b6102ef613267565b610335613283565b610335613289565b6103356004803603602081101561074857600080fd5b503561328f565b6102ca6132bb565b6103356004803603602081101561076d57600080fd5b503561334f565b610375613370565b6102ca6004803603602081101561079257600080fd5b503561337a565b6102ef613dfe565b6102ca613e1a565b60005473ffffffffffffffffffffffffffffffffffffffff16331461082f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6010828154811061088657600080fd5b906000526020600020906003020181600381106108a257600080fd5b015473ffffffffffffffffffffffffffffffffffffffff169150829050565b600d546000906108e9906108e0906108da856001613f49565b90613fc4565b600c5490613f49565b92915050565b60075460ff161561096157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b600081600481111561096f57fe5b146109db57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7472616e6368652053206f6e6c79000000000000000000000000000000000000604482015290519081900360640190fd5b60006109e561316c565b905082610a5357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f63616e2774206164642030000000000000000000000000000000000000000000604482015290519081900360640190fd5b8015610ac057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f76303a206d7573742062652065706f63682030206f6e6c790000000000000000604482015290519081900360640190fd5b6000610ad5610ace8361328f565b8590613fc4565b600454909150610ae59085613f49565b600481905550610b1584600e8481548110610afc57fe5b9060005260206000200154613f4990919063ffffffff16565b600e8381548110610b2257fe5b6000918252602082200191909155836004811115610b3c57fe5b1415610b5357601d54610b4f9085613f49565b601d555b610b908160128481548110610b6457fe5b9060005260206000209060050201856004811115610b7e57fe5b60058110610b8857fe5b015490613f49565b60128381548110610b9d57fe5b9060005260206000209060050201846004811115610bb757fe5b60058110610bc157fe5b0181905550610bd78460138481548110610b6457fe5b60138381548110610be457fe5b9060005260206000209060050201846004811115610bfe57fe5b60058110610c0857fe5b0155600154610c2f9073ffffffffffffffffffffffffffffffffffffffff16333087614037565b60108281548110610c3c57fe5b9060005260206000209060030201836004811115610c5657fe5b60038110610c6057fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101849052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b158015610cd857600080fd5b505af1158015610cec573d6000803e3d6000fd5b5050505060118281548110610cfd57fe5b9060005260206000209060030201836004811115610d1757fe5b60038110610d2157fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101879052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b158015610d9957600080fd5b505af1158015610dad573d6000803e3d6000fd5b505050507fc7d2d1a5a726dc6005e76316c12eb5ee642296cc38c1b996651599995a480f3c610ddb8361328f565b858360108681548110610dea57fe5b9060005260206000209060030201876004811115610e0457fe5b60038110610e0e57fe5b015473ffffffffffffffffffffffffffffffffffffffff1686886004811115610e3357fe5b3360118a81548110610e4157fe5b90600052602060002090600302018b6004811115610e5b57fe5b60038110610e6557fe5b01546040805198895260208901979097528787019590955273ffffffffffffffffffffffffffffffffffffffff9384166060880152608087019290925260a0860152811660c08501521660e083015251908190036101000190a17f1d69fb63e4692a6ae9a9b249224c389569da92d8e2e96243d71fd6b3bc3055d9600454600e8481548110610ef057fe5b9060005260206000200154601d6000015460138681548110610f0e57fe5b9060005260206000209060050201876004811115610f2857fe5b60058110610f3257fe5b015460128781548110610f4157fe5b9060005260206000209060050201886004811115610f5b57fe5b60058110610f6557fe5b01546040805195865260208601949094528484019290925260608401526080830152519081900360a00190a150505050565b600c54600d5482565b600754610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461106357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff838116911614156110ed57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616e6e6f7420737765657020706f6f6c206173736574730000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051839160009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561115e57600080fd5b505afa158015611172573d6000803e3d6000fd5b505050506040513d602081101561118857600080fd5b505190506111ad73ffffffffffffffffffffffffffffffffffffffff831684836140d2565b6040805133815273ffffffffffffffffffffffffffffffffffffffff80861660208301528616818301526060810183905290517f2c4e64c7c0957a81c0076a0a3f3c7d9f0a5d6158292071c794436f829d12cfb79181900360800190a150505050565b60075460ff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff16331461129f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b60075460ff161561131157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b600061131b61316c565b6007805473ffffffffffffffffffffffffffffffffffffffff808616610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff90921691909117909155600154604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051939450859360009392909216916370a0823191602480820192602092909190829003018186803b1580156113cb57600080fd5b505afa1580156113df573d6000803e3d6000fd5b505050506040513d60208110156113f557600080fd5b5051600654601d549192506000916001909101908161141057fe5b601d80546000909155602354929091049250829003906114309082613f49565b6023556024546114409083613f49565b602455611476611453826108da8861328f565b6014878154811061146057fe5b6000918252602082206003919091020190610b88565b6014868154811061148357fe5b6000918252602082206003919091020101556114b26114a5836108da8861328f565b6015878154811061146057fe5b601586815481106114bf57fe5b6000918252602082206003919091020101556115056114e1826108da8861328f565b601287815481106114ee57fe5b600091825260209091206005909102016001610b7e565b6012868154811061151257fe5b600091825260209091206005909102016001015561155a611536836108da8861328f565b6012878154811061154357fe5b600091825260209091206005909102016002610b7e565b6012868154811061156757fe5b600091825260209091206005909102016002018190555061158f81601387815481106114ee57fe5b6013868154811061159c57fe5b60009182526020909120600590910201600101819055506115c4826013878154811061154357fe5b601386815481106115d157fe5b60009182526020909120600590910201600201556040805173ffffffffffffffffffffffffffffffffffffffff881681526020810185905280820187905290517ffc2f950130d4b652317d4d65735fe2c28b9b137f09199cc20367042dedafb6d59181900360600190a16008546116489084613f49565b60085560015461166f9073ffffffffffffffffffffffffffffffffffffffff1687856140d2565b8373ffffffffffffffffffffffffffffffffffffffff16631d2e62d9846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156116c257600080fd5b505af11580156116d6573d6000803e3d6000fd5b50505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff1690565b6012828154811061172a57600080fd5b9060005260206000209060050201816005811061174657600080fd5b01549150829050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b600083118061177a5750600081115b6117e557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63616e27742072656d6f76652030000000000000000000000000000000000000604482015290519081900360640190fd5b60075473ffffffffffffffffffffffffffffffffffffffff6101009091048116906000908190819088161580159061181d5750600087115b15611c7e5761182a614648565b73ffffffffffffffffffffffffffffffffffffffff89166000908152602760209081526040918290208251608081018452815460ff908116151582526001830154938201939093526002820154909391929184019116600481111561188b57fe5b600481111561189657fe5b81526020016002820160019054906101000a900460ff1660018111156118b857fe5b60018111156118c357fe5b905250805190915061193657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f62616c616e636520746f6b656e206c6f6f6b7570206661696c65640000000000604482015290519081900360640190fd5b60008160400151600481111561194857fe5b146119b457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f76303a207472616e636865206d75737420626520530000000000000000000000604482015290519081900360640190fd5b60208101516000826060015160018111156119cb57fe5b14611a3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6261642064736563206164647265737300000000000000000000000000000000604482015290519081900360640190fd5b8015611aa457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76303a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff16611b2157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b611b5b60128281548110611b3157fe5b600091825260208220600591909102010154611b558b670de0b6b3a7640000613fc4565b90614164565b9250670de0b6b3a7640000611b8f8460168481548110611b7757fe5b60009182526020822060059190910201015490613fc4565b81611b9657fe5b049450670de0b6b3a7640000611bb38460178481548110611b7757fe5b81611bba57fe5b049350611be68560168381548110611bce57fe5b600091825260208220600591909102010154906141a6565b60168281548110611bf357fe5b600091825260208220600591909102010181905550611c198460178381548110611bce57fe5b60178281548110611c2657fe5b600091825260208220600591909102010181905550611c4c8960128381548110611bce57fe5b60128281548110611c5957fe5b600091825260208220600591909102010155600554611c7890866141a6565b60055550505b73ffffffffffffffffffffffffffffffffffffffff861615801590611ca35750600085115b1561204057611cb0614648565b73ffffffffffffffffffffffffffffffffffffffff87166000908152602760209081526040918290208251608081018452815460ff9081161515825260018301549382019390935260028201549093919291840191166004811115611d1157fe5b6004811115611d1c57fe5b81526020016002820160019054906101000a900460ff166001811115611d3e57fe5b6001811115611d4957fe5b9052508051909150611dbc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f62616c616e636520746f6b656e20696e666f206c6f6f6b7570206661696c6564604482015290519081900360640190fd5b600081604001516004811115611dce57fe5b14611e3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f76303a207472616e636865206d75737420626520530000000000000000000000604482015290519081900360640190fd5b6020810151600182606001516001811115611e5157fe5b14611ebd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6261642062616c616e636520746f6b656e206164647265737300000000000000604482015290519081900360640190fd5b8015611f2a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76303a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff16611fa757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b611fb88760138381548110611bce57fe5b60138281548110611fc557fe5b60009182526020822060059190910201018190555061200487600e8381548110611feb57fe5b90600052602060002001546141a690919063ffffffff16565b600e828154811061201157fe5b60009182526020909120015560045461202a90886141a6565b60045560085461203a90886141a6565b60085550505b73ffffffffffffffffffffffffffffffffffffffff8816158015906120655750600087115b156122f257604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518991899173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156120da57600080fd5b505afa1580156120ee573d6000803e3d6000fd5b505050506040513d602081101561210457600080fd5b5051101561217357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b604080517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018a9052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b1580156121e757600080fd5b505af11580156121fb573d6000803e3d6000fd5b5050604080517f96728a7200000000000000000000000000000000000000000000000000000000815260048101889052336024820152905173ffffffffffffffffffffffffffffffffffffffff891693506396728a729250604480830192600092919082900301818387803b15801561227357600080fd5b505af1158015612287573d6000803e3d6000fd5b50506002546122b0925073ffffffffffffffffffffffffffffffffffffffff16905033856140d2565b604080518381526020810186905280820185905290517f45d0d3545b4cb7d20e6d592c7158c445e3acda72c55074ab88b0027aa9c2d2789181900360600190a1505b73ffffffffffffffffffffffffffffffffffffffff8616158015906123175750600085115b1561257357604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518791879173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561238c57600080fd5b505afa1580156123a0573d6000803e3d6000fd5b505050506040513d60208110156123b657600080fd5b5051101561242557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b604080517f9dc29fac00000000000000000000000000000000000000000000000000000000815233600482015260248101889052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b15801561249957600080fd5b505af11580156124ad573d6000803e3d6000fd5b5050604080517f96728a72000000000000000000000000000000000000000000000000000000008152600481018a9052336024820152905173ffffffffffffffffffffffffffffffffffffffff891693506396728a729250604480830192600092919082900301818387803b15801561252557600080fd5b505af1158015612539573d6000803e3d6000fd5b50506040805189815290517ffbcc912eee8a56d51e3708fe32ba15f4191e6f92b2ccae4f00bbb544dba49f029350908190036020019150a1505b73ffffffffffffffffffffffffffffffffffffffff8816158015906125985750600087115b806125c3575073ffffffffffffffffffffffffffffffffffffffff8616158015906125c35750600085115b61262e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6e6f20616374696f6e20706572666f726d656400000000000000000000000000604482015290519081900360640190fd5b5050505050505050565b60135483146126a857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696d70726f706572206e65772065706f63680000000000000000000000000000604482015290519081900360640190fd5b600e8054600181810190925560007fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd9091018190556040805160a0810182528281526020810183905290810182905260608101829052608081018290526012805493840181559091526127439160059081027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344401919061466f565b506040805160a08101825260008082526020820181905291810182905260608101829052608081018290526013805460018101825592526127ac9160059081027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a09001919061466f565b50604080516060810182526000808252602082018190529181018290526014805460018101825592526128079160039081027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec0191906146b2565b50604080516060810182526000808252602082018190529181018290526015805460018101825592526128629160039081027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec4750191906146b2565b506040805160a08101825260008082526020820181905291810182905260608101829052608081018290526016805460018101825592526128cb9160059081027fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b512428901919061466f565b506040805160a08101825260008082526020820181905291810182905260608101829052608081018290526017805460018101825592526129349160059081027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c1501919061466f565b506040805160608101909152601090808460008151811061295157fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460018151811061298357fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825201846002815181106129b557fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206129fc92600390810290910191906146e4565b5060408051606081019091526011908083600081518110612a1957fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682520183600181518110612a4b57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682520183600281518110612a7d57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16909152825460018101845560009384529220612ac492600390810290910191906146e4565b50604080516080810182526001815260208101859052908101600081526020016000905260276000848181518110612af857fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612b8857fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612bc957fe5b02179055505060408051608081018252600180825260208201879052909250908201908152602001600090526027600084600181518110612c0657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612c9657fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612cd757fe5b0217905550506040805160808101825260018152602081018690529150810160028152602001600090526027600084600281518110612d1257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612da257fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612de357fe5b02179055505060408051608081018252600181526020810186905291508101600081526020016001905260276000838181518110612e1d57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612ead57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612eee57fe5b02179055505060408051608081018252600180825260208201879052909250908201908152602001600190526027600083600181518110612f2b57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612fbb57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612ffc57fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160019052602760008360028151811061303757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360048111156130c757fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561310857fe5b02179055505050505050565b60065481565b6016828154811061172a57600080fd5b6011828154811061088657600080fd5b60055481565b6015828154811061315057600080fd5b9060005260206000209060030201816003811061174657600080fd5b600c5460009042116131df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6265666f72652065706f63682030000000000000000000000000000000000000604482015290519081900360640190fd5b600d54600c544203816131ee57fe5b04905090565b6017828154811061172a57600080fd5b60035473ffffffffffffffffffffffffffffffffffffffff1681565b6013828154811061172a57600080fd5b6014828154811061315057600080fd5b601854601954601a54601b54601c5485565b600f6020526000908152604090205460ff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60085481565b60045481565b60006108e9426132b56108e0600c600101546108da600188613f4990919063ffffffff16565b906141a6565b60005473ffffffffffffffffffffffffffffffffffffffff16331461334157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b61334d60096000614751565b565b600e818154811061335f57600080fd5b600091825260209091200154905081565b600c54600d549091565b6000818152600f602052604090205460ff16156133f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f65706f636820616c726561647920776f756e6420646f776e0000000000000000604482015290519081900360640190fd5b600061340261316c565b905080821061347257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e6e6f742077696e6420646f776e206675747572652065706f6368000000604482015290519081900360640190fd5b61347a614772565b506040805161010081018252600060208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018082526134e8906108c1565b42101561355657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e27742063616c6c206265666f72652065706f636820656e646564000000604482015290519081900360640190fd5b69065a4da25d3016c00000831c60208201526135706147b7565b6040518060a0016040528060648460200151601860000154028161359057fe5b0481526020016064846020015160186001015402816135ab57fe5b0481526020016064846020015160186002015402816135c657fe5b04815260200160008152602001600081525090507f02ac5b59c8ff91aed9818435a4a06bf88afedae653001d8d7086f29057eca88c82600001518260000151836020015184604001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a1600754600854604080517f1a2b383200000000000000000000000000000000000000000000000000000000815260048101929092525161010090920473ffffffffffffffffffffffffffffffffffffffff16918291631a2b38329160248083019260209291908290030181600087803b1580156136b557600080fd5b505af11580156136c9573d6000803e3d6000fd5b505050506040513d60208110156136df57600080fd5b5051604084018190526005546136f491613f49565b600555600654670de0b6b3a76400009061372b9060018101906137179084613fc4565b8161371e57fe5b6040870151919004613fc4565b8161373257fe5b0483608001818152505082608001518360400151038360600181815250507ffc57cb7b16ccefbcc01644760e4cd2af479ddb03c207322653ce01e5b7ac9cc68173ffffffffffffffffffffffffffffffffffffffff16636bab3c746040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156137b957600080fd5b505af11580156137cd573d6000803e3d6000fd5b505050506040513d60208110156137e357600080fd5b5051600854600e805461384091908a9081106137fb57fe5b9060005260206000200154611b55670de0b6b3a76400006108da600e8d8154811061382257fe5b90600052602060002001548b60400151613f4990919063ffffffff16565b600e898154811061384d57fe5b90600052602060002001548760400151886080015189606001516040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390a16138f783606001516108da601288815481106138be57fe5b6000918252602090912060059091020160010154601489815481106138df57fe5b60009182526020822060039190910201015490614164565b8360a001818152505061393983608001516108da6012888154811061391857fe5b6000918252602090912060059091020160020154601589815481106138df57fe5b60c0840181905260a084015161394e91613f49565b60e084015260a08301516060840151613966916141a6565b606084015260c0830151608084015161397e916141a6565b608084015260e0830151601680548790811061399657fe5b600091825260208220600591909102010155606083015160168054879081106139bb57fe5b6000918252602090912060059091020160010155608083015160168054879081106139e257fe5b60009182526020909120600590910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858460e00151856060015186608001518660000151876020015188604001516040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390a1613afe613ab483604001516108da60128981548110613a9357fe5b600091825260209091206005909102016002015460158a815481106138df57fe5b613af8613af085602001516108da60128b81548110613acf57fe5b600091825260209091206005909102016001015460148c815481106138df57fe5b855190613f49565b90613f49565b60178681548110613b0b57fe5b600091825260208220600591909102010181905550613b67613b5c83602001516108da60128981548110613b3b57fe5b600091825260209091206005909102016001015460148a815481106138df57fe5b6020840151906141a6565b60178681548110613b7457fe5b6000918252602090912060059091020160010181905550613bb1613ba683604001516108da60128981548110613a9357fe5b6040840151906141a6565b60178681548110613bbe57fe5b60009182526020909120600590910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858460e001518560600151866080015160178a81548110613c1357fe5b60009182526020822060059190910201015460178b81548110613c3257fe5b600091825260209091206005909102016001015460178c81548110613c5357fe5b6000918252602090912060059091020160020154604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190a16000858152600f6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556002549186015181517fc21b27c70000000000000000000000000000000000000000000000000000000081523060048201526024810191909152905173ffffffffffffffffffffffffffffffffffffffff9092169263c21b27c79260448084019382900301818387803b158015613d4e57600080fd5b505af1158015613d62573d6000803e3d6000fd5b50505050613d6e614772565b600254600354604080517fc21b27c700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015269021e19e0c9bab24000008a1c6024820181905291519497509093919092169163c21b27c791604480830192600092919082900301818387803b1580156116c257600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600b5473ffffffffffffffffffffffffffffffffffffffff163314613ea057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b62015180613eae60006108c1565b034211613f1c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f747279696e6720746f2073687574646f776e20746f6f206561726c7900000000604482015290519081900360640190fd5b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600082820183811015613fbd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082613fd3575060006108e9565b82820282848281613fe057fe5b0414613fbd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806148226021913960400191505060405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526140cc9085906141e8565b50505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261415f9084906141e8565b505050565b6000613fbd83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506142c0565b6000613fbd83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061437c565b606061424a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166143f09092919063ffffffff16565b80519091501561415f5780806020019051602081101561426957600080fd5b505161415f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614843602a913960400191505060405180910390fd5b60008183614366576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561432b578181015183820152602001614313565b50505050905090810190601f1680156143585780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161437257fe5b0495945050505050565b600081848411156143e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815283516024840152835190928392604490910191908501908083836000831561432b578181015183820152602001614313565b505050900390565b60606143ff8484600085614407565b949350505050565b606082471015614462576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806147fc6026913960400191505060405180910390fd5b61446b856145c2565b6144d657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061454057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614503565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146145a2576040519150601f19603f3d011682016040523d82523d6000602084013e6145a7565b606091505b50915091506145b78282866145c8565b979650505050505050565b3b151590565b606083156145d7575081613fbd565b8251156145e75782518084602001fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815284516024840152845185939192839260440191908501908083836000831561432b578181015183820152602001614313565b60408051608081018252600080825260208201819052909182019081526020016000905290565b82600581019282156146a2579160200282015b828111156146a2578251829060ff16905591602001919060010190614682565b506146ae9291506147e6565b5090565b82600381019282156146a257916020028201828111156146a2578251829060ff16905591602001919060010190614682565b82600381019282156146a2579160200282015b828111156146a257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906146f7565b508054600082559060005260206000209081019061476f91906147e6565b50565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b5b808211156146ae57600081556001016147e756fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212201775c375fd15edff519b314b0d6c594693b6a36516f5be7d12a2d8a85a03853d64736f6c63430007040033000000000000000000000000f601912923d5fc15ad10bfdf5bbde949363fa7030000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c000000000000000000000000866f288397fa0e8c0551f97bf4419097686bfc7b
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102925760003560e01c806370d4ac4e11610160578063a72b6c30116100d8578063ebd485fc1161008c578063f04af65211610071578063f04af6521461077c578063f89e91bf14610799578063fc0e74d1146107a157610292565b8063ebd485fc14610757578063f034c18d1461077457610292565b8063c6b483ab116100bd578063c6b483ab1461072a578063df4cbfd814610732578063e653be741461074f57610292565b8063a72b6c301461071a578063bc4ce8441461072257610292565b80638f32cf0c1161012f578063947750071161011457806394775007146106a75780639b53e366146106ca578063a684b599146106fd57610292565b80638f32cf0c1461067c5780639392f6f21461068457610292565b806370d4ac4e14610626578063746c2e591461062e578063837a9bc714610651578063845187441461065957610292565b80634c1a42591161020e5780635b1caa2f116101c25780636acc25be116101a75780636acc25be146105d85780636bd6f696146105e057806370cdf4761461060357610292565b80635b1caa2f146104635780636120f0dc146104aa57610292565b806354e7ec80116101f357806354e7ec8014610430578063580f346f146104385780635aa6e6751461045b57610292565b80634c1a4259146103f557806354d0c8a01461042857610292565b80631816f314116102655780632a0ccc881161024a5780632a0ccc88146103965780632b666fcf1461039e57806348373cc6146103d957610292565b80631816f3141461036d57806322cef9d31461038e57610292565b8063070313fa146102975780630bbb0c58146102cc5780630efb8dbd146103185780630f78dac314610347575b600080fd5b6102ca600480360360208110156102ad57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166107a9565b005b6102ef600480360360408110156102e257600080fd5b5080359060200135610876565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103356004803603602081101561032e57600080fd5b50356108c1565b60408051918252519081900360200190f35b6102ca6004803603604081101561035d57600080fd5b508035906020013560ff166108ef565b610375610f97565b6040805192835260208301919091528051918290030190f35b6102ef610fa0565b6102ef610fc1565b6102ca600480360360408110156103b457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610fdd565b6103e1611210565b604080519115158252519081900360200190f35b6102ca6004803603602081101561040b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611219565b6102ef6116e2565b6102ef6116fe565b6103356004803603604081101561044e57600080fd5b508035906020013561171a565b6102ef61174f565b6102ca6004803603608081101561047957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013591604082013516906060013561176b565b6102ca600480360360608110156104c057600080fd5b813591908101906040810160208201356401000000008111156104e257600080fd5b8201836020820111156104f457600080fd5b8035906020019184602083028401116401000000008311171561051657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561056657600080fd5b82018360208201111561057857600080fd5b8035906020019184602083028401116401000000008311171561059a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612638945050505050565b610335613114565b610335600480360360408110156105f657600080fd5b508035906020013561311a565b6102ef6004803603604081101561061957600080fd5b508035906020013561312a565b61033561313a565b6103356004803603604081101561064457600080fd5b5080359060200135613140565b61033561316c565b6103356004803603604081101561066f57600080fd5b50803590602001356131f4565b6102ef613204565b6103356004803603604081101561069a57600080fd5b5080359060200135613220565b610335600480360360408110156106bd57600080fd5b5080359060200135613230565b6106d2613240565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6103e16004803603602081101561071357600080fd5b5035613252565b6102ef613267565b610335613283565b610335613289565b6103356004803603602081101561074857600080fd5b503561328f565b6102ca6132bb565b6103356004803603602081101561076d57600080fd5b503561334f565b610375613370565b6102ca6004803603602081101561079257600080fd5b503561337a565b6102ef613dfe565b6102ca613e1a565b60005473ffffffffffffffffffffffffffffffffffffffff16331461082f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6010828154811061088657600080fd5b906000526020600020906003020181600381106108a257600080fd5b015473ffffffffffffffffffffffffffffffffffffffff169150829050565b600d546000906108e9906108e0906108da856001613f49565b90613fc4565b600c5490613f49565b92915050565b60075460ff161561096157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b600081600481111561096f57fe5b146109db57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7472616e6368652053206f6e6c79000000000000000000000000000000000000604482015290519081900360640190fd5b60006109e561316c565b905082610a5357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f63616e2774206164642030000000000000000000000000000000000000000000604482015290519081900360640190fd5b8015610ac057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f76303a206d7573742062652065706f63682030206f6e6c790000000000000000604482015290519081900360640190fd5b6000610ad5610ace8361328f565b8590613fc4565b600454909150610ae59085613f49565b600481905550610b1584600e8481548110610afc57fe5b9060005260206000200154613f4990919063ffffffff16565b600e8381548110610b2257fe5b6000918252602082200191909155836004811115610b3c57fe5b1415610b5357601d54610b4f9085613f49565b601d555b610b908160128481548110610b6457fe5b9060005260206000209060050201856004811115610b7e57fe5b60058110610b8857fe5b015490613f49565b60128381548110610b9d57fe5b9060005260206000209060050201846004811115610bb757fe5b60058110610bc157fe5b0181905550610bd78460138481548110610b6457fe5b60138381548110610be457fe5b9060005260206000209060050201846004811115610bfe57fe5b60058110610c0857fe5b0155600154610c2f9073ffffffffffffffffffffffffffffffffffffffff16333087614037565b60108281548110610c3c57fe5b9060005260206000209060030201836004811115610c5657fe5b60038110610c6057fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101849052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b158015610cd857600080fd5b505af1158015610cec573d6000803e3d6000fd5b5050505060118281548110610cfd57fe5b9060005260206000209060030201836004811115610d1757fe5b60038110610d2157fe5b0154604080517f40c10f1900000000000000000000000000000000000000000000000000000000815233600482015260248101879052905173ffffffffffffffffffffffffffffffffffffffff909216916340c10f199160448082019260009290919082900301818387803b158015610d9957600080fd5b505af1158015610dad573d6000803e3d6000fd5b505050507fc7d2d1a5a726dc6005e76316c12eb5ee642296cc38c1b996651599995a480f3c610ddb8361328f565b858360108681548110610dea57fe5b9060005260206000209060030201876004811115610e0457fe5b60038110610e0e57fe5b015473ffffffffffffffffffffffffffffffffffffffff1686886004811115610e3357fe5b3360118a81548110610e4157fe5b90600052602060002090600302018b6004811115610e5b57fe5b60038110610e6557fe5b01546040805198895260208901979097528787019590955273ffffffffffffffffffffffffffffffffffffffff9384166060880152608087019290925260a0860152811660c08501521660e083015251908190036101000190a17f1d69fb63e4692a6ae9a9b249224c389569da92d8e2e96243d71fd6b3bc3055d9600454600e8481548110610ef057fe5b9060005260206000200154601d6000015460138681548110610f0e57fe5b9060005260206000209060050201876004811115610f2857fe5b60058110610f3257fe5b015460128781548110610f4157fe5b9060005260206000209060050201886004811115610f5b57fe5b60058110610f6557fe5b01546040805195865260208601949094528484019290925260608401526080830152519081900360a00190a150505050565b600c54600d5482565b600754610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461106357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff838116911614156110ed57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616e6e6f7420737765657020706f6f6c206173736574730000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051839160009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561115e57600080fd5b505afa158015611172573d6000803e3d6000fd5b505050506040513d602081101561118857600080fd5b505190506111ad73ffffffffffffffffffffffffffffffffffffffff831684836140d2565b6040805133815273ffffffffffffffffffffffffffffffffffffffff80861660208301528616818301526060810183905290517f2c4e64c7c0957a81c0076a0a3f3c7d9f0a5d6158292071c794436f829d12cfb79181900360800190a150505050565b60075460ff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff16331461129f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b60075460ff161561131157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f706f6f6c2073687574646f776e00000000000000000000000000000000000000604482015290519081900360640190fd5b600061131b61316c565b6007805473ffffffffffffffffffffffffffffffffffffffff808616610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff90921691909117909155600154604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051939450859360009392909216916370a0823191602480820192602092909190829003018186803b1580156113cb57600080fd5b505afa1580156113df573d6000803e3d6000fd5b505050506040513d60208110156113f557600080fd5b5051600654601d549192506000916001909101908161141057fe5b601d80546000909155602354929091049250829003906114309082613f49565b6023556024546114409083613f49565b602455611476611453826108da8861328f565b6014878154811061146057fe5b6000918252602082206003919091020190610b88565b6014868154811061148357fe5b6000918252602082206003919091020101556114b26114a5836108da8861328f565b6015878154811061146057fe5b601586815481106114bf57fe5b6000918252602082206003919091020101556115056114e1826108da8861328f565b601287815481106114ee57fe5b600091825260209091206005909102016001610b7e565b6012868154811061151257fe5b600091825260209091206005909102016001015561155a611536836108da8861328f565b6012878154811061154357fe5b600091825260209091206005909102016002610b7e565b6012868154811061156757fe5b600091825260209091206005909102016002018190555061158f81601387815481106114ee57fe5b6013868154811061159c57fe5b60009182526020909120600590910201600101819055506115c4826013878154811061154357fe5b601386815481106115d157fe5b60009182526020909120600590910201600201556040805173ffffffffffffffffffffffffffffffffffffffff881681526020810185905280820187905290517ffc2f950130d4b652317d4d65735fe2c28b9b137f09199cc20367042dedafb6d59181900360600190a16008546116489084613f49565b60085560015461166f9073ffffffffffffffffffffffffffffffffffffffff1687856140d2565b8373ffffffffffffffffffffffffffffffffffffffff16631d2e62d9846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156116c257600080fd5b505af11580156116d6573d6000803e3d6000fd5b50505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b600b5473ffffffffffffffffffffffffffffffffffffffff1690565b6012828154811061172a57600080fd5b9060005260206000209060050201816005811061174657600080fd5b01549150829050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b600083118061177a5750600081115b6117e557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63616e27742072656d6f76652030000000000000000000000000000000000000604482015290519081900360640190fd5b60075473ffffffffffffffffffffffffffffffffffffffff6101009091048116906000908190819088161580159061181d5750600087115b15611c7e5761182a614648565b73ffffffffffffffffffffffffffffffffffffffff89166000908152602760209081526040918290208251608081018452815460ff908116151582526001830154938201939093526002820154909391929184019116600481111561188b57fe5b600481111561189657fe5b81526020016002820160019054906101000a900460ff1660018111156118b857fe5b60018111156118c357fe5b905250805190915061193657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f62616c616e636520746f6b656e206c6f6f6b7570206661696c65640000000000604482015290519081900360640190fd5b60008160400151600481111561194857fe5b146119b457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f76303a207472616e636865206d75737420626520530000000000000000000000604482015290519081900360640190fd5b60208101516000826060015160018111156119cb57fe5b14611a3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6261642064736563206164647265737300000000000000000000000000000000604482015290519081900360640190fd5b8015611aa457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76303a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff16611b2157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b611b5b60128281548110611b3157fe5b600091825260208220600591909102010154611b558b670de0b6b3a7640000613fc4565b90614164565b9250670de0b6b3a7640000611b8f8460168481548110611b7757fe5b60009182526020822060059190910201015490613fc4565b81611b9657fe5b049450670de0b6b3a7640000611bb38460178481548110611b7757fe5b81611bba57fe5b049350611be68560168381548110611bce57fe5b600091825260208220600591909102010154906141a6565b60168281548110611bf357fe5b600091825260208220600591909102010181905550611c198460178381548110611bce57fe5b60178281548110611c2657fe5b600091825260208220600591909102010181905550611c4c8960128381548110611bce57fe5b60128281548110611c5957fe5b600091825260208220600591909102010155600554611c7890866141a6565b60055550505b73ffffffffffffffffffffffffffffffffffffffff861615801590611ca35750600085115b1561204057611cb0614648565b73ffffffffffffffffffffffffffffffffffffffff87166000908152602760209081526040918290208251608081018452815460ff9081161515825260018301549382019390935260028201549093919291840191166004811115611d1157fe5b6004811115611d1c57fe5b81526020016002820160019054906101000a900460ff166001811115611d3e57fe5b6001811115611d4957fe5b9052508051909150611dbc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f62616c616e636520746f6b656e20696e666f206c6f6f6b7570206661696c6564604482015290519081900360640190fd5b600081604001516004811115611dce57fe5b14611e3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f76303a207472616e636865206d75737420626520530000000000000000000000604482015290519081900360640190fd5b6020810151600182606001516001811115611e5157fe5b14611ebd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6261642062616c616e636520746f6b656e206164647265737300000000000000604482015290519081900360640190fd5b8015611f2a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f76303a2062616c20746f6b656e2065706f6368206d7573742062652031000000604482015290519081900360640190fd5b6000818152600f602052604090205460ff16611fa757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e27742072656d6f76652066726f6d20776f756e642075702065706f6368604482015290519081900360640190fd5b611fb88760138381548110611bce57fe5b60138281548110611fc557fe5b60009182526020822060059190910201018190555061200487600e8381548110611feb57fe5b90600052602060002001546141a690919063ffffffff16565b600e828154811061201157fe5b60009182526020909120015560045461202a90886141a6565b60045560085461203a90886141a6565b60085550505b73ffffffffffffffffffffffffffffffffffffffff8816158015906120655750600087115b156122f257604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518991899173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156120da57600080fd5b505afa1580156120ee573d6000803e3d6000fd5b505050506040513d602081101561210457600080fd5b5051101561217357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e73756666696369656e7420647365632062616c616e636500000000000000604482015290519081900360640190fd5b604080517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018a9052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b1580156121e757600080fd5b505af11580156121fb573d6000803e3d6000fd5b5050604080517f96728a7200000000000000000000000000000000000000000000000000000000815260048101889052336024820152905173ffffffffffffffffffffffffffffffffffffffff891693506396728a729250604480830192600092919082900301818387803b15801561227357600080fd5b505af1158015612287573d6000803e3d6000fd5b50506002546122b0925073ffffffffffffffffffffffffffffffffffffffff16905033856140d2565b604080518381526020810186905280820185905290517f45d0d3545b4cb7d20e6d592c7158c445e3acda72c55074ab88b0027aa9c2d2789181900360600190a1505b73ffffffffffffffffffffffffffffffffffffffff8616158015906123175750600085115b1561257357604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518791879173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561238c57600080fd5b505afa1580156123a0573d6000803e3d6000fd5b505050506040513d60208110156123b657600080fd5b5051101561242557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e74207072696e636970616c2062616c616e63650000604482015290519081900360640190fd5b604080517f9dc29fac00000000000000000000000000000000000000000000000000000000815233600482015260248101889052905173ffffffffffffffffffffffffffffffffffffffff831691639dc29fac91604480830192600092919082900301818387803b15801561249957600080fd5b505af11580156124ad573d6000803e3d6000fd5b5050604080517f96728a72000000000000000000000000000000000000000000000000000000008152600481018a9052336024820152905173ffffffffffffffffffffffffffffffffffffffff891693506396728a729250604480830192600092919082900301818387803b15801561252557600080fd5b505af1158015612539573d6000803e3d6000fd5b50506040805189815290517ffbcc912eee8a56d51e3708fe32ba15f4191e6f92b2ccae4f00bbb544dba49f029350908190036020019150a1505b73ffffffffffffffffffffffffffffffffffffffff8816158015906125985750600087115b806125c3575073ffffffffffffffffffffffffffffffffffffffff8616158015906125c35750600085115b61262e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6e6f20616374696f6e20706572666f726d656400000000000000000000000000604482015290519081900360640190fd5b5050505050505050565b60135483146126a857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696d70726f706572206e65772065706f63680000000000000000000000000000604482015290519081900360640190fd5b600e8054600181810190925560007fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd9091018190556040805160a0810182528281526020810183905290810182905260608101829052608081018290526012805493840181559091526127439160059081027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344401919061466f565b506040805160a08101825260008082526020820181905291810182905260608101829052608081018290526013805460018101825592526127ac9160059081027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a09001919061466f565b50604080516060810182526000808252602082018190529181018290526014805460018101825592526128079160039081027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec0191906146b2565b50604080516060810182526000808252602082018190529181018290526015805460018101825592526128629160039081027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec4750191906146b2565b506040805160a08101825260008082526020820181905291810182905260608101829052608081018290526016805460018101825592526128cb9160059081027fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b512428901919061466f565b506040805160a08101825260008082526020820181905291810182905260608101829052608081018290526017805460018101825592526129349160059081027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c1501919061466f565b506040805160608101909152601090808460008151811061295157fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252018460018151811061298357fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825201846002815181106129b557fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff169091528254600181018455600093845292206129fc92600390810290910191906146e4565b5060408051606081019091526011908083600081518110612a1957fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682520183600181518110612a4b57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682520183600281518110612a7d57fe5b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16909152825460018101845560009384529220612ac492600390810290910191906146e4565b50604080516080810182526001815260208101859052908101600081526020016000905260276000848181518110612af857fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612b8857fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612bc957fe5b02179055505060408051608081018252600180825260208201879052909250908201908152602001600090526027600084600181518110612c0657fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612c9657fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612cd757fe5b0217905550506040805160808101825260018152602081018690529150810160028152602001600090526027600084600281518110612d1257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612da257fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612de357fe5b02179055505060408051608081018252600181526020810186905291508101600081526020016001905260276000838181518110612e1d57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612ead57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612eee57fe5b02179055505060408051608081018252600180825260208201879052909250908201908152602001600190526027600083600181518110612f2b57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff02191690836004811115612fbb57fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100836001811115612ffc57fe5b021790555050604080516080810182526001815260208101869052915081016002815260200160019052602760008360028151811061303757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020160006101000a81548160ff021916908360048111156130c757fe5b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561310857fe5b02179055505050505050565b60065481565b6016828154811061172a57600080fd5b6011828154811061088657600080fd5b60055481565b6015828154811061315057600080fd5b9060005260206000209060030201816003811061174657600080fd5b600c5460009042116131df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6265666f72652065706f63682030000000000000000000000000000000000000604482015290519081900360640190fd5b600d54600c544203816131ee57fe5b04905090565b6017828154811061172a57600080fd5b60035473ffffffffffffffffffffffffffffffffffffffff1681565b6013828154811061172a57600080fd5b6014828154811061315057600080fd5b601854601954601a54601b54601c5485565b600f6020526000908152604090205460ff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60085481565b60045481565b60006108e9426132b56108e0600c600101546108da600188613f4990919063ffffffff16565b906141a6565b60005473ffffffffffffffffffffffffffffffffffffffff16331461334157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d75737420626520676f7665726e616e63650000000000000000000000000000604482015290519081900360640190fd5b61334d60096000614751565b565b600e818154811061335f57600080fd5b600091825260209091200154905081565b600c54600d549091565b6000818152600f602052604090205460ff16156133f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f65706f636820616c726561647920776f756e6420646f776e0000000000000000604482015290519081900360640190fd5b600061340261316c565b905080821061347257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e6e6f742077696e6420646f776e206675747572652065706f6368000000604482015290519081900360640190fd5b61347a614772565b506040805161010081018252600060208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018082526134e8906108c1565b42101561355657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f63616e27742063616c6c206265666f72652065706f636820656e646564000000604482015290519081900360640190fd5b69065a4da25d3016c00000831c60208201526135706147b7565b6040518060a0016040528060648460200151601860000154028161359057fe5b0481526020016064846020015160186001015402816135ab57fe5b0481526020016064846020015160186002015402816135c657fe5b04815260200160008152602001600081525090507f02ac5b59c8ff91aed9818435a4a06bf88afedae653001d8d7086f29057eca88c82600001518260000151836020015184604001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a1600754600854604080517f1a2b383200000000000000000000000000000000000000000000000000000000815260048101929092525161010090920473ffffffffffffffffffffffffffffffffffffffff16918291631a2b38329160248083019260209291908290030181600087803b1580156136b557600080fd5b505af11580156136c9573d6000803e3d6000fd5b505050506040513d60208110156136df57600080fd5b5051604084018190526005546136f491613f49565b600555600654670de0b6b3a76400009061372b9060018101906137179084613fc4565b8161371e57fe5b6040870151919004613fc4565b8161373257fe5b0483608001818152505082608001518360400151038360600181815250507ffc57cb7b16ccefbcc01644760e4cd2af479ddb03c207322653ce01e5b7ac9cc68173ffffffffffffffffffffffffffffffffffffffff16636bab3c746040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156137b957600080fd5b505af11580156137cd573d6000803e3d6000fd5b505050506040513d60208110156137e357600080fd5b5051600854600e805461384091908a9081106137fb57fe5b9060005260206000200154611b55670de0b6b3a76400006108da600e8d8154811061382257fe5b90600052602060002001548b60400151613f4990919063ffffffff16565b600e898154811061384d57fe5b90600052602060002001548760400151886080015189606001516040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390a16138f783606001516108da601288815481106138be57fe5b6000918252602090912060059091020160010154601489815481106138df57fe5b60009182526020822060039190910201015490614164565b8360a001818152505061393983608001516108da6012888154811061391857fe5b6000918252602090912060059091020160020154601589815481106138df57fe5b60c0840181905260a084015161394e91613f49565b60e084015260a08301516060840151613966916141a6565b606084015260c0830151608084015161397e916141a6565b608084015260e0830151601680548790811061399657fe5b600091825260208220600591909102010155606083015160168054879081106139bb57fe5b6000918252602090912060059091020160010155608083015160168054879081106139e257fe5b60009182526020909120600590910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858460e00151856060015186608001518660000151876020015188604001516040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390a1613afe613ab483604001516108da60128981548110613a9357fe5b600091825260209091206005909102016002015460158a815481106138df57fe5b613af8613af085602001516108da60128b81548110613acf57fe5b600091825260209091206005909102016001015460148c815481106138df57fe5b855190613f49565b90613f49565b60178681548110613b0b57fe5b600091825260208220600591909102010181905550613b67613b5c83602001516108da60128981548110613b3b57fe5b600091825260209091206005909102016001015460148a815481106138df57fe5b6020840151906141a6565b60178681548110613b7457fe5b6000918252602090912060059091020160010181905550613bb1613ba683604001516108da60128981548110613a9357fe5b6040840151906141a6565b60178681548110613bbe57fe5b60009182526020909120600590910201600201819055507fc02e9d57f5d0e6c88fa2bb10be566c735854afd14dfc5c1b0ecf9c334ac6ee35858460e001518560600151866080015160178a81548110613c1357fe5b60009182526020822060059190910201015460178b81548110613c3257fe5b600091825260209091206005909102016001015460178c81548110613c5357fe5b6000918252602090912060059091020160020154604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190a16000858152600f6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556002549186015181517fc21b27c70000000000000000000000000000000000000000000000000000000081523060048201526024810191909152905173ffffffffffffffffffffffffffffffffffffffff9092169263c21b27c79260448084019382900301818387803b158015613d4e57600080fd5b505af1158015613d62573d6000803e3d6000fd5b50505050613d6e614772565b600254600354604080517fc21b27c700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015269021e19e0c9bab24000008a1c6024820181905291519497509093919092169163c21b27c791604480830192600092919082900301818387803b1580156116c257600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600b5473ffffffffffffffffffffffffffffffffffffffff163314613ea057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6d75737420626520737472617465677900000000000000000000000000000000604482015290519081900360640190fd5b62015180613eae60006108c1565b034211613f1c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f747279696e6720746f2073687574646f776e20746f6f206561726c7900000000604482015290519081900360640190fd5b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600082820183811015613fbd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082613fd3575060006108e9565b82820282848281613fe057fe5b0414613fbd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806148226021913960400191505060405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526140cc9085906141e8565b50505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261415f9084906141e8565b505050565b6000613fbd83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506142c0565b6000613fbd83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061437c565b606061424a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166143f09092919063ffffffff16565b80519091501561415f5780806020019051602081101561426957600080fd5b505161415f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614843602a913960400191505060405180910390fd5b60008183614366576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561432b578181015183820152602001614313565b50505050905090810190601f1680156143585780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161437257fe5b0495945050505050565b600081848411156143e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815283516024840152835190928392604490910191908501908083836000831561432b578181015183820152602001614313565b505050900390565b60606143ff8484600085614407565b949350505050565b606082471015614462576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806147fc6026913960400191505060405180910390fd5b61446b856145c2565b6144d657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061454057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614503565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146145a2576040519150601f19603f3d011682016040523d82523d6000602084013e6145a7565b606091505b50915091506145b78282866145c8565b979650505050505050565b3b151590565b606083156145d7575081613fbd565b8251156145e75782518084602001fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815284516024840152845185939192839260440191908501908083836000831561432b578181015183820152602001614313565b60408051608081018252600080825260208201819052909182019081526020016000905290565b82600581019282156146a2579160200282015b828111156146a2578251829060ff16905591602001919060010190614682565b506146ae9291506147e6565b5090565b82600381019282156146a257916020028201828111156146a2578251829060ff16905591602001919060010190614682565b82600381019282156146a2579160200282015b828111156146a257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906146f7565b508054600082559060005260206000209081019061476f91906147e6565b50565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b5b808211156146ae57600081556001016147e756fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212201775c375fd15edff519b314b0d6c594693b6a36516f5be7d12a2d8a85a03853d64736f6c63430007040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f601912923d5fc15ad10bfdf5bbde949363fa7030000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c000000000000000000000000866f288397fa0e8c0551f97bf4419097686bfc7b
-----Decoded View---------------
Arg [0] : _strategy (address): 0xf601912923D5Fc15AD10Bfdf5bbDE949363Fa703
Arg [1] : _base_asset (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [2] : _SFI_address (address): 0xb753428af26E81097e7fD17f40c88aaA3E04902c
Arg [3] : _team_address (address): 0x866f288397FA0e8c0551f97BF4419097686bFC7B
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f601912923d5fc15ad10bfdf5bbde949363fa703
Arg [1] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [2] : 000000000000000000000000b753428af26e81097e7fd17f40c88aaa3e04902c
Arg [3] : 000000000000000000000000866f288397fa0e8c0551f97bf4419097686bfc7b
Deployed Bytecode Sourcemap
36201:25117:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59369:144;;;;;;;;;;;;;;;;-1:-1:-1;59369:144:0;;;;:::i;:::-;;38197:40;;;;;;;;;;;;;;;;-1:-1:-1;38197:40:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;59555:154;;;;;;;;;;;;;;;;-1:-1:-1;59555:154:0;;:::i;:::-;;;;;;;;;;;;;;;;43517:2320;;;;;;;;;;;;;;;;-1:-1:-1;43517:2320:0;;;;;;;;;:::i;37665:160::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;37019:35;;;:::i;36495:26::-;;;:::i;60947:368::-;;;;;;;;;;;;;;;;-1:-1:-1;60947:368:0;;;;;;;;;;;:::i;36879:29::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;56623:2485;;;;;;;;;;;;;;;;-1:-1:-1;56623:2485:0;;;;:::i;36401:33::-;;;:::i;60533:110::-;;;:::i;38364:38::-;;;;;;;;;;;;;;;;-1:-1:-1;38364:38:0;;;;;;;:::i;36307:25::-;;;:::i;52180:4289::-;;;;;;;;;;;;;;;;-1:-1:-1;52180:4289:0;;;;;;;;;;;;;;;;;;;;;:::i;40407:2598::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40407:2598:0;;;;;;;;-1:-1:-1;40407:2598:0;;-1:-1:-1;;40407:2598:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40407:2598:0;;-1:-1:-1;40407:2598:0;;-1:-1:-1;;;;;40407:2598:0:i;36795:35::-;;;:::i;38668:43::-;;;;;;;;;;;;;;;;-1:-1:-1;38668:43:0;;;;;;;:::i;38278:45::-;;;;;;;;;;;;;;;;-1:-1:-1;38278:45:0;;;;;;;:::i;36699:28::-;;;:::i;38601:41::-;;;;;;;;;;;;;;;;-1:-1:-1;38601:41:0;;;;;;;:::i;59715:218::-;;;:::i;38769:38::-;;;;;;;;;;;;;;;;-1:-1:-1;38769:38:0;;;;;;;:::i;36548:27::-;;;:::i;38445:43::-;;;;;;;;;;;;;;;;-1:-1:-1;38445:43:0;;;;;;;:::i;38533:42::-;;;;;;;;;;;;;;;;-1:-1:-1;38533:42:0;;;;;;;:::i;39135:136::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37972:46;;;;;;;;;;;;;;;;-1:-1:-1;37972:46:0;;:::i;60311:113::-;;;:::i;37117:38::-;;;:::i;36608:29::-;;;:::i;59939:189::-;;;;;;;;;;;;;;;;-1:-1:-1;59939:189:0;;:::i;60731:135::-;;;:::i;37869:32::-;;;;;;;;;;;;;;;;-1:-1:-1;37869:32:0;;:::i;60155:150::-;;;:::i;46697:5328::-;;;;;;;;;;;;;;;;-1:-1:-1;46697:5328:0;;:::i;60430:97::-;;;:::i;59114:225::-;;;:::i;59369:144::-;59452:10;;;;59438;:24;59430:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59492:10;:15;;;;;;;;;;;;;;;59369:144::o;38197:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38197:40:0;;-1:-1:-1;38197:40:0:o;59555:154::-;59681:20;;59614:7;;59637:66;;59664:38;;:12;:5;59681:20;59664:9;:12::i;:::-;:16;;:38::i;:::-;59637:11;:22;;:26;:66::i;:::-;59630:73;59555:154;-1:-1:-1;;59555:154:0:o;43517:2320::-;43607:9;;;;43606:10;43598:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43660:9;43649:7;:20;;;;;;;;;43641:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43752:13;43768:19;:17;:19::i;:::-;43752:35;-1:-1:-1;43804:11:0;43796:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43945:10;;43937:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44290:12;44305:46;44316:34;44344:5;44316:27;:34::i;:::-;44305:6;;:10;:46::i;:::-;44377:14;;44290:61;;-1:-1:-1;44377:26:0;;44396:6;44377:18;:26::i;:::-;44360:14;:43;;;;44482:34;44509:6;44482:15;44498:5;44482:22;;;;;;;;;;;;;;;;:26;;:34;;;;:::i;:::-;44457:15;44473:5;44457:22;;;;;;;;;;;;;;;;:59;;;;44562:7;:20;;;;;;;;;44558:99;;;44616:27;:29;:41;;44650:6;44616:33;:41::i;:::-;44584:27;:73;44558:99;44772:53;44820:4;44772:18;44791:5;44772:25;;;;;;;;;;;;;;;;;;44806:7;44798:16;;;;;;;;44772:43;;;;;;;;;;:47;:53::i;:::-;44726:18;44745:5;44726:25;;;;;;;;;;;;;;;;;;44760:7;44752:16;;;;;;;;44726:43;;;;;;;;:99;;;;44883:60;44936:6;44883:23;44907:5;44883:30;;;;;;;:60;44832:23;44856:5;44832:30;;;;;;;;;;;;;;;;;;44871:7;44863:16;;;;;;;;44832:48;;;;;;;;:111;44996:18;;44989:78;;44996:18;;45033:10;45053:4;45060:6;44989:43;:78::i;:::-;45172:20;45193:5;45172:27;;;;;;;;;;;;;;;;;;45208:7;45200:16;;;;;;;;45172:45;;;;;;;;;45150:91;;;;;;45224:10;45150:91;;;;;;;;;;;;45172:45;;;;;45150:73;;:91;;;;;45172:45;;45150:91;;;;;;;;45172:45;;45150:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45351:25;45377:5;45351:32;;;;;;;;;;;;;;;;;;45392:7;45384:16;;;;;;;;45351:50;;;;;;;;;45329:98;;;;;;45408:10;45329:98;;;;;;;;;;;;45351:50;;;;;45329:78;;:98;;;;;45351:50;;45329:98;;;;;;;;45351:50;;45329:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45441:200;45456:34;45484:5;45456:27;:34::i;:::-;45492:6;45500:4;45506:20;45527:5;45506:27;;;;;;;;;;;;;;;;;;45542:7;45534:16;;;;;;;;45506:45;;;;;;;;;;;45553:5;45568:7;45560:16;;;;;;;;45578:10;45590:25;45616:5;45590:32;;;;;;;;;;;;;;;;;;45631:7;45623:16;;;;;;;;45590:50;;;;;;;;;45441:200;;;;;;;;;;;;;;;;;;;;45590:50;45441:200;;;;;;;;;;;;;;;;;;;;;;;;45590:50;45441:200;;;;;;;;;45590:50;45441:200;;;45653:178;45666:14;;45682:15;45698:5;45682:22;;;;;;;;;;;;;;;;45706:27;:29;;;45737:23;45761:5;45737:30;;;;;;;;;;;;;;;;;;45776:7;45768:16;;;;;;;;45737:48;;;;;;;;;45787:18;45806:5;45787:25;;;;;;;;;;;;;;;;;;45821:7;45813:16;;;;;;;;45787:43;;;;;;;;;45653:178;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43517:2320;;;;:::o;37665:160::-;;;;;;:::o;37019:35::-;;;;;;;;;:::o;36495:26::-;;;;;;:::o;60947:368::-;61031:10;;;;61017;:24;61009:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61089:18;;;61079:28;;;61089:18;;61079:28;;61071:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61194:28;;;;;;61216:4;61194:28;;;;;;61165:6;;61145:10;;61194:13;;;;;;:28;;;;;;;;;;;;;;:13;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61194:28:0;;-1:-1:-1;61229:27:0;:16;;;61246:3;61194:28;61229:16;:27::i;:::-;61270:39;;;61279:10;61270:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60947:368;;;;:::o;36879:29::-;;;;;;:::o;56623:2485::-;56728:8;;;;56706:10;:31;56698:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56774:9;;;;56773:10;56765:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56808:13;56824:19;:17;:19::i;:::-;56850:20;:38;;;;;;;;;;;;;;;;;;;:20;56989:18;56982:51;;;;;;57027:4;56982:51;;;;;;56808:35;;-1:-1:-1;56873:15:0;;-1:-1:-1;;56989:18:0;;;;;56982:36;;:51;;;;;;;;;;;;;;;56989:18;56982:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56982:51:0;57158:20;;57125:27;:29;56982:51;;-1:-1:-1;57102:20:0;;57179:1;57158:22;;;;;57125:56;;;;57262:27;:29;;57238:21;57390:33;;;57461:28;;57125:56;;;;;-1:-1:-1;57262:44:0;;;;57461:47;;57262:44;57461:32;:47::i;:::-;57430:28;:78;57545:27;;:45;;57577:12;57545:31;:45::i;:::-;57515:27;:75;57720:108;57774:53;57813:13;57774:34;57802:5;57774:27;:34::i;:53::-;57720:22;57743:5;57720:29;;;;;;;;;;;;;;;;;;;;;;:49;;:108;57668:22;57691:5;57668:29;;;;;;;;;;;;;;;;;;;;;:49;:160;57924:106;57977:52;58016:12;57977:34;58005:5;57977:27;:34::i;:52::-;57924:21;57946:5;57924:28;;;;;;;:106;57872:21;57894:5;57872:28;;;;;;;;;;;;;;;;;;;;;:48;:158;58126:105;58177:53;58216:13;58177:34;58205:5;58177:27;:34::i;:53::-;58126:18;58145:5;58126:25;;;;;;;;;;;;;;;;;;;;;58160:10;58152:19;;58126:105;58077:18;58096:5;58077:25;;;;;;;;;;;;;;;;;;;;;58111:10;58077:46;:154;58316:103;58366:52;58405:12;58366:34;58394:5;58366:27;:34::i;:52::-;58316:18;58335:5;58316:25;;;;;;;;;;;;;;;;;;;;;58350:9;58342:18;;58316:103;58267:18;58286:5;58267:25;;;;;;;;;;;;;;;;;;;;;58301:9;58267:45;:152;;;;58512:70;58568:13;58512:23;58536:5;58512:30;;;;;;;:70;58458:23;58482:5;58458:30;;;;;;;;;;;;;;;;;;;;;58497:10;58458:51;:124;;;;58673:68;58728:12;58673:23;58697:5;58673:30;;;;;;;:68;58619:23;58643:5;58619:30;;;;;;;;;;;;;;;;;;;;;58658:9;58619:50;:122;58786:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58907:23;;:35;;58935:6;58907:27;:35::i;:::-;58881:23;:61;59003:18;;58996:64;;59003:18;;59036:15;59053:6;58996:39;:64::i;:::-;59067:12;:27;;;59095:6;59067:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56623:2485;;;;;;:::o;36401:33::-;;;;;;:::o;60533:110::-;60628:8;;;;60533:110;:::o;38364:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38364:38:0;;-1:-1:-1;38364:38:0:o;36307:25::-;;;;;;:::o;52180:4289::-;52367:1;52353:11;:15;:39;;;;52391:1;52372:16;:20;52353:39;52345:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52465:20;;;;;;;;;;52418:28;;;;;;52627:37;;;;;;:56;;;52682:1;52668:11;:15;52627:56;52623:1552;;;52779:34;;:::i;:::-;52816:44;;;;;;;:21;:44;;;;;;;;;52779:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52816:44;;52779:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52877:15:0;;52779:81;;-1:-1:-1;52869:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52961:9;52941:8;:16;;;:29;;;;;;;;;52933:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53072:14;;;;53050:19;53103:8;:19;;;:39;;;;;;;;;53095:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53180:16;;53172:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53247:29;;;;:16;:29;;;;;;;;53239:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53412:81;53441:18;53460:11;53441:31;;;;;;;;;;;;;;;;;;;;;:51;;53412:24;:11;53428:7;53412:15;:24::i;:::-;:28;;:81::i;:::-;53397:96;;53596:7;53519:74;53580:12;53519:23;53543:11;53519:36;;;;;;;;;;;;;;;;;;;;;:56;;;:60;:74::i;:::-;:84;;;;;;53502:101;;53696:7;53624:69;53680:12;53624:18;53643:11;53624:31;;;;;;;:69;:79;;;;;;53612:91;;53773:76;53834:14;53773:23;53797:11;53773:36;;;;;;;;;;;;;;;;;;;;;:56;;;:60;:76::i;:::-;53714:23;53738:11;53714:36;;;;;;;;;;;;;;;;;;;;;:56;:135;;;;53912:66;53968:9;53912:18;53931:11;53912:31;;;;;;;:66;53858:18;53877:11;53858:31;;;;;;;;;;;;;;;;;;;;;:51;:120;;;;54041:68;54097:11;54041:18;54060:11;54041:31;;;;;;;:68;53987:18;54006:11;53987:31;;;;;;;;;;;;;;;;;;;;;:51;:122;54134:13;;:33;;54152:14;54134:17;:33::i;:::-;54118:13;:49;-1:-1:-1;;52623:1552:0;54240:42;;;;;;;:66;;;54305:1;54286:16;:20;54240:66;54236:1112;;;54402:34;;:::i;:::-;54439:49;;;;;;;:21;:49;;;;;;;;;54402:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54439:49;;54402:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54505:15:0;;54402:86;;-1:-1:-1;54497:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54594:9;54574:8;:16;;;:29;;;;;;;;;54566:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54705:14;;;;54759:21;54736:8;:19;;;:44;;;;;;;;;54728:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54827:16;;54819:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54894:29;;;;:16;:29;;;;;;;;54886:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55030:78;55091:16;55030:23;55054:11;55030:36;;;;;;;:78;54971:23;54995:11;54971:36;;;;;;;;;;;;;;;;;;;;;:56;:137;;;;55148:50;55181:16;55148:15;55164:11;55148:28;;;;;;;;;;;;;;;;:32;;:50;;;;:::i;:::-;55117:15;55133:11;55117:28;;;;;;;;;;;;;;;;;:81;55224:14;;:36;;55243:16;55224:18;:36::i;:::-;55207:14;:53;55295:23;;:45;;55323:16;55295:27;:45::i;:::-;55269:23;:71;-1:-1:-1;;54236:1112:0;55377:37;;;;;;;:56;;;55432:1;55418:11;:15;55377:56;55373:482;;;55533:25;;;;;;55547:10;55533:25;;;;;;55494:21;;55562:11;;55533:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55533:25:0;:40;;55525:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55612:33;;;;;;55621:10;55612:33;;;;;;;;;;;;:8;;;;;;:33;;;;;-1:-1:-1;;55612:33:0;;;;;;;-1:-1:-1;55612:8:0;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;55654:55:0;;;;;;;;;;;;55698:10;55654:55;;;;;;:27;;;;-1:-1:-1;55654:27:0;;-1:-1:-1;55654:55:0;;;;;-1:-1:-1;;55654:55:0;;;;;;;-1:-1:-1;55654:27:0;:55;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;55725:11:0;;55718:55;;-1:-1:-1;55725:11:0;;;-1:-1:-1;55751:10:0;55763:9;55718:32;:55::i;:::-;55787:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55373:482;;55865:42;;;;;;;:66;;;55930:1;55911:16;:20;55865:66;55861:432;;;56036:25;;;;;;56050:10;56036:25;;;;;;55992:26;;56065:16;;56036:13;;;;;;:25;;;;;;;;;;;;;;:13;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56036:25:0;:45;;56028:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56125:38;;;;;;56134:10;56125:38;;;;;;;;;;;;:8;;;;;;:38;;;;;-1:-1:-1;;56125:38:0;;;;;;;-1:-1:-1;56125:8:0;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56172:57:0;;;;;;;;;;;;56218:10;56172:57;;;;;;:27;;;;-1:-1:-1;56172:27:0;;-1:-1:-1;56172:57:0;;;;;-1:-1:-1;;56172:57:0;;;;;;;-1:-1:-1;56172:27:0;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56243:42:0;;;;;;;;;;-1:-1:-1;56243:42:0;;;;;;;-1:-1:-1;56243:42:0;55861:432;;56310:37;;;;;;;:56;;;56365:1;56351:11;:15;56310:56;56309:130;;;-1:-1:-1;56372:42:0;;;;;;;:66;;;56437:1;56418:16;:20;56372:66;56301:162;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52180:4289;;;;;;;;:::o;40407:2598::-;40568:23;:30;:39;;40560:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40639:15;:23;;;;;;;;;40660:1;40639:23;;;;;;;40669:36;;;;;;;;;;;40639:23;40669:36;;;;;;;;;;;;;;;;;;;;;;;:18;:36;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;40712:41:0;;;;;;;;-1:-1:-1;40712:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;:41;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;40760:36:0;;;;;;;;-1:-1:-1;40760:36:0;;;;;;;;;;;;;;;:22;:36;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;40803:35:0;;;;;;;;-1:-1:-1;40803:35:0;;;;;;;;;;;;;;;:21;:35;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;40845:41:0;;;;;;;;-1:-1:-1;40845:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;:41;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;40893:36:0;;;;;;;;-1:-1:-1;40893:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:18;:36;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;40938:252:0;;;;;;;;;:20;;:252;41010:31;-1:-1:-1;41010:51:0;;;;;;;;;;;;;;;;;;;40938:252;;;;;41070:31;41110:10;41070:52;;;;;;;;;;;;;;;;;;;40938:252;;;;;41131:31;41171:9;41131:51;;;;;;;;;;;;;;;;;;;40938:252;;;;;;;;;;;;-1:-1:-1;40938:252:0;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41199:272:0;;;;;;;;;:25;;:272;41276:36;-1:-1:-1;41276:56:0;;;;;;;;;;;;;;;;;;;41199:272;;;;;41341:36;41386:10;41341:57;;;;;;;;;;;;;;;;;;;41199:272;;;;;41407:36;41452:9;41407:56;;;;;;;;;;;;;;;;;;;41199:272;;;;;;;;;;;;-1:-1:-1;41199:272:0;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41650:133:0;;;;;;;;41686:4;41650:133;;;;;;;;;;;-1:-1:-1;41650:133:0;;;;41759:16;41650:133;;41573:21;:74;41595:31;41573:74;41595:51;;;;;;;;;;;;;;41573:74;;;;;;;;;;;;;;;:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41573:210:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41870:134:0;;;;;;;;41906:4;41870:134;;;;;;;;;;;-1:-1:-1;41870:134:0;;;;;;;;41980:16;41870:134;;41792:21;:75;41814:31;41854:10;41814:52;;;;;;;;;;;;;;41792:75;;;;;;;;;;;;;;;:212;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41792:212:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42090:133:0;;;;;;;;42126:4;42090:133;;;;;;;;;-1:-1:-1;42090:133:0;;42169:9;42090:133;;;;42199:16;42090:133;;42013:21;:74;42035:31;42075:9;42035:51;;;;;;;;;;;;;;42013:74;;;;;;;;;;;;;;;:210;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42013:210:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42401:138:0;;;;;;;;42437:4;42401:138;;;;;;;;;-1:-1:-1;42401:138:0;;-1:-1:-1;42401:138:0;;;;42510:21;42401:138;;42319:21;:79;42341:36;42319:79;42341:56;;;;;;;;;;;;;;42319:79;;;;;;;;;;;;;;;:220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42319:220:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42631:139:0;;;;;;;;42667:4;42631:139;;;;;;;;;;;-1:-1:-1;42631:139:0;;;;;;;;42741:21;42631:139;;42548:21;:80;42570:36;42615:10;42570:57;;;;;;;;;;;;;;42548:80;;;;;;;;;;;;;;;:222;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42548:222:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42861:138:0;;;;;;;;42897:4;42861:138;;;;;;;;;-1:-1:-1;42861:138:0;;42940:9;42861:138;;;;42970:21;42861:138;;42779:21;:79;42801:36;42846:9;42801:56;;;;;;;;;;;;;;42779:79;;;;;;;;;;;;;;;:220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42779:220:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;40407:2598:0:o;36795:35::-;;;;:::o;38668:43::-;;;;;;;;;;;;38278:45;;;;;;;;;;;;36699:28;;;;:::o;38601:41::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59715:218;59807:11;:22;59765:7;;59789:15;:40;59781:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59907:20;;:11;59881:22;59863:15;:40;59907:20;59862:65;;;;;59855:72;;59715:218;:::o;38769:38::-;;;;;;;;;;;;36548:27;;;;;;:::o;38445:43::-;;;;;;;;;;;;38533:42;;;;;;;;;;;;39135:136;;;;;;;;;;;;:::o;37972:46::-;;;;;;;;;;;;;;;:::o;60311:113::-;60400:18;;;;60311:113;:::o;37117:38::-;;;;:::o;36608:29::-;;;;:::o;59939:189::-;60012:7;60035:87;60106:15;60035:66;60062:38;60079:11;:20;;;60062:12;60072:1;60062:5;:9;;:12;;;;:::i;60035:66::-;:70;;:87::i;60731:135::-;60805:10;;;;60791;:24;60783:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60845:15;60852:8;;60845:15;:::i;:::-;60731:135::o;37869:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37869:32:0;:::o;60155:150::-;60254:11;:22;60278:20;;60155:150;;:::o;46697:5328::-;46760:23;;;;:16;:23;;;;;;;;46759:24;46751:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46819:21;46843:19;:17;:19::i;:::-;46819:43;;46885:13;46877:5;:21;46869:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46939:29;;:::i;:::-;-1:-1:-1;46971:270:0;;;;;;;;-1:-1:-1;46971:270:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47275:17;;;47248:44;;;47326:39;;:13;:39::i;:::-;47307:15;:58;;47299:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47476:15;47475:26;;47451:21;;;:50;47550:42;;:::i;:::-;47595:252;;;;;;;;47676:3;47652:9;:21;;;47624:22;:24;;;:49;:55;;;;;;47595:252;;;;47745:3;47721:9;:21;;;47693:22;:25;;;:49;:55;;;;;;47595:252;;;;47814:3;47790:9;:21;;;47762:22;:24;;;:49;:55;;;;;;47595:252;;;;47831:1;47595:252;;;;47838:1;47595:252;;;47550:297;;47861:115;47878:9;:24;;;47904:20;:22;;;47928:20;:23;;;47953:20;:22;;;47861:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48358:20;;48434:23;;48413:45;;;;;;;;;;;;;;48358:20;;;;;;;;;48413;;:45;;;;;;;;;;;;;;-1:-1:-1;48358:20:0;48413:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48413:45:0;48386:24;;;:72;;;48481:13;;:43;;:17;:43::i;:::-;48465:13;:59;48673:20;;48702:7;;48609:90;;48696:1;48673:24;;;48638:33;;48702:7;48638:24;:33::i;:::-;:60;;;;;48609:24;;;;;48638:60;;48609:28;:90::i;:::-;:100;;;;;;48577:9;:28;;:132;;;;;48775:9;:28;;;48748:9;:24;;;:55;48716:9;:29;;:87;;;;;48815:282;48837:7;:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48837:22:0;48861:23;;48961:15;:22;;48887:97;;48961:15;48977:5;;48961:22;;;;;;;;;;;;;;48888:67;48947:7;48889:52;48918:15;48934:5;48918:22;;;;;;;;;;;;;;;;48889:9;:24;;;:28;;:52;;;;:::i;48887:97::-;48987:15;49003:5;48987:22;;;;;;;;;;;;;;;;49011:9;:24;;;49037:9;:28;;;49067:9;:29;;;48815:282;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49250:138;49358:9;:29;;;49251:101;49305:18;49324:5;49305:25;;;;;;;;;;;;;;;;;;;;;49339:10;49305:46;;49251:22;49274:5;49251:29;;;;;;;;;;;;;;;;;;;;;:49;;;:53;:101::i;49250:138::-;49207:9;:40;;:181;;;;;49438:135;49544:9;:28;;;49439:99;49492:18;49511:5;49492:25;;;;;;;;;;;;;;;;;;;;;49526:9;49492:45;;49439:21;49461:5;49439:28;;;;;;;49438:135;49395:39;;;:178;;;49612:40;;;;:85;;:44;:85::i;:::-;49580:28;;;:117;49770:40;;;;49736:29;;;;:75;;:33;:75::i;:::-;49704:29;;;:107;49883:39;;;;49850:28;;;;:73;;:32;:73::i;:::-;49818:28;;;:105;50028:28;;;;49974:23;:30;;49998:5;;49974:30;;;;;;;;;;;;;;;;;;;:50;:82;50153:29;;;;50099:23;:30;;50123:5;;50099:30;;;;;;;;;;;;;;;;;;;50138:10;50099:51;:83;50269:28;;;;50215:23;:30;;50239:5;;50215:30;;;;;;;;;;;;;;;;;;;50254:9;50215:50;:82;;;;50338:216;50357:5;50364:9;:28;;;50394:9;:29;;;50425:9;:28;;;50463:20;:22;;;50496:20;:23;;;50530:20;:22;;;50338:216;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50612:291;50775:127;50879:20;:22;;;50775:99;50828:18;50847:5;50828:25;;;;;;;;;;;;;;;;;;;;;50862:9;50828:45;;50775:21;50797:5;50775:28;;;;;;;:127;50612:158;50639:130;50745:20;:23;;;50639:101;50693:18;50712:5;50693:25;;;;;;;;;;;;;;;;;;;;;50727:10;50693:46;;50639:22;50662:5;50639:29;;;;;;;:130;50612:22;;;:26;:158::i;:::-;:162;;:291::i;:::-;50563:18;50582:5;50563:25;;;;;;;;;;;;;;;;;;;;;:45;:340;;;;50959:159;50987:130;51093:20;:23;;;50987:101;51041:18;51060:5;51041:25;;;;;;;;;;;;;;;;;;;;;51075:10;51041:46;;50987:22;51010:5;50987:29;;;;;;;:130;50959:23;;;;;:27;:159::i;:::-;50910:18;50929:5;50910:25;;;;;;;;;;;;;;;;;;;;;50944:10;50910:46;:208;;;;51174:155;51201:127;51305:20;:22;;;51201:99;51254:18;51273:5;51254:25;;;;;;;51201:127;51174:22;;;;;:26;:155::i;:::-;51125:18;51144:5;51125:25;;;;;;;;;;;;;;;;;;;;;51159:9;51125:45;:204;;;;51433:285;51452:5;51459:9;:28;;;51489:9;:29;;;51520:9;:28;;;51558:18;51577:5;51558:25;;;;;;;;;;;;;;;;;;;;;:45;;51614:18;51633:5;51614:25;;;;;;;;;;;;;;;;;;;;;51648:10;51614:46;;51671:18;51690:5;51671:25;;;;;;;;;;;;;;;;;;;;;51705:9;51671:45;;51433:285;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51725:23;;;;:16;:23;;;;;;;;:30;;;;51751:4;51725:30;;;51785:11;;51822:21;;;;51781:63;;;;;51815:4;51781:63;;;;;;;;;;;;;51785:11;;;;;51781:25;;:63;;;;;;;;;;51725:23;51785:11;51781:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51851:16;;:::i;:::-;51974:11;;51996:12;;51970:49;;;;;;51974:11;51996:12;;;51970:49;;;;51896:15;51895:26;;51970:49;;;;;;;;51851:16;;-1:-1:-1;51895:26:0;;51974:11;;;;;51970:25;;:49;;;;;51876:16;;51970:49;;;;;;;51876:16;51974:11;51970:49;;;;;;;;;;60430:97;60488:7;60511:10;;;60430:97;:::o;59114:225::-;59189:8;;;;59167:10;:31;59159:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59271:6;59252:16;59266:1;59252:13;:16::i;:::-;:25;59234:15;:43;59226:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59317:9;:16;;;;59329:4;59317:16;;;59114:225::o;3271:181::-;3329:7;3361:5;;;3385:6;;;;3377:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3443:1;3271:181;-1:-1:-1;;;3271:181:0:o;4625:471::-;4683:7;4928:6;4924:47;;-1:-1:-1;4958:1:0;4951:8;;4924:47;4995:5;;;4999:1;4995;:5;:1;5019:5;;;;;:10;5011:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31258:199;31382:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31405:27;31382:68;;;31355:96;;31375:5;;31355:19;:96::i;:::-;31258:199;;;;:::o;31081:171::-;31187:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31210:23;31187:58;;;31160:86;;31180:5;;31160:19;:86::i;:::-;31081:171;;;:::o;5572:132::-;5630:7;5657:39;5661:1;5664;5657:39;;;;;;;;;;;;;;;;;:3;:39::i;3735:136::-;3793:7;3820:43;3824:1;3827;3820:43;;;;;;;;;;;;;;;;;:3;:43::i;33282:723::-;33690:23;33716:69;33744:4;33716:69;;;;;;;;;;;;;;;;;33724:5;33716:27;;;;:69;;;;;:::i;:::-;33796:17;;33690:95;;-1:-1:-1;33796:21:0;33792:208;;33926:10;33915:30;;;;;;;;;;;;;;;-1:-1:-1;33915:30:0;33907:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6200:278;6286:7;6321:12;6314:5;6306:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6345:9;6361:1;6357;:5;;;;;;;6200:278;-1:-1:-1;;;;;6200:278:0:o;4174:192::-;4260:7;4296:12;4288:6;;;;4280:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4332:5:0;;;4174:192::o;15136:195::-;15239:12;15271:52;15293:6;15301:4;15307:1;15310:12;15271:21;:52::i;:::-;15264:59;15136:195;-1:-1:-1;;;;15136:195:0:o;16188:530::-;16315:12;16373:5;16348:21;:30;;16340:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16440:18;16451:6;16440:10;:18::i;:::-;16432:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16566:12;16580:23;16607:6;:11;;16627:5;16635:4;16607:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16565:75;;;;16658:52;16676:7;16685:10;16697:12;16658:17;:52::i;:::-;16651:59;16188:530;-1:-1:-1;;;;;;;16188:530:0:o;12216:422::-;12583:20;12622:8;;;12216:422::o;18728:742::-;18843:12;18872:7;18868:595;;;-1:-1:-1;18903:10:0;18896:17;;18868:595;19017:17;;:21;19013:439;;19280:10;19274:17;19341:15;19328:10;19324:2;19320:19;19313:44;19228:148;19416:20;;;;;;;;;;;;;;;;;;;;19423:12;;19416:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;
Swarm Source
ipfs://1775c375fd15edff519b314b0d6c594693b6a36516f5be7d12a2d8a85a03853d
Loading...
Loading
Loading...
Loading
Net Worth in USD
$3,559.19
Net Worth in ETH
1.757399
Token Allocations
SFI
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $107.13 | 33.2231 | $3,559.19 |
Loading...
Loading
Loading...
Loading
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.