Token Dividend-Bearing Croblanc Token
Overview CRC20
Price
$0.00 @ 0.000000 CRO
Fully Diluted Market Cap
Total Supply:
43,555,667.940905 xCROBLANC
Holders:
92 addresses
Contract:
Decimals:
18
Balance
2,000 xCROBLANCValue
$0.00
[ Download CSV Export ]
[ Download CSV Export ]
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
CroblancDividends
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at cronoscan.com on 2022-01-07 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/math/SafeMath.sol pragma solidity >=0.6.0 <0.8.0; /** * @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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * 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); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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: @openzeppelin/contracts/token/ERC20/IERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @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: @openzeppelin/contracts/utils/Context.sol pragma solidity >=0.6.0 <0.8.0; /* * @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: @openzeppelin/contracts/token/ERC20/ERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @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; 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_) public { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 virtual returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual 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 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 virtual { _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: @openzeppelin/contracts/utils/Address.sol pragma solidity >=0.6.2 <0.8.0; /** * @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.4._ */ 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.4._ */ 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: @openzeppelin/contracts/token/ERC20/SafeERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @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: @openzeppelin/contracts/access/Ownable.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: @openzeppelin/contracts/utils/Pausable.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor () internal { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: src/contracts/interfaces/uniswap/IUniswapV2Router01.sol pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } // File: src/contracts/interfaces/uniswap/IUniswapV2Router02.sol pragma solidity >=0.6.2; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } // File: src/contracts/interfaces/IWETH.sol pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint256 amount) external; } // File: src/contracts/CroblancToken.sol pragma solidity >=0.6.0 <0.8.0; //---------------------------------------------------------------------------------------------------------------------- // _ // / \ _-' *** CroblancToken *** // _/| \-''- _ / //__-' { | \ Croblanc is just a classic and simple ERC20 Token. // / \ // / "O. |O } Hard supply cap: 100,000,000 CROBLANC // | \ ; // ', After the initial release of Croblanc, adding new minters (farms) require a 24 hours notice // \_ __\ to avoid any abuse of authority. Everyone can monitor the blockchain and see that a new // ''-_ \.// minter will be added soon. // / '-____' // / Burned tokens can be minted again unless they are burned using the burnForever() function. // _' // _-' //---------------------------------------------------------------------------------------------------------------------- contract CroblancToken is ERC20, Ownable { using SafeERC20 for IERC20; using SafeMath for uint256; struct MinterInfo { bool enabled; uint256 activationTimestamp; } uint256 public maxTotalSupply; // 100,000,000 max uint256 public minimumActivationDelay; mapping (address => MinterInfo) public minters; event NewMinterProposed(address _address, uint256 _activationTimestamp); event NewMinterAdded(address _address); event MinterRemoved(address _address); modifier onlyMinter() { require(minters[msg.sender].enabled); require(minters[msg.sender].activationTimestamp <= block.timestamp); _; } constructor (string memory _name, string memory _symbol) public ERC20(_name, _symbol) { maxTotalSupply = 100000000 * 1e18; // 1 CROBLANC will be pre-minted for the initial dividend reserve _mint(msg.sender, 1e18); } function mint(address _to, uint256 _amount) public onlyMinter returns (uint256) { require(_amount.add(totalSupply()) <= maxTotalSupply); _mint(_to, _amount); return _amount; } function safeMint(address _to, uint256 _amount) external onlyMinter returns (uint256) { if (_amount.add(totalSupply()) > maxTotalSupply) { return mint(_to, maxTotalSupply.sub(totalSupply())); } return mint(_to, _amount); } // Adding a minter must be done with a 24 hours notice in order to avoid any abuse of authority. function proposeNewMinter(address _newMinter) external onlyOwner { uint256 activationTimestamp = block.timestamp + minimumActivationDelay; minters[_newMinter].activationTimestamp = activationTimestamp; emit NewMinterProposed(_newMinter, activationTimestamp); } // Enable a minter after the 24 hours notice period has passed. function enableNewMinter(address _minter) external onlyOwner { require(minters[_minter].activationTimestamp > 0); require(minters[_minter].activationTimestamp <= block.timestamp); minters[_minter].enabled = true; emit NewMinterAdded(_minter); } // Immediately remove a minter. function removeMinter(address _minter) external onlyOwner { minters[_minter].enabled = false; minters[_minter].activationTimestamp = 0; delete minters[_minter]; emit MinterRemoved(_minter); } // Only during initial deployment. Will not work after calling postDeploymentLockMinters() function addMinter(address _minter) external onlyOwner { require(minimumActivationDelay == 0); minters[_minter].enabled = true; minters[_minter].activationTimestamp = block.timestamp; emit NewMinterAdded(_minter); } // It is possible to add minters instantly upon initial deployment to make the process easier. // But after this function is called, it will not possible to mind without waiting a 24 hours notice. function postDeploymentLockMinters() external onlyOwner { require(minimumActivationDelay == 0); minimumActivationDelay = 86400; } // With the simple burn function, the burned tokens can be minted again by our liquidity mining incentives function burn(uint256 _amount) external { _burn(msg.sender, _amount); } // The burnForever function burns but also reduce the maximum supply forever! function burnForever(uint256 _amount) external { _burn(msg.sender, _amount); maxTotalSupply = maxTotalSupply.sub(_amount); } // Admin helper for people who send tokens on the contract address, this contract address should not host any fund. function tokenRecovery(address _token) external onlyOwner { uint256 amount = IERC20(_token).balanceOf(address(this)); IERC20(_token).transfer(msg.sender, amount); } } // File: src/contracts/interfaces/croblanc/ICroblancFarm.sol pragma solidity ^0.6.0; interface ICroblancFarm { function updatePool(bool enableDividendsAutoswap) external; } // File: src/contracts/CroblancAlpha.sol pragma solidity >=0.6.0 <0.8.0; //---------------------------------------------------------------------------------------------------------------------- // _ // / \ _-' // _/| \-''- _ / //__-' { | \ *** CroblancAlpha *** // / \ // / "O. |O } The Alpha contract contains an unique reference to the treasury // | \ ; and the dividends contracts. // ', // \_ __\ It is also the master control of CROBLANC tokens emission, with // ''-_ \.// the mechanism inspired by the traditional MasterChef template. // / '-____' // / // _' // _-' //---------------------------------------------------------------------------------------------------------------------- contract CroblancAlpha is Ownable, Pausable { using SafeERC20 for IERC20; using SafeMath for uint256; // Info of each farm struct farmInfo { bool registered; bool farmingEnabled; uint256 allocationPoints; } struct AddressProposal { address newAddress; uint256 unlockTimestamp; } // Info of each mapping(address => farmInfo) public farmInfos; address[] public farms; address public treasury; address public dividends; AddressProposal public newTreasury; AddressProposal public newDividends; // Base CROBLANCs to distribute per second. Capped to 0.01 uint256 public croblancPerSecond; // Inflation control, times 100. >100: is a multiplier, <100: is a divider. Capped to 10000 (100 times 100) or 20000 during full moons uint256 public emissionMultiplier; // Performance fee charged per thousand, hard capped to 250 (25%) uint256 public performanceFeePerThousand; // Sum of allocation points of all farms uint256 public totalAllocationPoints; event NewTreasuryProposed(address indexed newAddress, uint256 unlockTime); event NewTreasuryDeployed(address indexed newAddress); event NewDividendsProposed(address indexed newAddress, uint256 unlockTime); event NewDividendsDeployed(address indexed newAddress); constructor ( address _treasury, address _dividends, uint256 _croblancPerSecond, uint256 _emissionMultiplier, uint256 _performanceFeePerThousand ) public { treasury = _treasury; dividends = _dividends; setCroblancPerSecond(_croblancPerSecond, true); setEmissionMultiplier(_emissionMultiplier, true); performanceFeePerThousand = _performanceFeePerThousand; } function getReward(address _farm, uint256 _from, uint256 _to) public view returns (uint256) { if (!farmInfos[_farm].farmingEnabled || _from == 0) { return 0; } uint256 multiplier = _to.sub(_from).mul(emissionMultiplier).div(100); uint256 globalReward = multiplier.mul(croblancPerSecond); // example with 1000 CROBLANC total for a pool with 500 allocations points over a total of 1500 // mul(1e12) and div(1e12) in order to prevent integer rounding issues // farmReward = globalReward.mul(1e12).div(totalAllocationPoints).mul(farmInfos[_farm].allocationPoints).div(1e12); // farmReward = 1000 .mul(1e12).div( 1500 ).mul( 500 ).div(1e12) // farmReward = ((1000e12 / 1500) * 500) / 1e12 // farmReward = 666666666667 * 500 / 1e12 // farmReward = 333333333333333 / 1e12 // farmReward = 333 uint256 farmReward = globalReward.mul(1e12).div(totalAllocationPoints).mul(farmInfos[_farm].allocationPoints).div(1e12); return farmReward; } function isFullMoon() public view returns (bool) { // Data until end of 2025, after that there will be no moon boost over >100x multiplier anymore. uint32[50] memory fullMoonDays = [ 1639785600, 1642377600, 1644969600, 1647561600, 1650067200, 1652572800, 1655164800, 1657670400, 1660176000, 1662768000, 1665273600, 1667865600, 1670371200, 1672963200, 1675555200, 1678147200, 1680652800, 1683244800, 1685750400, 1688342400, 1690848000, 1693353600, 1695945600, 1698451200, 1701043200, 1703548800, 1706140800, 1708732800, 1711324800, 1713830400, 1716422400, 1718928000, 1721520000, 1724025600, 1726531200, 1729123200, 1731628800, 1734220800, 1736726400, 1739318400, 1741910400, 1744416000, 1747008000, 1749600000, 1752105600, 1754697600, 1757203200, 1759708800, 1762300800, 1764806400 ]; for (uint32 i = 0; i < fullMoonDays.length ; i++) { if (block.timestamp >= fullMoonDays[i] && block.timestamp <= fullMoonDays[i] + 86400) { return true; } } return false; } function getFarmIndexByAddress(address _farm) public view returns (uint256) { for (uint256 i = 0; i < farms.length; i++) { if (farms[i] == _farm) { return i; } } revert(); } function getFarms() external view returns (address[] memory) { return farms; } function farmsLength() external view returns (uint256) { return farms.length; } function addFarm(address _farm, uint256 _allocationPoints) external onlyOwner { require(!farmInfos[_farm].registered); // Register the pool data in the mapping farmInfos[_farm].registered = true; // Also add in the global array farms.push(_farm); // Enable farming + give points enableFarming(_farm, _allocationPoints); } function removeFarm(address _farm) external onlyOwner { require(farmInfos[_farm].registered); // Gracefully delete the mapping entry if (farmInfos[_farm].farmingEnabled) { // Disable farming if still enabled disableFarming(_farm); } // Should never happen, just in case if (farmInfos[_farm].allocationPoints > 0) { // Remove allocation points amendAllocationPoints(_farm, 0); } // Null the remaining data farmInfos[_farm].registered = false; delete farmInfos[_farm]; // Also remove from farms array uint256 index = getFarmIndexByAddress(_farm); farms[index] = farms[farms.length-1]; farms.pop(); } function amendAllocationPoints(address _farm, uint256 _allocationPoints) public onlyOwner { require(farmInfos[_farm].registered); uint256 allocationPointsBefore = farmInfos[_farm].allocationPoints; if (allocationPointsBefore == _allocationPoints) { return; } farmInfos[_farm].allocationPoints = _allocationPoints; totalAllocationPoints = totalAllocationPoints.sub(allocationPointsBefore).add(_allocationPoints); } function disableFarming(address _farm) public onlyOwner { require(farmInfos[_farm].registered); require(farmInfos[_farm].farmingEnabled); // Harvest rewards one last time ICroblancFarm(farms[getFarmIndexByAddress(_farm)]).updatePool(false); // Then disable the farming amendAllocationPoints(_farm, 0); farmInfos[_farm].farmingEnabled = false; } function enableFarming(address _farm, uint256 _allocationPoints) public onlyOwner { require(farmInfos[_farm].registered); require(!farmInfos[_farm].farmingEnabled); farmInfos[_farm].farmingEnabled = true; amendAllocationPoints(_farm, _allocationPoints); } function _massUpdateFarms(uint256 _from, uint256 _to) internal { // Beware of gas exhaustion, if we are over gas limit we must disable some farms first or call two or more // transactions with a part of the range. for (uint256 i = _from; i < _to; i++) { if (farmInfos[farms[i]].farmingEnabled) { ICroblancFarm(farms[i]).updatePool(false); } } } function setCroblancPerSecond(uint256 _croblancPerSecond, bool _updateFarms) public onlyOwner { // maximum base speed: 0.031709791983764590 CROBLANC / sec // maximum multiplier: 100 // equals: 3.1709791983764590 CROBLANC / sec // = 273972.6027397260576 CROBLANC / day // = 100M CROBLANC / 1 year require(_croblancPerSecond <= 31709791983764590, "Over hard cap"); // Harvest one last time before updating the farming settings if (_updateFarms) { _massUpdateFarms(0, farms.length); } // Update the emission croblancPerSecond = _croblancPerSecond; } // Amend the treasury is delayed by 7 days to avoid any abuse of authority function proposeNewTreasury(address _newTreasuryAddress) external onlyOwner { // Save proposal newTreasury.unlockTimestamp = block.timestamp + 604800; newTreasury.newAddress = _newTreasuryAddress; // Alert everybody emit NewTreasuryProposed(_newTreasuryAddress, newTreasury.unlockTimestamp); } function deployNewTreasury() external onlyOwner { // Access control require(newTreasury.unlockTimestamp > 0); require(newTreasury.unlockTimestamp <= block.timestamp); // Update Treasury treasury = newTreasury.newAddress; // Reset proposal newTreasury.newAddress = address(0); newTreasury.unlockTimestamp = 0; // Alert everybody emit NewTreasuryDeployed(newTreasury.newAddress); } // Amend the treasury is delayed by 7 days to avoid any abuse of authority function proposeNewDividends(address _newDividendsAddress) external onlyOwner { // Save proposal newDividends.unlockTimestamp = block.timestamp + 604800; newDividends.newAddress = _newDividendsAddress; // Alert everybody emit NewDividendsProposed(_newDividendsAddress, newDividends.unlockTimestamp); } function deployNewDividends() external onlyOwner { // Access control require(newDividends.unlockTimestamp > 0); require(newDividends.unlockTimestamp <= block.timestamp); // Update Dividends dividends = newDividends.newAddress; // Reset proposal newDividends.newAddress = address(0); newDividends.unlockTimestamp = 0; // Alert everybody emit NewDividendsDeployed(newDividends.newAddress); } function setEmissionMultiplier(uint256 _emissionMultiplier, bool _updateFarms) public onlyOwner { // Maximum of x200 (during full moon) require(_emissionMultiplier <= 20000, "Too high"); if (!isFullMoon()) { // After full, maximum will is capped to x100 // Potential abuse of authority: if Owner doesn't lower the emissionMultiplier after the full moon ends, a // x200 multiplier may run longer than expected. We do not want the users to pay gas for massUpdateFarms, // so we will handle this with cron jobs and do our best to keep a full moon booster duration around 24h. require(_emissionMultiplier <= 10000, "Not full moon"); } // Supposed to be always true. Just keep the option in cause we have an out of gas and let the admin update // the pools manually if (_updateFarms) { // Harvest one last time before updating the farming settings _massUpdateFarms(0, farms.length); } // Update the multiplier emissionMultiplier = _emissionMultiplier; } function massUpdateFarmsPartly(uint256 _from, uint256 _to) external onlyOwner { _massUpdateFarms(_from, _to); } function setPerformanceFeePerThousand(uint256 _performanceFeePerThousand) public onlyOwner { // Hard cap of 25% to prevent any abuse of authority. require(_performanceFeePerThousand <= 250); performanceFeePerThousand = _performanceFeePerThousand; } } // File: src/contracts/CroblancDividends.sol pragma solidity >=0.6.0 <0.8.0; //---------------------------------------------------------------------------------------------------------------------- // _ // / \ _-' // _/| \-''- _ / //__-' { | \ *** CroblancDividends *** // / \ // / "O. |O } Revenue sharing manager for Croblanc stakers. // | \ ; This contract is a single staking pool that also acts as the LP token. // ', It also pulls CRO directly from other addresses (all farms) and calculates the proper // \_ __\ revenue sharing between all token holders. // ''-_ \.// // / '-____' There is also an optional auto-buyback of CROBLANC upon harvest // / // _' // _-' //---------------------------------------------------------------------------------------------------------------------- contract CroblancDividends is ERC20, Ownable, ReentrancyGuard { using SafeERC20 for IERC20; using SafeMath for uint256; struct AddressProposal { address newAddress; uint256 unlockTimestamp; } // Info of each user mapping(address => uint256) public wcroRewardDebt; mapping(address => uint256) public wcroAlreadyClaimedPerShare; mapping(address => bool) public blacklisted; // Tokens address constant public wcro = address(0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23); address public croblanc; address public treasury; address public routeFrom; address public routeTo; // Calculation of rewards uint256 public lastRewardTime; // Timestamp of the last CROBLANCs distribution. uint256 public accWcroPerShare; // Accumulated WCROs per share, times 1e18. uint256 public accWcroWithdrawn; uint256 public totalWcroPerShare; uint256 public totalWcroLifetime; // For CROBLANC buyback address public router = 0x145863Eb42Cf62847A6Ca784e6416C1682b1b2Ae; // VVS router AddressProposal public newRouter; // Update of router procedure bool public isBuybackEnabled = false; // Buyback can be set on/off // Events event Deposit(address indexed user, uint256 amount); event Withdraw(address indexed user, uint256 amount); event NewRouterProposed(address indexed newAddress, uint256 unlockTime); event NewRouterDeployed(address indexed newAddress); constructor ( address _croblanc, address _treasury, address _routeFrom, address _routeTo ) public ERC20("Dividend-Bearing Croblanc Token", "xCROBLANC") { croblanc = _croblanc; treasury = _treasury; routeFrom = _routeFrom; routeTo = _routeTo; } function pullDividends(address _address, uint256 _amount) external { if (totalSupply() == 0) { return; } // Pull the WCROs IERC20(wcro).transferFrom(_address, address(this), _amount); // Split for every share uint256 wcroPerShare = _amount.mul(1e18).div(totalSupply()); totalWcroPerShare = totalWcroPerShare.add(wcroPerShare); totalWcroLifetime = totalWcroLifetime.add(_amount); } // View function to see pending WCRO on frontend. function pendingWcro(address _user) public view returns (uint256) { if (isBuybackEnabled) { return totalWcroPerShare.sub(wcroAlreadyClaimedPerShare[_user]).mul(balanceOf(_user)).div(2e18); } else { return totalWcroPerShare.sub(wcroAlreadyClaimedPerShare[_user]).mul(balanceOf(_user)).div(1e18); } } // Public endpoint to harvest rewards for msg.sender function harvest() public { // Harvest for myself _harvestOnBehalfOf(msg.sender); } // Admin endpoint to force a harvest on behalf of another user function harvestOnBehalfOf(address _user) external onlyOwner { _harvestOnBehalfOf(_user); } // Harvest for a user function _harvestOnBehalfOf(address _user) internal { uint256 amount = pendingWcro(_user); // If buyback is enabled, `amount` equals to 50% of the actual available wcro, half for the user, half bought back if (!blacklisted[_user]) { IERC20(wcro).transfer(_user, amount); } else { IERC20(wcro).transfer(treasury, amount); } // Buyback if needed if (isBuybackEnabled) { _buyback(amount); } // Save history wcroAlreadyClaimedPerShare[_user] = totalWcroPerShare; } function deposit(uint256 _amount) public nonReentrant { // User already has LP tokens deposited if (balanceOf(msg.sender) > 0) { // Force a harvest first harvest(); } // User will deposit? if (_amount > 0) { // Pull his LP tokens IERC20(croblanc).safeTransferFrom(msg.sender, address(this), _amount); // Mint our own LP tokens _mint(msg.sender, _amount); } // Reset user debt so he will farm the correct amount wcroAlreadyClaimedPerShare[msg.sender] = totalWcroPerShare; emit Deposit(msg.sender, _amount); } function depositAll() public { deposit(IERC20(croblanc).balanceOf(msg.sender)); } function withdraw(uint256 _amount) public nonReentrant { require(_amount > 0); require(balanceOf(msg.sender) >= _amount); // Force a harvest harvest(); // User will withdraw? if (_amount > 0) { // Substract withdrawn amount from user shares _burn(msg.sender, _amount); // Transfer the want back to the user IERC20(croblanc).safeTransfer(msg.sender, _amount); } // Reset user debt so he will farm the correct amount wcroAlreadyClaimedPerShare[msg.sender] = totalWcroPerShare; emit Withdraw(msg.sender, _amount); } function withdrawAll() public { withdraw(balanceOf(msg.sender)); } function _buyback(uint256 _amountWcro) internal { address[] memory route = new address[](2); route[0] = routeFrom; route[1] = routeTo; IUniswapV2Router02(router).swapExactTokensForTokens(_amountWcro, 0, route, treasury, block.timestamp); } // @notice amount raises "Unused function parameter" warning. As it overrides native ERC20 code, we keep it anyway. function _beforeTokenTransfer(address from, address to, uint256 amount) internal override { // In case we mint or burn if (from == address(0) || to == address(0)) { // Nothing to do return; } // Force a harvest for both users _harvestOnBehalfOf(from); _harvestOnBehalfOf(to); // Transfer the pending balances and reset users debts wcroAlreadyClaimedPerShare[from] = totalWcroPerShare; wcroAlreadyClaimedPerShare[to] = totalWcroPerShare; } // Warning! Enable buyback will immediately divide the pending wcro for everybody by 2 function enableBuyback() external onlyOwner { isBuybackEnabled = true; _giveAllowances(); } // Warning! Enable buyback will immediately multiply the pending wcro for everybody by 2 function disableBuyback() external onlyOwner { isBuybackEnabled = false; _revokeAllowances(); } function amendRoute(address _routeFrom, address _routeTo) external onlyOwner { routeFrom = _routeFrom; routeTo = _routeTo; } function _giveAllowances() internal { IERC20(wcro).approve(router, type(uint256).max); } function _revokeAllowances() internal { IERC20(wcro).approve(router, 0); } function addToBlacklist(address _address) external onlyOwner { blacklisted[_address] = true; } function removeFromBlacklist(address _address) external onlyOwner { delete blacklisted[_address]; } // Amend the router is delayed by 7 days to avoid any abuse of authority function proposeNewRouter(address _newAddress) external onlyOwner { // Access control require(newRouter.unlockTimestamp == 0); require(_newAddress != address(0)); // Save proposal newRouter.unlockTimestamp = block.timestamp + 604800; newRouter.newAddress = _newAddress; // Alert everybody emit NewRouterProposed(_newAddress, newRouter.unlockTimestamp); } function deployNewRouter() external onlyOwner { // Access control require(newRouter.unlockTimestamp > 0); require(newRouter.unlockTimestamp <= block.timestamp); // Cancel previous allowances especially the one to the router _revokeAllowances(); // Update router router = newRouter.newAddress; // Reset proposal newRouter.newAddress = address(0); newRouter.unlockTimestamp = 0; // Set a new allowance to the new router _giveAllowances(); // Alert everybody emit NewRouterDeployed(newRouter.newAddress); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_croblanc","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_routeFrom","type":"address"},{"internalType":"address","name":"_routeTo","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"NewRouterDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"NewRouterProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"accWcroPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accWcroWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_routeFrom","type":"address"},{"internalType":"address","name":"_routeTo","type":"address"}],"name":"amendRoute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"blacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"croblanc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployNewRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableBuyback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableBuyback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"harvestOnBehalfOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isBuybackEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRewardTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newRouter","outputs":[{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"uint256","name":"unlockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingWcro","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"proposeNewRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"pullDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routeFrom","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"routeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWcroLifetime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWcroPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wcro","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wcroAlreadyClaimedPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wcroRewardDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405273145863eb42cf62847a6ca784e6416c1682b1b2ae601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601660006101000a81548160ff0219169083151502179055503480156200008157600080fd5b50604051620045c4380380620045c483398181016040526080811015620000a757600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291905050506040518060400160405280601f81526020017f4469766964656e642d42656172696e672043726f626c616e6320546f6b656e008152506040518060400160405280600981526020017f7843524f424c414e43000000000000000000000000000000000000000000000081525081600390805190602001906200015a92919062000361565b5080600490805190602001906200017392919062000361565b506012600560006101000a81548160ff021916908360ff16021790555050506000620001a46200035960201b60201c565b905080600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350600160068190555083600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505062000407565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620003a457805160ff1916838001178555620003d5565b82800160010185558215620003d5579182015b82811115620003d4578251825591602001919060010190620003b7565b5b509050620003e49190620003e8565b5090565b5b8082111562000403576000816000905550600101620003e9565b5090565b6141ad80620004176000396000f3fe608060405234801561001057600080fd5b506004361061027f5760003560e01c806370d34b1d1161015c578063a9059cbb116100ce578063dbac26e911610087578063dbac26e914610bb6578063dd62ed3e14610c10578063de5f626814610c88578063f034ac9614610c92578063f2fde38b14610c9c578063f887ea4014610ce05761027f565b8063a9059cbb14610a94578063af2dd0e614610af8578063b0558efe14610b2c578063b3913e0114610b36578063b6b55f2514610b54578063cb5136b914610b825761027f565b80638da5cb5b116101205780638da5cb5b146108ab5780638e0d71c4146108df5780639231cf7414610937578063939683041461095557806395d89b41146109ad578063a457c2d714610a305761027f565b806370d34b1d146107cf578063715018a6146108135780637167a5001461081d5780637abaa9b21461083d578063853828b6146108a15761027f565b80632e87c034116101f557806339509351116101b9578063395093511461064d57806344337ea1146106b15780634641257d146106f5578063537df3b6146106ff57806361d027b31461074357806370a08231146107775761027f565b80632e87c034146105645780632f1c91a814610582578063313ce567146105a057806338164057146105c1578063393ece15146105f55761027f565b80631e1232bd116102475780631e1232bd1461040857806320c8db141461041257806323b872dd1461043057806328d00c1f146104b457806329719549146105025780632e1a7d4d146105365761027f565b806306fdde0314610284578063095ea7b3146103075780630e31390f1461036b578063105bf2c4146103af57806318160ddd146103ea575b600080fd5b61028c610d14565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102cc5780820151818401526020810190506102b1565b50505050905090810190601f1680156102f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103536004803603604081101561031d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610db6565b60405180821515815260200191505060405180910390f35b6103ad6004803603602081101561038157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610dd4565b005b6103b7610f78565b604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b6103f2610faa565b6040518082815260200191505060405180910390f35b610410610fb4565b005b61041a611088565b6040518082815260200191505060405180910390f35b61049c6004803603606081101561044657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061108e565b60405180821515815260200191505060405180910390f35b610500600480360360408110156104ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611167565b005b61050a6112cf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105626004803603602081101561054c57600080fd5b81019080803590602001909291905050506112f5565b005b61056c6114a0565b6040518082815260200191505060405180910390f35b61058a6114a6565b6040518082815260200191505060405180910390f35b6105a86114ac565b604051808260ff16815260200191505060405180910390f35b6105c96114c3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106376004803603602081101561060b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114e9565b6040518082815260200191505060405180910390f35b6106996004803603604081101561066357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611501565b60405180821515815260200191505060405180910390f35b6106f3600480360360208110156106c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115b4565b005b6106fd6116be565b005b6107416004803603602081101561071557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116c9565b005b61074b6117ca565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107b96004803603602081101561078d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117f0565b6040518082815260200191505060405180910390f35b610811600480360360208110156107e557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611838565b005b61081b6118f3565b005b610825611a63565b60405180821515815260200191505060405180910390f35b61089f6004803603604081101561085357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a76565b005b6108a9611bab565b005b6108b3611bbe565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610921600480360360208110156108f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611be8565b6040518082815260200191505060405180910390f35b61093f611c00565b6040518082815260200191505060405180910390f35b6109976004803603602081101561096b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c06565b6040518082815260200191505060405180910390f35b6109b5611d3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156109f55780820151818401526020810190506109da565b50505050905090810190601f168015610a225780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610a7c60048036036040811015610a4657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611dde565b60405180821515815260200191505060405180910390f35b610ae060048036036040811015610aaa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611eab565b60405180821515815260200191505060405180910390f35b610b00611ec9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610b34611ee1565b005b610b3e6120e4565b6040518082815260200191505060405180910390f35b610b8060048036036020811015610b6a57600080fd5b81019080803590602001909291905050506120ea565b005b610b8a612287565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610bf860048036036020811015610bcc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122ad565b60405180821515815260200191505060405180910390f35b610c7260048036036040811015610c2657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122cd565b6040518082815260200191505060405180910390f35b610c90612354565b005b610c9a612422565b005b610cde60048036036020811015610cb257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506124f6565b005b610ce86126eb565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610dac5780601f10610d8157610100808354040283529160200191610dac565b820191906000526020600020905b815481529060010190602001808311610d8f57829003601f168201915b5050505050905090565b6000610dca610dc3612711565b8484612719565b6001905092915050565b610ddc612711565b73ffffffffffffffffffffffffffffffffffffffff16610dfa611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614610e83576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060146001015414610e9557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ecf57600080fd5b62093a80420160146001018190555080601460000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fc5e17c31e8e3a339dc52e6fece89679da494f9cc4def3ce25908abdf0ce8d6bf6014600101546040518082815260200191505060405180910390a250565b60148060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b6000600254905090565b610fbc612711565b73ffffffffffffffffffffffffffffffffffffffff16610fda611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611063576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000601660006101000a81548160ff021916908315150217905550611086612910565b565b60125481565b600061109b8484846129f6565b61115c846110a7612711565b6111578560405180606001604052806028815260200161409760289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061110d612711565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b612719565b600190509392505050565b6000611171610faa565b141561117c576112cb565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff166323b872dd8330846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506040513d602081101561124957600080fd5b8101908080519060200190929190505050506000611291611268610faa565b611283670de0b6b3a764000085612d7190919063ffffffff16565b612df790919063ffffffff16565b90506112a881601154612e8090919063ffffffff16565b6011819055506112c382601254612e8090919063ffffffff16565b601281905550505b5050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6002600654141561136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000811161138357600080fd5b8061138d336117f0565b101561139857600080fd5b6113a06116be565b6000811115611401576113b33382612f08565b6114003382600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166130cc9092919063ffffffff16565b5b601154600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364826040518082815260200191505060405180910390a2600160068190555050565b600f5481565b60105481565b6000600560009054906101000a900460ff16905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60076020528060005260406000206000915090505481565b60006115aa61150e612711565b846115a5856001600061151f612711565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e8090919063ffffffff16565b612719565b6001905092915050565b6115bc612711565b73ffffffffffffffffffffffffffffffffffffffff166115da611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611663576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6116c73361316e565b565b6116d1612711565b73ffffffffffffffffffffffffffffffffffffffff166116ef611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611778576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff021916905550565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611840612711565b73ffffffffffffffffffffffffffffffffffffffff1661185e611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146118e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6118f08161316e565b50565b6118fb612711565b73ffffffffffffffffffffffffffffffffffffffff16611919611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146119a2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b601660009054906101000a900460ff1681565b611a7e612711565b73ffffffffffffffffffffffffffffffffffffffff16611a9c611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611b25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b81600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b611bbc611bb7336117f0565b6112f5565b565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60086020528060005260406000206000915090505481565b600e5481565b6000601660009054906101000a900460ff1615611cac57611ca5671bc16d674ec80000611c97611c35856117f0565b611c89600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546011546133df90919063ffffffff16565b612d7190919063ffffffff16565b612df790919063ffffffff16565b9050611d37565b611d34670de0b6b3a7640000611d26611cc4856117f0565b611d18600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546011546133df90919063ffffffff16565b612d7190919063ffffffff16565b612df790919063ffffffff16565b90505b919050565b606060048054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dd45780601f10611da957610100808354040283529160200191611dd4565b820191906000526020600020905b815481529060010190602001808311611db757829003601f168201915b5050505050905090565b6000611ea1611deb612711565b84611e9c856040518060600160405280602581526020016141536025913960016000611e15612711565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b612719565b6001905092915050565b6000611ebf611eb8612711565b84846129f6565b6001905092915050565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2381565b611ee9612711565b73ffffffffffffffffffffffffffffffffffffffff16611f07611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611f90576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060146001015411611fa257600080fd5b426014600101541115611fb457600080fd5b611fbc612910565b601460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601460000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060146001018190555061207a613462565b601460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f12d3547bd58eba068ae6b8015435647a924bc68e1fd5aee8a8fc564010fa905b60405160405180910390a2565b60115481565b60026006541415612163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000612176336117f0565b1115612185576121846116be565b5b60008111156121e8576121dd333083600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613567909392919063ffffffff16565b6121e73382613628565b5b601154600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c826040518082815260200191505060405180910390a2600160068190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b612420600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156123e057600080fd5b505afa1580156123f4573d6000803e3d6000fd5b505050506040513d602081101561240a57600080fd5b81019080805190602001909291905050506120ea565b565b61242a612711565b73ffffffffffffffffffffffffffffffffffffffff16612448611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146124d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001601660006101000a81548160ff0219169083151502179055506124f4613462565b565b6124fe612711565b73ffffffffffffffffffffffffffffffffffffffff1661251c611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146125a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561262b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613fe26026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561279f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806141056024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612825576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806140086022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663095ea7b3601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660006040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156129b857600080fd5b505af11580156129cc573d6000803e3d6000fd5b505050506040513d60208110156129e257600080fd5b810190808051906020019092919050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612a7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806140e06025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613f9d6023913960400191505060405180910390fd5b612b0d8383836137ef565b612b788160405180606001604052806026815260200161402a602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612c0b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e8090919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290612d64576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d29578082015181840152602081019050612d0e565b50505050905090810190601f168015612d565780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600080831415612d845760009050612df1565b6000828402905082848281612d9557fe5b0414612dec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806140766021913960400191505060405180910390fd5b809150505b92915050565b6000808211612e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b818381612e7757fe5b04905092915050565b600080828401905083811015612efe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f8e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806140bf6021913960400191505060405180910390fd5b612f9a826000836137ef565b61300581604051806060016040528060228152602001613fc0602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061305c816002546133df90919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6131698363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613904565b505050565b600061317982611c06565b9050600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661329257735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561325157600080fd5b505af1158015613265573d6000803e3d6000fd5b505050506040513d602081101561327b57600080fd5b810190808051906020019092919050505050613376565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561333957600080fd5b505af115801561334d573d6000803e3d6000fd5b505050506040513d602081101561336357600080fd5b8101908080519060200190929190505050505b601660009054906101000a900460ff161561339557613394816139f3565b5b601154600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600082821115613457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663095ea7b3601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561352957600080fd5b505af115801561353d573d6000803e3d6000fd5b505050506040513d602081101561355357600080fd5b810190808051906020019092919050505050565b613622846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613904565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156136cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6136d7600083836137ef565b6136ec81600254612e8090919063ffffffff16565b600281905550613743816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e8090919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806138565750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15613860576138ff565b6138698361316e565b6138728261316e565b601154600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601154600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505050565b6060613966826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613cfc9092919063ffffffff16565b90506000815111156139ee5780806020019051602081101561398757600080fd5b81019080805190602001909291905050506139ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614129602a913960400191505060405180910390fd5b5b505050565b6060600267ffffffffffffffff81118015613a0d57600080fd5b50604051908082528060200260200182016040528015613a3c5781602001602082028036833780820191505090505b509050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600081518110613a6f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110613ad957fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166338ed173983600084600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16426040518663ffffffff1660e01b815260040180868152602001858152602001806020018473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613bf9578082015181840152602081019050613bde565b505050509050019650505050505050600060405180830381600087803b158015613c2257600080fd5b505af1158015613c36573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015613c6057600080fd5b8101908080516040519392919084640100000000821115613c8057600080fd5b83820191506020820185811115613c9657600080fd5b8251866020820283011164010000000082111715613cb357600080fd5b8083526020830192505050908051906020019060200280838360005b83811015613cea578082015181840152602081019050613ccf565b50505050905001604052505050505050565b6060613d0b8484600085613d14565b90509392505050565b606082471015613d6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806140506026913960400191505060405180910390fd5b613d7885613ebd565b613dea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613e3a5780518252602082019150602081019050602083039250613e17565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613e9c576040519150601f19603f3d011682016040523d82523d6000602084013e613ea1565b606091505b5091509150613eb1828286613ed0565b92505050949350505050565b600080823b905060008111915050919050565b60608315613ee057829050613f95565b600083511115613ef35782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f5a578082015181840152602081019050613f3f565b50505050905090810190601f168015613f875780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212205b5ca9d252d898620e9c01d9aca826d67eea112906d2e54a66d0cbac5877022164736f6c634300060c0033000000000000000000000000d3cecbe5639d05aed446da11f08d495ca6bf359f000000000000000000000000b20234c33337537111f4ab6f5ecad400134ac1430000000000000000000000005c7f8a570d578ed84e63fdfa7b1ee72deae1ae23000000000000000000000000d3cecbe5639d05aed446da11f08d495ca6bf359f
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061027f5760003560e01c806370d34b1d1161015c578063a9059cbb116100ce578063dbac26e911610087578063dbac26e914610bb6578063dd62ed3e14610c10578063de5f626814610c88578063f034ac9614610c92578063f2fde38b14610c9c578063f887ea4014610ce05761027f565b8063a9059cbb14610a94578063af2dd0e614610af8578063b0558efe14610b2c578063b3913e0114610b36578063b6b55f2514610b54578063cb5136b914610b825761027f565b80638da5cb5b116101205780638da5cb5b146108ab5780638e0d71c4146108df5780639231cf7414610937578063939683041461095557806395d89b41146109ad578063a457c2d714610a305761027f565b806370d34b1d146107cf578063715018a6146108135780637167a5001461081d5780637abaa9b21461083d578063853828b6146108a15761027f565b80632e87c034116101f557806339509351116101b9578063395093511461064d57806344337ea1146106b15780634641257d146106f5578063537df3b6146106ff57806361d027b31461074357806370a08231146107775761027f565b80632e87c034146105645780632f1c91a814610582578063313ce567146105a057806338164057146105c1578063393ece15146105f55761027f565b80631e1232bd116102475780631e1232bd1461040857806320c8db141461041257806323b872dd1461043057806328d00c1f146104b457806329719549146105025780632e1a7d4d146105365761027f565b806306fdde0314610284578063095ea7b3146103075780630e31390f1461036b578063105bf2c4146103af57806318160ddd146103ea575b600080fd5b61028c610d14565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102cc5780820151818401526020810190506102b1565b50505050905090810190601f1680156102f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103536004803603604081101561031d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610db6565b60405180821515815260200191505060405180910390f35b6103ad6004803603602081101561038157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610dd4565b005b6103b7610f78565b604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b6103f2610faa565b6040518082815260200191505060405180910390f35b610410610fb4565b005b61041a611088565b6040518082815260200191505060405180910390f35b61049c6004803603606081101561044657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061108e565b60405180821515815260200191505060405180910390f35b610500600480360360408110156104ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611167565b005b61050a6112cf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105626004803603602081101561054c57600080fd5b81019080803590602001909291905050506112f5565b005b61056c6114a0565b6040518082815260200191505060405180910390f35b61058a6114a6565b6040518082815260200191505060405180910390f35b6105a86114ac565b604051808260ff16815260200191505060405180910390f35b6105c96114c3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106376004803603602081101561060b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114e9565b6040518082815260200191505060405180910390f35b6106996004803603604081101561066357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611501565b60405180821515815260200191505060405180910390f35b6106f3600480360360208110156106c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115b4565b005b6106fd6116be565b005b6107416004803603602081101561071557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116c9565b005b61074b6117ca565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107b96004803603602081101561078d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117f0565b6040518082815260200191505060405180910390f35b610811600480360360208110156107e557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611838565b005b61081b6118f3565b005b610825611a63565b60405180821515815260200191505060405180910390f35b61089f6004803603604081101561085357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a76565b005b6108a9611bab565b005b6108b3611bbe565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610921600480360360208110156108f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611be8565b6040518082815260200191505060405180910390f35b61093f611c00565b6040518082815260200191505060405180910390f35b6109976004803603602081101561096b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c06565b6040518082815260200191505060405180910390f35b6109b5611d3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156109f55780820151818401526020810190506109da565b50505050905090810190601f168015610a225780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610a7c60048036036040811015610a4657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611dde565b60405180821515815260200191505060405180910390f35b610ae060048036036040811015610aaa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611eab565b60405180821515815260200191505060405180910390f35b610b00611ec9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610b34611ee1565b005b610b3e6120e4565b6040518082815260200191505060405180910390f35b610b8060048036036020811015610b6a57600080fd5b81019080803590602001909291905050506120ea565b005b610b8a612287565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610bf860048036036020811015610bcc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122ad565b60405180821515815260200191505060405180910390f35b610c7260048036036040811015610c2657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122cd565b6040518082815260200191505060405180910390f35b610c90612354565b005b610c9a612422565b005b610cde60048036036020811015610cb257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506124f6565b005b610ce86126eb565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610dac5780601f10610d8157610100808354040283529160200191610dac565b820191906000526020600020905b815481529060010190602001808311610d8f57829003601f168201915b5050505050905090565b6000610dca610dc3612711565b8484612719565b6001905092915050565b610ddc612711565b73ffffffffffffffffffffffffffffffffffffffff16610dfa611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614610e83576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060146001015414610e9557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ecf57600080fd5b62093a80420160146001018190555080601460000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fc5e17c31e8e3a339dc52e6fece89679da494f9cc4def3ce25908abdf0ce8d6bf6014600101546040518082815260200191505060405180910390a250565b60148060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b6000600254905090565b610fbc612711565b73ffffffffffffffffffffffffffffffffffffffff16610fda611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611063576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000601660006101000a81548160ff021916908315150217905550611086612910565b565b60125481565b600061109b8484846129f6565b61115c846110a7612711565b6111578560405180606001604052806028815260200161409760289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061110d612711565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b612719565b600190509392505050565b6000611171610faa565b141561117c576112cb565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff166323b872dd8330846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506040513d602081101561124957600080fd5b8101908080519060200190929190505050506000611291611268610faa565b611283670de0b6b3a764000085612d7190919063ffffffff16565b612df790919063ffffffff16565b90506112a881601154612e8090919063ffffffff16565b6011819055506112c382601254612e8090919063ffffffff16565b601281905550505b5050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6002600654141561136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000811161138357600080fd5b8061138d336117f0565b101561139857600080fd5b6113a06116be565b6000811115611401576113b33382612f08565b6114003382600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166130cc9092919063ffffffff16565b5b601154600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364826040518082815260200191505060405180910390a2600160068190555050565b600f5481565b60105481565b6000600560009054906101000a900460ff16905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60076020528060005260406000206000915090505481565b60006115aa61150e612711565b846115a5856001600061151f612711565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e8090919063ffffffff16565b612719565b6001905092915050565b6115bc612711565b73ffffffffffffffffffffffffffffffffffffffff166115da611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611663576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6116c73361316e565b565b6116d1612711565b73ffffffffffffffffffffffffffffffffffffffff166116ef611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611778576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff021916905550565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611840612711565b73ffffffffffffffffffffffffffffffffffffffff1661185e611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146118e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6118f08161316e565b50565b6118fb612711565b73ffffffffffffffffffffffffffffffffffffffff16611919611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146119a2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b601660009054906101000a900460ff1681565b611a7e612711565b73ffffffffffffffffffffffffffffffffffffffff16611a9c611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611b25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b81600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b611bbc611bb7336117f0565b6112f5565b565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60086020528060005260406000206000915090505481565b600e5481565b6000601660009054906101000a900460ff1615611cac57611ca5671bc16d674ec80000611c97611c35856117f0565b611c89600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546011546133df90919063ffffffff16565b612d7190919063ffffffff16565b612df790919063ffffffff16565b9050611d37565b611d34670de0b6b3a7640000611d26611cc4856117f0565b611d18600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546011546133df90919063ffffffff16565b612d7190919063ffffffff16565b612df790919063ffffffff16565b90505b919050565b606060048054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dd45780601f10611da957610100808354040283529160200191611dd4565b820191906000526020600020905b815481529060010190602001808311611db757829003601f168201915b5050505050905090565b6000611ea1611deb612711565b84611e9c856040518060600160405280602581526020016141536025913960016000611e15612711565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b612719565b6001905092915050565b6000611ebf611eb8612711565b84846129f6565b6001905092915050565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2381565b611ee9612711565b73ffffffffffffffffffffffffffffffffffffffff16611f07611bbe565b73ffffffffffffffffffffffffffffffffffffffff1614611f90576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060146001015411611fa257600080fd5b426014600101541115611fb457600080fd5b611fbc612910565b601460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601460000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060146001018190555061207a613462565b601460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f12d3547bd58eba068ae6b8015435647a924bc68e1fd5aee8a8fc564010fa905b60405160405180910390a2565b60115481565b60026006541415612163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000612176336117f0565b1115612185576121846116be565b5b60008111156121e8576121dd333083600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613567909392919063ffffffff16565b6121e73382613628565b5b601154600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c826040518082815260200191505060405180910390a2600160068190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b612420600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156123e057600080fd5b505afa1580156123f4573d6000803e3d6000fd5b505050506040513d602081101561240a57600080fd5b81019080805190602001909291905050506120ea565b565b61242a612711565b73ffffffffffffffffffffffffffffffffffffffff16612448611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146124d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001601660006101000a81548160ff0219169083151502179055506124f4613462565b565b6124fe612711565b73ffffffffffffffffffffffffffffffffffffffff1661251c611bbe565b73ffffffffffffffffffffffffffffffffffffffff16146125a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561262b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613fe26026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561279f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806141056024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612825576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806140086022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663095ea7b3601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660006040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156129b857600080fd5b505af11580156129cc573d6000803e3d6000fd5b505050506040513d60208110156129e257600080fd5b810190808051906020019092919050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612a7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806140e06025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613f9d6023913960400191505060405180910390fd5b612b0d8383836137ef565b612b788160405180606001604052806026815260200161402a602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612c0b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e8090919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290612d64576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d29578082015181840152602081019050612d0e565b50505050905090810190601f168015612d565780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600080831415612d845760009050612df1565b6000828402905082848281612d9557fe5b0414612dec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806140766021913960400191505060405180910390fd5b809150505b92915050565b6000808211612e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b818381612e7757fe5b04905092915050565b600080828401905083811015612efe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f8e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806140bf6021913960400191505060405180910390fd5b612f9a826000836137ef565b61300581604051806060016040528060228152602001613fc0602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612cb79092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061305c816002546133df90919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6131698363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613904565b505050565b600061317982611c06565b9050600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661329257735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561325157600080fd5b505af1158015613265573d6000803e3d6000fd5b505050506040513d602081101561327b57600080fd5b810190808051906020019092919050505050613376565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561333957600080fd5b505af115801561334d573d6000803e3d6000fd5b505050506040513d602081101561336357600080fd5b8101908080519060200190929190505050505b601660009054906101000a900460ff161561339557613394816139f3565b5b601154600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600082821115613457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2373ffffffffffffffffffffffffffffffffffffffff1663095ea7b3601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561352957600080fd5b505af115801561353d573d6000803e3d6000fd5b505050506040513d602081101561355357600080fd5b810190808051906020019092919050505050565b613622846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613904565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156136cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6136d7600083836137ef565b6136ec81600254612e8090919063ffffffff16565b600281905550613743816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e8090919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806138565750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15613860576138ff565b6138698361316e565b6138728261316e565b601154600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601154600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505050565b6060613966826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613cfc9092919063ffffffff16565b90506000815111156139ee5780806020019051602081101561398757600080fd5b81019080805190602001909291905050506139ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614129602a913960400191505060405180910390fd5b5b505050565b6060600267ffffffffffffffff81118015613a0d57600080fd5b50604051908082528060200260200182016040528015613a3c5781602001602082028036833780820191505090505b509050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600081518110613a6f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110613ad957fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166338ed173983600084600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16426040518663ffffffff1660e01b815260040180868152602001858152602001806020018473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613bf9578082015181840152602081019050613bde565b505050509050019650505050505050600060405180830381600087803b158015613c2257600080fd5b505af1158015613c36573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015613c6057600080fd5b8101908080516040519392919084640100000000821115613c8057600080fd5b83820191506020820185811115613c9657600080fd5b8251866020820283011164010000000082111715613cb357600080fd5b8083526020830192505050908051906020019060200280838360005b83811015613cea578082015181840152602081019050613ccf565b50505050905001604052505050505050565b6060613d0b8484600085613d14565b90509392505050565b606082471015613d6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806140506026913960400191505060405180910390fd5b613d7885613ebd565b613dea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613e3a5780518252602082019150602081019050602083039250613e17565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613e9c576040519150601f19603f3d011682016040523d82523d6000602084013e613ea1565b606091505b5091509150613eb1828286613ed0565b92505050949350505050565b600080823b905060008111915050919050565b60608315613ee057829050613f95565b600083511115613ef35782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f5a578082015181840152602081019050613f3f565b50505050905090810190601f168015613f875780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212205b5ca9d252d898620e9c01d9aca826d67eea112906d2e54a66d0cbac5877022164736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d3cecbe5639d05aed446da11f08d495ca6bf359f000000000000000000000000b20234c33337537111f4ab6f5ecad400134ac1430000000000000000000000005c7f8a570d578ed84e63fdfa7b1ee72deae1ae23000000000000000000000000d3cecbe5639d05aed446da11f08d495ca6bf359f
-----Decoded View---------------
Arg [0] : _croblanc (address): 0xd3cecbe5639d05aed446da11f08d495ca6bf359f
Arg [1] : _treasury (address): 0xb20234c33337537111f4ab6f5ecad400134ac143
Arg [2] : _routeFrom (address): 0x5c7f8a570d578ed84e63fdfa7b1ee72deae1ae23
Arg [3] : _routeTo (address): 0xd3cecbe5639d05aed446da11f08d495ca6bf359f
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d3cecbe5639d05aed446da11f08d495ca6bf359f
Arg [1] : 000000000000000000000000b20234c33337537111f4ab6f5ecad400134ac143
Arg [2] : 0000000000000000000000005c7f8a570d578ed84e63fdfa7b1ee72deae1ae23
Arg [3] : 000000000000000000000000d3cecbe5639d05aed446da11f08d495ca6bf359f
Deployed ByteCode Sourcemap
65573:8476:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13468:91;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15614:169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;72957:435;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66680:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;14567:108;;;:::i;:::-;;;;;;;;;;;;;;;;;;;72155:118;;;:::i;:::-;;66523:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16265:321;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;67426:476;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66178:24;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;70103:677;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66361:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66446:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;14411:91;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;66209:22;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;65838:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16995:218;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;72642:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;68387:106;;;:::i;:::-;;72758:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66148:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;14738:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;68569:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;35875:148;;;:::i;:::-;;66749:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;72281:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;70788:80;;;:::i;:::-;;35224:87;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;65894:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66271:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67965:356;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13678:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17716:269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;15078:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;66029:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;73400:644;;;:::i;:::-;;66484:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;69317:675;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66118:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;65962:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;15316:151;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;70000:95;;;:::i;:::-;;71939:114;;;:::i;:::-;;36178:244;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66593:66;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;13468:91;13513:13;13546:5;13539:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13468:91;:::o;15614:169::-;15697:4;15714:39;15723:12;:10;:12::i;:::-;15737:7;15746:6;15714:8;:39::i;:::-;15771:4;15764:11;;15614:169;;;;:::o;72957:435::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73098:1:::1;73069:9;:25;;;:30;73061:39;;;::::0;::::1;;73142:1;73119:25;;:11;:25;;;;73111:34;;;::::0;::::1;;73230:6;73212:15;:24;73184:9;:25;;:52;;;;73270:11;73247:9;:20;;;:34;;;;;;;;;;;;;;;;;;73345:11;73327:57;;;73358:9;:25;;;73327:57;;;;;;;;;;;;;;;;;;72957:435:::0;:::o;66680:32::-;;;;;;;;;;;;;;;;;;;;;;;:::o;14567:108::-;14628:7;14655:12;;14648:19;;14567:108;:::o;72155:118::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72230:5:::1;72211:16;;:24;;;;;;;;;;;;;;;;;;72246:19;:17;:19::i;:::-;72155:118::o:0;66523:32::-;;;;:::o;16265:321::-;16371:4;16388:36;16398:6;16406:9;16417:6;16388:9;:36::i;:::-;16435:121;16444:6;16452:12;:10;:12::i;:::-;16466:89;16504:6;16466:89;;;;;;;;;;;;;;;;;:11;:19;16478:6;16466:19;;;;;;;;;;;;;;;:33;16486:12;:10;:12::i;:::-;16466:33;;;;;;;;;;;;;;;;:37;;:89;;;;;:::i;:::-;16435:8;:121::i;:::-;16574:4;16567:11;;16265:321;;;;;:::o;67426:476::-;67525:1;67508:13;:11;:13::i;:::-;:18;67504:57;;;67543:7;;67504:57;66068:42;67600:25;;;67626:8;67644:4;67651:7;67600:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67706:20;67729:36;67751:13;:11;:13::i;:::-;67729:17;67741:4;67729:7;:11;;:17;;;;:::i;:::-;:21;;:36;;;;:::i;:::-;67706:59;;67796:35;67818:12;67796:17;;:21;;:35;;;;:::i;:::-;67776:17;:55;;;;67864:30;67886:7;67864:17;;:21;;:30;;;;:::i;:::-;67844:17;:50;;;;67426:476;;;;:::o;66178:24::-;;;;;;;;;;;;;:::o;70103:677::-;40456:1;41062:7;;:19;;41054:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40456:1;41195:7;:18;;;;70187:1:::1;70177:7;:11;70169:20;;;::::0;::::1;;70233:7;70208:21;70218:10;70208:9;:21::i;:::-;:32;;70200:41;;;::::0;::::1;;70282:9;:7;:9::i;:::-;70350:1;70340:7;:11;70336:248;;;70428:26;70434:10;70446:7;70428:5;:26::i;:::-;70522:50;70552:10;70564:7;70529:8;;;;;;;;;;;70522:29;;;;:50;;;;;:::i;:::-;70336:248;70708:17;;70667:26;:38;70694:10;70667:38;;;;;;;;;;;;;;;:58;;;;70752:10;70743:29;;;70764:7;70743:29;;;;;;;;;;;;;;;;;;40412:1:::0;41374:7;:22;;;;70103:677;:::o;66361:30::-;;;;:::o;66446:31::-;;;;:::o;14411:91::-;14460:5;14485:9;;;;;;;;;;;14478:16;;14411:91;:::o;66209:22::-;;;;;;;;;;;;;:::o;65838:49::-;;;;;;;;;;;;;;;;;:::o;16995:218::-;17083:4;17100:83;17109:12;:10;:12::i;:::-;17123:7;17132:50;17171:10;17132:11;:25;17144:12;:10;:12::i;:::-;17132:25;;;;;;;;;;;;;;;:34;17158:7;17132:34;;;;;;;;;;;;;;;;:38;;:50;;;;:::i;:::-;17100:8;:83::i;:::-;17201:4;17194:11;;16995:218;;;;:::o;72642:108::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72738:4:::1;72714:11;:21;72726:8;72714:21;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;72642:108:::0;:::o;68387:106::-;68455:30;68474:10;68455:18;:30::i;:::-;68387:106::o;72758:113::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72842:11:::1;:21;72854:8;72842:21;;;;;;;;;;;;;;;;72835:28;;;;;;;;;;;72758:113:::0;:::o;66148:23::-;;;;;;;;;;;;;:::o;14738:127::-;14812:7;14839:9;:18;14849:7;14839:18;;;;;;;;;;;;;;;;14832:25;;14738:127;;;:::o;68569:105::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68641:25:::1;68660:5;68641:18;:25::i;:::-;68569:105:::0;:::o;35875:148::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35982:1:::1;35945:40;;35966:6;;;;;;;;;;;35945:40;;;;;;;;;;;;36013:1;35996:6;;:19;;;;;;;;;;;;;;;;;;35875:148::o:0;66749:36::-;;;;;;;;;;;;;:::o;72281:147::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72381:10:::1;72369:9;;:22;;;;;;;;;;;;;;;;;;72412:8;72402:7;;:18;;;;;;;;;;;;;;;;;;72281:147:::0;;:::o;70788:80::-;70829:31;70838:21;70848:10;70838:9;:21::i;:::-;70829:8;:31::i;:::-;70788:80::o;35224:87::-;35270:7;35297:6;;;;;;;;;;;35290:13;;35224:87;:::o;65894:61::-;;;;;;;;;;;;;;;;;:::o;66271:29::-;;;;:::o;67965:356::-;68022:7;68046:16;;;;;;;;;;;68042:272;;;68086:88;68169:4;68086:78;68147:16;68157:5;68147:9;:16::i;:::-;68086:56;68108:26;:33;68135:5;68108:33;;;;;;;;;;;;;;;;68086:17;;:21;;:56;;;;:::i;:::-;:60;;:78;;;;:::i;:::-;:82;;:88;;;;:::i;:::-;68079:95;;;;68042:272;68214:88;68297:4;68214:78;68275:16;68285:5;68275:9;:16::i;:::-;68214:56;68236:26;:33;68263:5;68236:33;;;;;;;;;;;;;;;;68214:17;;:21;;:56;;;;:::i;:::-;:60;;:78;;;;:::i;:::-;:82;;:88;;;;:::i;:::-;68207:95;;67965:356;;;;:::o;13678:95::-;13725:13;13758:7;13751:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13678:95;:::o;17716:269::-;17809:4;17826:129;17835:12;:10;:12::i;:::-;17849:7;17858:96;17897:15;17858:96;;;;;;;;;;;;;;;;;:11;:25;17870:12;:10;:12::i;:::-;17858:25;;;;;;;;;;;;;;;:34;17884:7;17858:34;;;;;;;;;;;;;;;;:38;;:96;;;;;:::i;:::-;17826:8;:129::i;:::-;17973:4;17966:11;;17716:269;;;;:::o;15078:175::-;15164:4;15181:42;15191:12;:10;:12::i;:::-;15205:9;15216:6;15181:9;:42::i;:::-;15241:4;15234:11;;15078:175;;;;:::o;66029:82::-;66068:42;66029:82;:::o;73400:644::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73520:1:::1;73492:9;:25;;;:29;73484:38;;;::::0;::::1;;73570:15;73541:9;:25;;;:44;;73533:53;;;::::0;::::1;;73671:19;:17;:19::i;:::-;73738:9;:20;;;;;;;;;;;;73729:6;;:29;;;;;;;;;;;;;;;;;;73829:1;73798:9;:20;;;:33;;;;;;;;;;;;;;;;;;73870:1;73842:9;:25;;:29;;;;73934:17;:15;:17::i;:::-;74015:9;:20;;;;;;;;;;;;73997:39;;;;;;;;;;;;73400:644::o:0;66484:32::-;;;;:::o;69317:675::-;40456:1;41062:7;;:19;;41054:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40456:1;41195:7;:18;;;;69459:1:::1;69435:21;69445:10;69435:9;:21::i;:::-;:25;69431:105;;;69515:9;:7;:9::i;:::-;69431:105;69593:1;69583:7;:11;69579:228;;;69646:69;69680:10;69700:4;69707:7;69653:8;;;;;;;;;;;69646:33;;;;:69;;;;;;:::i;:::-;69769:26;69775:10;69787:7;69769:5;:26::i;:::-;69579:228;69921:17;;69880:26;:38;69907:10;69880:38;;;;;;;;;;;;;;;:58;;;;69964:10;69956:28;;;69976:7;69956:28;;;;;;;;;;;;;;;;;;40412:1:::0;41374:7;:22;;;;69317:675;:::o;66118:23::-;;;;;;;;;;;;;:::o;65962:43::-;;;;;;;;;;;;;;;;;;;;;;:::o;15316:151::-;15405:7;15432:11;:18;15444:5;15432:18;;;;;;;;;;;;;;;:27;15451:7;15432:27;;;;;;;;;;;;;;;;15425:34;;15316:151;;;;:::o;70000:95::-;70040:47;70055:8;;;;;;;;;;;70048:26;;;70075:10;70048:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70040:7;:47::i;:::-;70000:95::o;71939:114::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72013:4:::1;71994:16;;:23;;;;;;;;;;;;;;;;;;72028:17;:15;:17::i;:::-;71939:114::o:0;36178:244::-;35455:12;:10;:12::i;:::-;35444:23;;:7;:5;:7::i;:::-;:23;;;35436:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36287:1:::1;36267:22;;:8;:22;;;;36259:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36377:8;36348:38;;36369:6;;;;;;;;;;;36348:38;;;;;;;;;;;;36406:8;36397:6;;:17;;;;;;;;;;;;;;;;;;36178:244:::0;:::o;66593:66::-;;;;;;;;;;;;;:::o;10946:106::-;10999:15;11034:10;11027:17;;10946:106;:::o;20863:346::-;20982:1;20965:19;;:5;:19;;;;20957:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21063:1;21044:21;;:7;:21;;;;21036:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21147:6;21117:11;:18;21129:5;21117:18;;;;;;;;;;;;;;;:27;21136:7;21117:27;;;;;;;;;;;;;;;:36;;;;21185:7;21169:32;;21178:5;21169:32;;;21194:6;21169:32;;;;;;;;;;;;;;;;;;20863:346;;;:::o;72546:88::-;66068:42;72595:20;;;72616:6;;;;;;;;;;;72624:1;72595:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72546:88::o;18475:539::-;18599:1;18581:20;;:6;:20;;;;18573:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18683:1;18662:23;;:9;:23;;;;18654:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18738:47;18759:6;18767:9;18778:6;18738:20;:47::i;:::-;18818:71;18840:6;18818:71;;;;;;;;;;;;;;;;;:9;:17;18828:6;18818:17;;;;;;;;;;;;;;;;:21;;:71;;;;;:::i;:::-;18798:9;:17;18808:6;18798:17;;;;;;;;;;;;;;;:91;;;;18923:32;18948:6;18923:9;:20;18933:9;18923:20;;;;;;;;;;;;;;;;:24;;:32;;;;:::i;:::-;18900:9;:20;18910:9;18900:20;;;;;;;;;;;;;;;:55;;;;18988:9;18971:35;;18980:6;18971:35;;;18999:6;18971:35;;;;;;;;;;;;;;;;;;18475:539;;;:::o;5659:166::-;5745:7;5778:1;5773;:6;;5781:12;5765:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5816:1;5812;:5;5805:12;;5659:166;;;;;:::o;3711:220::-;3769:7;3798:1;3793;:6;3789:20;;;3808:1;3801:8;;;;3789:20;3820:9;3836:1;3832;:5;3820:17;;3865:1;3860;3856;:5;;;;;;:10;3848:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3922:1;3915:8;;;3711:220;;;;;:::o;4409:153::-;4467:7;4499:1;4495;:5;4487:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4553:1;4549;:5;;;;;;4542:12;;4409:153;;;;:::o;2832:179::-;2890:7;2910:9;2926:1;2922;:5;2910:17;;2951:1;2946;:6;;2938:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3002:1;2995:8;;;2832:179;;;;:::o;20007:418::-;20110:1;20091:21;;:7;:21;;;;20083:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20163:49;20184:7;20201:1;20205:6;20163:20;:49::i;:::-;20246:68;20269:6;20246:68;;;;;;;;;;;;;;;;;:9;:18;20256:7;20246:18;;;;;;;;;;;;;;;;:22;;:68;;;;;:::i;:::-;20225:9;:18;20235:7;20225:18;;;;;;;;;;;;;;;:89;;;;20340:24;20357:6;20340:12;;:16;;:24;;;;:::i;:::-;20325:12;:39;;;;20406:1;20380:37;;20389:7;20380:37;;;20410:6;20380:37;;;;;;;;;;;;;;;;;;20007:418;;:::o;31040:177::-;31123:86;31143:5;31173:23;;;31198:2;31202:5;31150:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31123:19;:86::i;:::-;31040:177;;;:::o;68709:600::-;68772:14;68789:18;68801:5;68789:11;:18::i;:::-;68772:35;;68949:11;:18;68961:5;68949:18;;;;;;;;;;;;;;;;;;;;;;;;;68944:160;;66068:42;68984:21;;;69006:5;69013:6;68984:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68944:160;;;66068:42;69053:21;;;69075:8;;;;;;;;;;;69085:6;69053:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68944:160;69150:16;;;;;;;;;;;69146:65;;;69183:16;69192:6;69183:8;:16::i;:::-;69146:65;69284:17;;69248:26;:33;69275:5;69248:33;;;;;;;;;;;;;;;:53;;;;68709:600;;:::o;3294:158::-;3352:7;3385:1;3380;:6;;3372:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3443:1;3439;:5;3432:12;;3294:158;;;;:::o;72436:102::-;66068:42;72483:20;;;72504:6;;;;;;;;;;;72512:17;72483:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72436:102::o;31225:205::-;31326:96;31346:5;31376:27;;;31405:4;31411:2;31415:5;31353:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31326:19;:96::i;:::-;31225:205;;;;:::o;19296:378::-;19399:1;19380:21;;:7;:21;;;;19372:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19450:49;19479:1;19483:7;19492:6;19450:20;:49::i;:::-;19527:24;19544:6;19527:12;;:16;;:24;;;;:::i;:::-;19512:12;:39;;;;19583:30;19606:6;19583:9;:18;19593:7;19583:18;;;;;;;;;;;;;;;;:22;;:30;;;;:::i;:::-;19562:9;:18;19572:7;19562:18;;;;;;;;;;;;;;;:51;;;;19650:7;19629:37;;19646:1;19629:37;;;19659:6;19629:37;;;;;;;;;;;;;;;;;;19296:378;;:::o;71285:554::-;71442:1;71426:18;;:4;:18;;;:38;;;;71462:1;71448:16;;:2;:16;;;71426:38;71422:107;;;71511:7;;71422:107;71584:24;71603:4;71584:18;:24::i;:::-;71619:22;71638:2;71619:18;:22::i;:::-;71753:17;;71718:26;:32;71745:4;71718:32;;;;;;;;;;;;;;;:52;;;;71814:17;;71781:26;:30;71808:2;71781:30;;;;;;;;;;;;;;;:50;;;;71285:554;;;;:::o;33345:761::-;33769:23;33795:69;33823:4;33795:69;;;;;;;;;;;;;;;;;33803:5;33795:27;;;;:69;;;;;:::i;:::-;33769:95;;33899:1;33879:10;:17;:21;33875:224;;;34021:10;34010:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34002:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33875:224;33345:761;;;:::o;70876:280::-;70935:22;70974:1;70960:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70935:41;;70998:9;;;;;;;;;;;70987:5;70993:1;70987:8;;;;;;;;;;;;;:20;;;;;;;;;;;71029:7;;;;;;;;;;;71018:5;71024:1;71018:8;;;;;;;;;;;;;:18;;;;;;;;;;;71066:6;;;;;;;;;;;71047:51;;;71099:11;71112:1;71115:5;71122:8;;;;;;;;;;;71132:15;71047:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70876:280;;:::o;26033:195::-;26136:12;26168:52;26190:6;26198:4;26204:1;26207:12;26168:21;:52::i;:::-;26161:59;;26033:195;;;;;:::o;27085:530::-;27212:12;27270:5;27245:21;:30;;27237:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27337:18;27348:6;27337:10;:18::i;:::-;27329:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27463:12;27477:23;27504:6;:11;;27524:5;27532:4;27504:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27462:75;;;;27555:52;27573:7;27582:10;27594:12;27555:17;:52::i;:::-;27548:59;;;;27085:530;;;;;;:::o;23115:422::-;23175:4;23383:12;23494:7;23482:20;23474:28;;23528:1;23521:4;:8;23514:15;;;23115:422;;;:::o;29625:742::-;29740:12;29769:7;29765:595;;;29800:10;29793:17;;;;29765:595;29934:1;29914:10;:17;:21;29910:439;;;30177:10;30171:17;30238:15;30225:10;30221:2;30217:19;30210:44;30125:148;30320:12;30313:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29625:742;;;;;;:::o
Swarm Source
ipfs://5b5ca9d252d898620e9c01d9aca826d67eea112906d2e54a66d0cbac58770221