Address Details
contract
0xBa6525D55084A1563D14F6Ac0216D1A588484fB7
- Contract Name
- GoodGhosting
- Creator
- 0xdbb021–173662 at 0x77f511–2cbba9
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 6 Transactions
- Transfers
- 16 Transfers
- Gas Used
- 1,656,270
- Last Balance Update
- 10286971
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- GoodGhosting
- Optimization enabled
- false
- Compiler version
- v0.6.11+commit.5ef660b1
- EVM Version
- istanbul
- Verified at
- 2022-08-21T09:36:30.870452Z
project:/contracts/GoodGhosting.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.11; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Pausable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./aave/ILendingPoolAddressesProvider.sol"; import "./aave/ILendingPool.sol"; import "./aave/AToken.sol"; /// @title GoodGhosting Game Contract /// @notice Used for games deployed on Ethereum Mainnet using Aave (v2) as the underlying pool, or for games deployed on Celo using Moola (v2) as the underlying pool /// @author Francis Odisi & Viraz Malhotra contract GoodGhosting is Ownable, Pausable { using SafeMath for uint256; /// @notice Ownership Control flag bool public allowRenouncingOwnership = false; /// @notice Controls if tokens were redeemed or not from the pool bool public redeemed; /// @notice controls if admin withdrew or not the performance fee. bool public adminWithdraw; /// @notice Address of the token used for depositing into the game by players (DAI) IERC20 public immutable daiToken; /// @notice Address of the interest bearing token received when funds are transferred to the external pool AToken public immutable adaiToken; /// @notice Which Aave instance we use to swap DAI to interest bearing aDAI ILendingPoolAddressesProvider public immutable lendingPoolAddressProvider; /// @notice Lending pool address ILendingPool public lendingPool; /// @notice Defines an optional token address used to provide additional incentives to users. Accepts "0x0" adresses when no incentive token exists. IERC20 public immutable incentiveToken; /// @notice total amount of incentive tokens to be distributed among winners uint256 public totalIncentiveAmount = 0; /// @notice Controls the amount of active players in the game (ignores players that early withdraw) uint256 public activePlayersCount = 0; /// @notice Stores the total amount of net interest received in the game. uint256 public totalGameInterest; /// @notice total principal amount uint256 public totalGamePrincipal; /// @notice performance fee amount allocated to the admin uint256 public adminFeeAmount; /// @notice The amount to be paid on each segment uint256 public immutable segmentPayment; /// @notice The number of segments in the game (segment count) uint256 public immutable lastSegment; /// @notice When the game started (deployed timestamp) uint256 public immutable firstSegmentStart; /// @notice The time duration (in seconds) of each segment uint256 public immutable segmentLength; /// @notice Defines the max quantity of players allowed in the game uint256 public immutable maxPlayersCount; /// @notice winner counter to track no of winners uint256 public winnerCount = 0; /// @notice The early withdrawal fee (percentage) uint8 public immutable earlyWithdrawalFee; /// @notice The performance admin fee (percentage) uint8 public immutable customFee; struct Player { bool withdrawn; bool canRejoin; bool isWinner; address addr; uint256 mostRecentSegmentPaid; uint256 amountPaid; uint256 winnerIndex; } /// @notice Stores info about the players in the game mapping(address => Player) public players; /// @notice controls the amount deposited in each segment that was not yet transferred to the external underlying pool /// @notice list of players address[] public iterablePlayers; /// @notice list of winners address[] public winners; event JoinedGame(address indexed player, uint256 amount); event Deposit( address indexed player, uint256 indexed segment, uint256 amount ); event Withdrawal( address indexed player, uint256 amount, uint256 playerReward, uint256 playerIncentive ); event FundsRedeemedFromExternalPool( uint256 totalAmount, uint256 totalGamePrincipal, uint256 totalGameInterest, uint256 rewards, uint256 totalIncentiveAmount ); event WinnersAnnouncement(address[] winners); event EarlyWithdrawal( address indexed player, uint256 amount, uint256 totalGamePrincipal ); event AdminWithdrawal( address indexed admin, uint256 totalGameInterest, uint256 adminFeeAmount, uint256 adminIncentiveAmount ); modifier whenGameIsCompleted() { require(isGameCompleted(), "Game is not completed"); _; } modifier whenGameIsNotCompleted() { require(!isGameCompleted(), "Game is already completed"); _; } /** Creates a new instance of GoodGhosting game @param _inboundCurrency Smart contract address of inbound currency used for the game. @param _lendingPoolAddressProvider Smart contract address of the lending pool adddress provider. @param _segmentCount Number of segments in the game. @param _segmentLength Lenght of each segment, in seconds (i.e., 180 (sec) => 3 minutes). @param _segmentPayment Amount of tokens each player needs to contribute per segment (i.e. 10*10**18 equals to 10 DAI - note that DAI uses 18 decimal places). @param _earlyWithdrawalFee Fee paid by users on early withdrawals (before the game completes). Used as an integer percentage (i.e., 10 represents 10%). @param _customFee performance fee charged by admin. Used as an integer percentage (i.e., 10 represents 10%). Does not accept "decimal" fees like "0.5". @param _dataProvider id for getting the data provider contract address 0x1 to be passed. @param _maxPlayersCount max quantity of players allowed to join the game @param _incentiveToken optional token address used to provide additional incentives to users. Accepts "0x0" adresses when no incentive token exists. */ constructor( IERC20 _inboundCurrency, ILendingPoolAddressesProvider _lendingPoolAddressProvider, uint256 _segmentCount, uint256 _segmentLength, uint256 _segmentPayment, uint8 _earlyWithdrawalFee, uint8 _customFee, address _dataProvider, uint256 _maxPlayersCount, IERC20 _incentiveToken ) public { require(_customFee <= 20, "_customFee must be less than or equal to 20%"); require(_earlyWithdrawalFee <= 10, "_earlyWithdrawalFee must be less than or equal to 10%"); require(_earlyWithdrawalFee > 0, "_earlyWithdrawalFee must be greater than zero"); require(_maxPlayersCount > 0, "_maxPlayersCount must be greater than zero"); require(address(_inboundCurrency) != address(0), "invalid _inboundCurrency address"); require(address(_lendingPoolAddressProvider) != address(0), "invalid _lendingPoolAddressProvider address"); require(_segmentCount > 0, "_segmentCount must be greater than zero"); require(_segmentLength > 0, "_segmentLength must be greater than zero"); require(_segmentPayment > 0, "_segmentPayment must be greater than zero"); require(_dataProvider != address(0), "invalid _dataProvider address"); // Initializes default variables firstSegmentStart = block.timestamp; //gets current time lastSegment = _segmentCount; segmentLength = _segmentLength; segmentPayment = _segmentPayment; earlyWithdrawalFee = _earlyWithdrawalFee; customFee = _customFee; daiToken = _inboundCurrency; lendingPoolAddressProvider = _lendingPoolAddressProvider; AaveProtocolDataProvider dataProvider = AaveProtocolDataProvider(_dataProvider); // lending pool needs to be approved in v2 since it is the core contract in v2 and not lending pool core lendingPool = ILendingPool( _lendingPoolAddressProvider.getLendingPool() ); // atoken address in v2 is fetched from data provider contract (address adaiTokenAddress, , ) = dataProvider.getReserveTokensAddresses(address(_inboundCurrency)); adaiToken = AToken(adaiTokenAddress); maxPlayersCount = _maxPlayersCount; incentiveToken = _incentiveToken; } /// @notice pauses the game. This function can be called only by the contract's admin. function pause() external onlyOwner whenNotPaused { _pause(); } /// @notice unpauses the game. This function can be called only by the contract's admin. function unpause() external onlyOwner whenPaused { _unpause(); } /// @notice Renounces Ownership. function renounceOwnership() public override onlyOwner { require(allowRenouncingOwnership, "Not allowed"); super.renounceOwnership(); } /// @notice Unlocks renounceOwnership. function unlockRenounceOwnership() external onlyOwner { allowRenouncingOwnership = true; } /// @notice Allows the admin to withdraw the performance fee, if applicable. This function can be called only by the contract's admin. /// @dev Cannot be called before the game ends. function adminFeeWithdraw() external virtual onlyOwner whenGameIsCompleted { require(redeemed, "Funds not redeemed from external pool"); require(!adminWithdraw, "Admin has already withdrawn"); adminWithdraw = true; // when there are no winners, admin will be able to withdraw the // additional incentives sent to the pool, avoiding locking the funds. uint256 adminIncentiveAmount = 0; if (winnerCount == 0 && totalIncentiveAmount > 0) { adminIncentiveAmount = totalIncentiveAmount; } emit AdminWithdrawal(owner(), totalGameInterest, adminFeeAmount, adminIncentiveAmount); if (adminFeeAmount > 0) { require( IERC20(daiToken).transfer(owner(), adminFeeAmount), "Fail to transfer ER20 tokens to admin" ); } if (adminIncentiveAmount > 0) { require( IERC20(incentiveToken).transfer(owner(), adminIncentiveAmount), "Fail to transfer ER20 incentive tokens to admin" ); } } /// @notice Allows a player to join the game function joinGame() external virtual whenNotPaused { _joinGame(); } /// @notice Allows a player to withdraw funds before the game ends. An early withdrawal fee is charged. /// @dev Cannot be called after the game is completed. function earlyWithdraw() external whenNotPaused whenGameIsNotCompleted { Player storage player = players[msg.sender]; require(player.amountPaid > 0, "Player does not exist"); require(!player.withdrawn, "Player has already withdrawn"); player.withdrawn = true; activePlayersCount = activePlayersCount.sub(1); if (winnerCount > 0 && player.isWinner) { winnerCount = winnerCount.sub(uint(1)); player.isWinner = false; winners[player.winnerIndex] = address(0); } // In an early withdraw, users get their principal minus the earlyWithdrawalFee % defined in the constructor. uint256 withdrawAmount = player.amountPaid.sub( player.amountPaid.mul(earlyWithdrawalFee).div(100) ); // Decreases the totalGamePrincipal on earlyWithdraw totalGamePrincipal = totalGamePrincipal.sub(player.amountPaid); uint256 currentSegment = getCurrentSegment(); // Users that early withdraw during the first segment, are allowed to rejoin. if (currentSegment == 0) { player.canRejoin = true; } emit EarlyWithdrawal(msg.sender, withdrawAmount, totalGamePrincipal); lendingPool.withdraw(address(daiToken), withdrawAmount, address(this)); require( IERC20(daiToken).transfer(msg.sender, withdrawAmount), "Fail to transfer ERC20 tokens on early withdraw" ); } /// @notice Allows player to withdraw their funds after the game ends with no loss (fee). Winners get a share of the interest earned. function withdraw() external virtual { Player storage player = players[msg.sender]; require(player.amountPaid > 0, "Player does not exist"); require(!player.withdrawn, "Player has already withdrawn"); player.withdrawn = true; // First player to withdraw redeems everyone's funds if (!redeemed) { redeemFromExternalPool(); } uint256 payout = player.amountPaid; uint256 playerIncentive = 0; if (player.mostRecentSegmentPaid == lastSegment.sub(1)) { // Player is a winner and gets a bonus! payout = payout.add(totalGameInterest.div(winnerCount)); // If there's additional incentives, distributes them to winners if (totalIncentiveAmount > 0) { playerIncentive = totalIncentiveAmount.div(winnerCount); } } emit Withdrawal(msg.sender, payout, 0, playerIncentive); require( IERC20(daiToken).transfer(msg.sender, payout), "Fail to transfer ERC20 tokens on withdraw" ); if (playerIncentive > 0) { require( IERC20(incentiveToken).transfer(msg.sender, playerIncentive), "Fail to transfer ERC20 incentive tokens on withdraw" ); } } /// @notice Allows players to make deposits for the game segments, after joining the game. function makeDeposit() external whenNotPaused { Player storage player = players[msg.sender]; require( !player.withdrawn, "Player already withdraw from game" ); // only registered players can deposit require( player.addr == msg.sender, "Sender is not a player" ); uint256 currentSegment = getCurrentSegment(); // User can only deposit between segment 1 and segment n-1 (where n is the number of segments for the game). // Details: // Segment 0 is paid when user joins the game (the first deposit window). // Last segment doesn't accept payments, because the payment window for the last // segment happens on segment n-1 (penultimate segment). // Any segment greater than the last segment means the game is completed, and cannot // receive payments require( currentSegment > 0 && currentSegment < lastSegment, "Deposit available only between segment 1 and segment n-1 (penultimate)" ); //check if current segment is currently unpaid require( player.mostRecentSegmentPaid != currentSegment, "Player already paid current segment" ); // check if player has made payments up to the previous segment require( player.mostRecentSegmentPaid == currentSegment.sub(1), "Player didn't pay the previous segment - game over!" ); emit Deposit(msg.sender, currentSegment, segmentPayment); _transferDaiToContract(); } /// @notice gets the number of players in the game /// @return number of players function getNumberOfPlayers() external view returns (uint256) { return iterablePlayers.length; } /// @notice Redeems funds from the external pool and updates the internal accounting controls related to the game stats. /// @dev Can only be called after the game is completed. function redeemFromExternalPool() public virtual whenGameIsCompleted { require(!redeemed, "Redeem operation already happened for the game"); redeemed = true; // Withdraws funds (principal + interest + rewards) from external pool if (adaiToken.balanceOf(address(this)) > 0) { lendingPool.withdraw( address(daiToken), type(uint256).max, address(this) ); } uint256 totalBalance = IERC20(daiToken).balanceOf(address(this)); // If there's an incentive token address defined, sets the total incentive amount to be distributed among winners. if (address(incentiveToken) != address(0)) { totalIncentiveAmount = IERC20(incentiveToken).balanceOf(address(this)); } // calculates gross interest uint256 grossInterest = 0; // Sanity check to avoid reverting due to overflow in the "subtraction" below. // This could only happen in case Aave changes the 1:1 ratio between // aToken vs. Token in the future (i.e., 1 aDAI is worth less than 1 DAI) if (totalBalance > totalGamePrincipal) { grossInterest = totalBalance.sub(totalGamePrincipal); } // calculates the performance/admin fee (takes a cut - the admin percentage fee - from the pool's interest). // calculates the "gameInterest" (net interest) that will be split among winners in the game uint256 _adminFeeAmount; if (customFee > 0) { _adminFeeAmount = (grossInterest.mul(customFee)).div(100); totalGameInterest = grossInterest.sub(_adminFeeAmount); } else { _adminFeeAmount = 0; totalGameInterest = grossInterest; } // when there's no winners, admin takes all the interest + rewards if (winnerCount == 0) { adminFeeAmount = grossInterest; } else { adminFeeAmount = _adminFeeAmount; } emit FundsRedeemedFromExternalPool( totalBalance, totalGamePrincipal, totalGameInterest, 0, totalIncentiveAmount ); emit WinnersAnnouncement(winners); } /// @notice Calculates the current segment of the game. /// @return current game segment function getCurrentSegment() public view returns (uint256) { return block.timestamp.sub(firstSegmentStart).div(segmentLength); } /// @notice Checks if the game is completed or not. /// @return "true" if completeted; otherwise, "false". function isGameCompleted() public view returns (bool) { // Game is completed when the current segment is greater than "lastSegment" of the game. return getCurrentSegment() > lastSegment; } /** @dev Manages the transfer of funds from the player to the contract, recording the required accounting operations to control the user's position in the pool. */ function _transferDaiToContract() internal { require( daiToken.allowance(msg.sender, address(this)) >= segmentPayment, "You need to have allowance to do transfer DAI on the smart contract" ); uint256 currentSegment = getCurrentSegment(); players[msg.sender].mostRecentSegmentPaid = currentSegment; players[msg.sender].amountPaid = players[msg.sender].amountPaid.add( segmentPayment ); // check if this is deposit for the last segment. If yes, the player is a winner. // since both join game and deposit method call this method so having it here if (currentSegment == lastSegment.sub(1)) { winners.push(msg.sender); // array indexes start from 0 players[msg.sender].winnerIndex = winners.length.sub(uint(1)); winnerCount = winnerCount.add(uint(1)); players[msg.sender].isWinner = true; } totalGamePrincipal = totalGamePrincipal.add(segmentPayment); require( daiToken.transferFrom(msg.sender, address(this), segmentPayment), "Transfer failed" ); // Allows the lending pool to convert DAI deposited on this contract to aDAI on lending pool uint256 contractBalance = daiToken.balanceOf(address(this)); require( daiToken.approve(address(lendingPool), contractBalance), "Fail to approve allowance to lending pool" ); lendingPool.deposit(address(daiToken), contractBalance, address(this), 155); } /// @notice Allows a player to join the game and controls function _joinGame() internal { require(getCurrentSegment() == 0, "Game has already started"); require( players[msg.sender].addr != msg.sender || players[msg.sender].canRejoin, "Cannot join the game more than once" ); activePlayersCount = activePlayersCount.add(1); require(activePlayersCount <= maxPlayersCount, "Reached max quantity of players allowed"); bool canRejoin = players[msg.sender].canRejoin; Player memory newPlayer = Player({ addr: msg.sender, mostRecentSegmentPaid: 0, amountPaid: 0, withdrawn: false, canRejoin: false, isWinner: false, winnerIndex: 0 }); players[msg.sender] = newPlayer; if (!canRejoin) { iterablePlayers.push(msg.sender); } emit JoinedGame(msg.sender, segmentPayment); _transferDaiToContract(); } }
/_openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol"; /** * @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; } }
/_openzeppelin/contracts/math/SafeMath.sol
// SPDX-License-Identifier: MIT 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; } }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT 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); }
/_openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT 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; } }
/_openzeppelin/contracts/utils/Pausable.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./Context.sol"; /** * @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()); } }
/project_/contracts/aave/AToken.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.11; interface AToken { /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); }
/project_/contracts/aave/ILendingPool.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.11; interface ILendingPool { function deposit(address _reserve, uint256 _amount, address onBehalfOf, uint16 _referralCode) external; //see: https://github.com/aave/aave-protocol/blob/1ff8418eb5c73ce233ac44bfb7541d07828b273f/contracts/tokenization/AToken.sol#L218 function withdraw(address asset, uint amount, address to) external; } interface AaveProtocolDataProvider { function getReserveTokensAddresses(address asset) external view returns(address, address, address); }
/project_/contracts/aave/ILendingPoolAddressesProvider.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.11; /** @title ILendingPoolAddressesProvider interface @notice provides the interface to fetch the LendingPoolCore address */ abstract contract ILendingPoolAddressesProvider { function getLendingPool() public virtual view returns (address); function setLendingPoolImpl(address _pool) public virtual; function getAddress(bytes32 id) public virtual view returns (address); function getLendingPoolCore() public virtual view returns (address payable); function setLendingPoolCoreImpl(address _lendingPoolCore) public virtual; function getLendingPoolConfigurator() public virtual view returns (address); function setLendingPoolConfiguratorImpl(address _configurator) public virtual; function getLendingPoolDataProvider() public virtual view returns (address); function setLendingPoolDataProviderImpl(address _provider) public virtual; function getLendingPoolParametersProvider() public virtual view returns (address); function setLendingPoolParametersProviderImpl(address _parametersProvider) public virtual; function getTokenDistributor() public virtual view returns (address); function setTokenDistributor(address _tokenDistributor) public virtual; function getFeeProvider() public virtual view returns (address); function setFeeProviderImpl(address _feeProvider) public virtual; function getLendingPoolLiquidationManager() public virtual view returns (address); function setLendingPoolLiquidationManager(address _manager) public virtual; function getLendingPoolManager() public virtual view returns (address); function setLendingPoolManager(address _lendingPoolManager) public virtual; function getPriceOracle() public virtual view returns (address); function setPriceOracle(address _priceOracle) public virtual; function getLendingRateOracle() public virtual view returns (address); function setLendingRateOracle(address _lendingRateOracle) public virtual; }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_inboundCurrency","internalType":"contract IERC20"},{"type":"address","name":"_lendingPoolAddressProvider","internalType":"contract ILendingPoolAddressesProvider"},{"type":"uint256","name":"_segmentCount","internalType":"uint256"},{"type":"uint256","name":"_segmentLength","internalType":"uint256"},{"type":"uint256","name":"_segmentPayment","internalType":"uint256"},{"type":"uint8","name":"_earlyWithdrawalFee","internalType":"uint8"},{"type":"uint8","name":"_customFee","internalType":"uint8"},{"type":"address","name":"_dataProvider","internalType":"address"},{"type":"uint256","name":"_maxPlayersCount","internalType":"uint256"},{"type":"address","name":"_incentiveToken","internalType":"contract IERC20"}]},{"type":"event","name":"AdminWithdrawal","inputs":[{"type":"address","name":"admin","internalType":"address","indexed":true},{"type":"uint256","name":"totalGameInterest","internalType":"uint256","indexed":false},{"type":"uint256","name":"adminFeeAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"adminIncentiveAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Deposit","inputs":[{"type":"address","name":"player","internalType":"address","indexed":true},{"type":"uint256","name":"segment","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EarlyWithdrawal","inputs":[{"type":"address","name":"player","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalGamePrincipal","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FundsRedeemedFromExternalPool","inputs":[{"type":"uint256","name":"totalAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalGamePrincipal","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalGameInterest","internalType":"uint256","indexed":false},{"type":"uint256","name":"rewards","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalIncentiveAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"JoinedGame","inputs":[{"type":"address","name":"player","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"WinnersAnnouncement","inputs":[{"type":"address[]","name":"winners","internalType":"address[]","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawal","inputs":[{"type":"address","name":"player","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"playerReward","internalType":"uint256","indexed":false},{"type":"uint256","name":"playerIncentive","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"activePlayersCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract AToken"}],"name":"adaiToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"adminFeeAmount","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"adminFeeWithdraw","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"adminWithdraw","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"allowRenouncingOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"customFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"daiToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"earlyWithdraw","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"earlyWithdrawalFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"firstSegmentStart","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentSegment","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNumberOfPlayers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"incentiveToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isGameCompleted","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"iterablePlayers","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"joinGame","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastSegment","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ILendingPool"}],"name":"lendingPool","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ILendingPoolAddressesProvider"}],"name":"lendingPoolAddressProvider","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"makeDeposit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxPlayersCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"withdrawn","internalType":"bool"},{"type":"bool","name":"canRejoin","internalType":"bool"},{"type":"bool","name":"isWinner","internalType":"bool"},{"type":"address","name":"addr","internalType":"address"},{"type":"uint256","name":"mostRecentSegmentPaid","internalType":"uint256"},{"type":"uint256","name":"amountPaid","internalType":"uint256"},{"type":"uint256","name":"winnerIndex","internalType":"uint256"}],"name":"players","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"redeemFromExternalPool","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"redeemed","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"segmentLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"segmentPayment","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalGameInterest","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalGamePrincipal","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalIncentiveAmount","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unlockRenounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"winnerCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"winners","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[]}]
Contract Creation Code
0x6101e060405260008060156101000a81548160ff0219169083151502179055506000600255600060035560006007553480156200003b57600080fd5b50604051620051e9380380620051e983398181016040526101408110156200006257600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050506000620000df620008cc60201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35060008060146101000a81548160ff02191690831515021790555060148460ff161115620001f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806200508e602c913960400191505060405180910390fd5b600a8560ff16111562000255576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180620051896035913960400191505060405180910390fd5b60008560ff1611620002b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806200510c602d913960400191505060405180910390fd5b600082116200030e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180620050ba602a913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415620003b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f696e76616c6964205f696e626f756e6443757272656e6379206164647265737381525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614156200043a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180620051be602b913960400191505060405180910390fd5b6000881162000495576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180620051396027913960400191505060405180910390fd5b60008711620004f0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180620050e46028913960400191505060405180910390fd5b600086116200054b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180620051606029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415620005ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f696e76616c6964205f6461746150726f7669646572206164647265737300000081525060200191505060405180910390fd5b4261014081815250508761012081815250508661016081815250508561010081815250508460ff166101a08160ff1660f81b815250508360ff166101c08160ff1660f81b815250508973ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508873ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060008390508973ffffffffffffffffffffffffffffffffffffffff16630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015620006f157600080fd5b505afa15801562000706573d6000803e3d6000fd5b505050506040513d60208110156200071d57600080fd5b8101908080519060200190929190505050600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008173ffffffffffffffffffffffffffffffffffffffff1663d2493b6c8d6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060606040518083038186803b158015620007ee57600080fd5b505afa15801562000803573d6000803e3d6000fd5b505050506040513d60608110156200081a57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050505090508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508361018081815250508273ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505050505050505050505050620008d4565b600033905090565b60805160601c60a05160601c60c05160601c60e05160601c61010051610120516101405161016051610180516101a05160f81c6101c05160f81c61468c62000a02600039806119e55280612d725280612da4525080610c415280610f96525080611b9e5280613ffa525080611e5552806127c15250806114b652806127e55250806108e5528061114f528061180f5280611e2052806135055250806108c1528061198d528061326e5280613448528061367852806136ee52806142d15250806113795280611a33528061230c5280612c2d5280612c69525080611a0f525080611d9a5280612925525080610d835280610e5a52806112395280611dfa52806121c25280612a415280612b3b528061328f52806136b0528061385a52806139345280613acb525061468c6000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c80638da5cb5b1161013b578063d4f77b1c116100b8578063f2fde38b1161007c578063f2fde38b1461082b578063f4ceab1c1461086f578063f5c9786714610879578063f8dd5ad314610897578063fd6673f5146108a157610248565b8063d4f77b1c14610719578063e0236a1814610723578063e231bff01461072d578063e2eb41ff1461074f578063f18d20be1461080957610248565b8063aad739f5116100ff578063aad739f514610603578063be22f54614610671578063c39b583c146106bb578063caa02e08146106dd578063d013666e146106fb57610248565b80638da5cb5b1461049957806395224b33146104e3578063a2fb117514610501578063a59a99731461056f578063a98a5c94146105b957610248565b80635edafd5a116101c9578063715018a61161018d578063715018a6146104275780637a23032c146104315780637c80e6da1461044f5780637e5f84761461046d5780638456cb591461048f57610248565b80635edafd5a146103335780635faeea37146103575780636338030014610375578063638126f8146103bf5780636a79328a1461040957610248565b80633ccfd60b116102105780633ccfd60b146102d55780633e7433eb146102df5780633f4ba83a146102fd57806340732c89146103075780635c975abb1461031157610248565b80630c8ac6451461024d57806311b2e2d91461026b57806315d74bb31461028957806316330d4014610293578063250a2b0d146102b7575b600080fd5b6102556108bf565b6040518082815260200191505060405180910390f35b6102736108e3565b6040518082815260200191505060405180910390f35b610291610907565b005b61029b610f94565b604051808260ff1660ff16815260200191505060405180910390f35b6102bf610fb8565b6040518082815260200191505060405180910390f35b6102dd610fbe565b005b6102e76114b4565b6040518082815260200191505060405180910390f35b6103056114d8565b005b61030f61160b565b005b6103196119cd565b604051808215151515815260200191505060405180910390f35b61033b6119e3565b604051808260ff1660ff16815260200191505060405180910390f35b61035f611a07565b6040518082815260200191505060405180910390f35b61037d611a0d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103c7611a31565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610411611a55565b6040518082815260200191505060405180910390f35b61042f611a5b565b005b610439611b96565b6040518082815260200191505060405180910390f35b610457611b9c565b6040518082815260200191505060405180910390f35b610475611bc0565b604051808215151515815260200191505060405180910390f35b610497611bd3565b005b6104a1611d07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104eb611d30565b6040518082815260200191505060405180910390f35b61052d6004803603602081101561051757600080fd5b8101908080359060200190929190505050611d36565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610577611d72565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105c1611d98565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61062f6004803603602081101561061957600080fd5b8101908080359060200190929190505050611dbc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610679611df8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106c3611e1c565b604051808215151515815260200191505060405180910390f35b6106e5611e4d565b6040518082815260200191505060405180910390f35b610703611e53565b6040518082815260200191505060405180910390f35b610721611e77565b005b61072b611efc565b005b61073561244c565b604051808215151515815260200191505060405180910390f35b6107916004803603602081101561076557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061245f565b604051808815151515815260200187151515158152602001861515151581526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182815260200197505050505050505060405180910390f35b6108116124e8565b604051808215151515815260200191505060405180910390f35b61086d6004803603602081101561084157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506124fb565b005b6108776126ee565b005b6108816127ba565b6040518082815260200191505060405180910390f35b61089f612826565b005b6108a9612f3d565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b61090f6119cd565b15610982576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b61098a611e1c565b156109fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f47616d6520697320616c726561647920636f6d706c657465640000000000000081525060200191505060405180910390fd5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816002015411610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f506c6179657220646f6573206e6f74206578697374000000000000000000000081525060200191505060405180910390fd5b8060000160009054906101000a900460ff1615610b3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f506c617965722068617320616c72656164792077697468647261776e0000000081525060200191505060405180910390fd5b60018160000160006101000a81548160ff021916908315150217905550610b726001600354612f4a90919063ffffffff16565b6003819055506000600754118015610b9857508060000160029054906101000a900460ff165b15610c3257610bb36001600754612f4a90919063ffffffff16565b60078190555060008160000160026101000a81548160ff0219169083151502179055506000600a826003015481548110610be957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6000610c97610c846064610c767f000000000000000000000000000000000000000000000000000000000000000060ff168660020154612fcd90919063ffffffff16565b61305390919063ffffffff16565b8360020154612f4a90919063ffffffff16565b9050610cb28260020154600554612f4a90919063ffffffff16565b6005819055506000610cc26127ba565b90506000811415610ceb5760018360000160016101000a81548160ff0219169083151502179055505b3373ffffffffffffffffffffffffffffffffffffffff167f1670585e36568ede58d159518ce92cad99f75ad41c7d8281df3dd4eaa0c855d083600554604051808381526020018281526020019250505060405180910390a2600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000000000000000000000000000000000000000000084306040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b158015610e4057600080fd5b505af1158015610e54573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610eff57600080fd5b505af1158015610f13573d6000803e3d6000fd5b505050506040513d6020811015610f2957600080fd5b8101908080519060200190929190505050610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614392602f913960400191505060405180910390fd5b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600201541161107b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f506c6179657220646f6573206e6f74206578697374000000000000000000000081525060200191505060405180910390fd5b8060000160009054906101000a900460ff1615611100576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f506c617965722068617320616c72656164792077697468647261776e0000000081525060200191505060405180910390fd5b60018160000160006101000a81548160ff021916908315150217905550600060169054906101000a900460ff1661113a57611139612826565b5b600081600201549050600080905061117c60017f0000000000000000000000000000000000000000000000000000000000000000612f4a90919063ffffffff16565b836001015414156111d8576111b06111a160075460045461305390919063ffffffff16565b836130dc90919063ffffffff16565b9150600060025411156111d7576111d460075460025461305390919063ffffffff16565b90505b5b3373ffffffffffffffffffffffffffffffffffffffff167f650fdf669e93aa6c8ff3defe2da9c12b64f1548e5e1e54e803f4c1beb6466c8e8360008460405180848152602001838152602001828152602001935050505060405180910390a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156112de57600080fd5b505af11580156112f2573d6000803e3d6000fd5b505050506040513d602081101561130857600080fd5b810190808051906020019092919050505061136e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806144ce6029913960400191505060405180910390fd5b60008111156114af577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561141e57600080fd5b505af1158015611432573d6000803e3d6000fd5b505050506040513d602081101561144857600080fd5b81019080805190602001909291905050506114ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806145f16033913960400191505060405180910390fd5b5b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6114e0613164565b73ffffffffffffffffffffffffffffffffffffffff166114fe611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61158f6119cd565b611601576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b61160961316c565b565b6116136119cd565b15611686576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff1615611731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061458a6021913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168160000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146117f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f53656e646572206973206e6f74206120706c617965720000000000000000000081525060200191505060405180910390fd5b60006118006127ba565b905060008111801561183157507f000000000000000000000000000000000000000000000000000000000000000081105b611886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604681526020018061443a6046913960600191505060405180910390fd5b80826001015414156118e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806145ce6023913960400191505060405180910390fd5b6118f7600182612f4a90919063ffffffff16565b826001015414611952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806146246033913960400191505060405180910390fd5b803373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a157f00000000000000000000000000000000000000000000000000000000000000006040518082815260200191505060405180910390a36119c961326c565b5050565b60008060149054906101000a900460ff16905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055481565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025481565b611a63613164565b73ffffffffffffffffffffffffffffffffffffffff16611a81611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611b0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060159054906101000a900460ff16611b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f4e6f7420616c6c6f77656400000000000000000000000000000000000000000081525060200191505060405180910390fd5b611b94613bb1565b565b60065481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600060159054906101000a900460ff1681565b611bdb613164565b73ffffffffffffffffffffffffffffffffffffffff16611bf9611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c8a6119cd565b15611cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b611d05613d1f565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60045481565b600a8181548110611d4357fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60098181548110611dc957fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f0000000000000000000000000000000000000000000000000000000000000000611e476127ba565b11905090565b60075481565b7f000000000000000000000000000000000000000000000000000000000000000081565b611e7f6119cd565b15611ef2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b611efa613e21565b565b611f04613164565b73ffffffffffffffffffffffffffffffffffffffff16611f22611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611fab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611fb3611e1c565b612025576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f47616d65206973206e6f7420636f6d706c65746564000000000000000000000081525060200191505060405180910390fd5b600060169054906101000a900460ff1661208a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806144806025913960400191505060405180910390fd5b600060179054906101000a900460ff161561210d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f41646d696e2068617320616c72656164792077697468647261776e000000000081525060200191505060405180910390fd5b6001600060176101000a81548160ff0219169083151502179055506000809050600060075414801561214157506000600254115b1561214c5760025490505b612154611d07565b73ffffffffffffffffffffffffffffffffffffffff167f80ebcacc706983394bb8fcc88ea7b9241338fb4617fffbea411b68b40ed5627e6004546006548460405180848152602001838152602001828152602001935050505060405180910390a260006006541115612301577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb612204611d07565b6006546040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561227057600080fd5b505af1158015612284573d6000803e3d6000fd5b505050506040513d602081101561229a57600080fd5b8101908080519060200190929190505050612300576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806144156025913960400191505060405180910390fd5b5b6000811115612449577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61234e611d07565b836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156123b857600080fd5b505af11580156123cc573d6000803e3d6000fd5b505050506040513d60208110156123e257600080fd5b8101908080519060200190929190505050612448576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614518602f913960400191505060405180910390fd5b5b50565b600060169054906101000a900460ff1681565b60086020528060005260406000206000915090508060000160009054906101000a900460ff16908060000160019054906101000a900460ff16908060000160029054906101000a900460ff16908060000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154905087565b600060179054906101000a900460ff1681565b612503613164565b73ffffffffffffffffffffffffffffffffffffffff16612521611d07565b73ffffffffffffffffffffffffffffffffffffffff16146125aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612630576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143ef6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6126f6613164565b73ffffffffffffffffffffffffffffffffffffffff16612714611d07565b73ffffffffffffffffffffffffffffffffffffffff161461279d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600060156101000a81548160ff021916908315150217905550565b60006128217f00000000000000000000000000000000000000000000000000000000000000006128137f000000000000000000000000000000000000000000000000000000000000000042612f4a90919063ffffffff16565b61305390919063ffffffff16565b905090565b61282e611e1c565b6128a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f47616d65206973206e6f7420636f6d706c65746564000000000000000000000081525060200191505060405180910390fd5b600060169054906101000a900460ff1615612906576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806143c1602e913960400191505060405180910390fd5b6001600060166101000a81548160ff02191690831515021790555060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156129c057600080fd5b505afa1580156129d4573d6000803e3d6000fd5b505050506040513d60208110156129ea57600080fd5b81019080805190602001909291905050501115612b3757600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166369328dec7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff306040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b158015612b1e57600080fd5b505af1158015612b32573d6000803e3d6000fd5b505050505b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612bd657600080fd5b505afa158015612bea573d6000803e3d6000fd5b505050506040513d6020811015612c0057600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1614612d46577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612d0457600080fd5b505afa158015612d18573d6000803e3d6000fd5b505050506040513d6020811015612d2e57600080fd5b81019080805190602001909291905050506002819055505b6000809050600554821115612d6d57612d6a60055483612f4a90919063ffffffff16565b90505b6000807f000000000000000000000000000000000000000000000000000000000000000060ff161115612e0357612de36064612dd57f000000000000000000000000000000000000000000000000000000000000000060ff1685612fcd90919063ffffffff16565b61305390919063ffffffff16565b9050612df88183612f4a90919063ffffffff16565b600481905550612e0f565b60009050816004819055505b60006007541415612e265781600681905550612e2e565b806006819055505b7f28d72925fdcea205b246c820015bd35812a740d1ec1a5cdc84f7784b50940fbb836005546004546000600254604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a17fdbb9607e18553d40c255226e09883b48f92a108f6f895b0f37db6ae0d7fd56e6600a60405180806020018281038252838181548152602001915080548015612f2a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612ee0575b50509250505060405180910390a1505050565b6000600980549050905090565b600082821115612fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b600080831415612fe0576000905061304d565b6000828402905082848281612ff157fe5b0414613048576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806144f76021913960400191505060405180910390fd5b809150505b92915050565b60008082116130ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b8183816130d357fe5b04905092915050565b60008082840190508381101561315a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600033905090565b6131746119cd565b6131e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b60008060146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa613229613164565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561335e57600080fd5b505afa158015613372573d6000803e3d6000fd5b505050506040513d602081101561338857600080fd5b810190808051906020019092919050505010156133f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260438152602001806145476043913960600191505060405180910390fd5b60006133fa6127ba565b905080600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506134b87f0000000000000000000000000000000000000000000000000000000000000000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546130dc90919063ffffffff16565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018190555061353260017f0000000000000000000000000000000000000000000000000000000000000000612f4a90919063ffffffff16565b81141561367357600a339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506135b56001600a80549050612f4a90919063ffffffff16565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003018190555061361160016007546130dc90919063ffffffff16565b6007819055506001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160026101000a81548160ff0219169083151502179055505b6136a87f00000000000000000000000000000000000000000000000000000000000000006005546130dc90919063ffffffff16565b6005819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd33307f00000000000000000000000000000000000000000000000000000000000000006040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156137a957600080fd5b505af11580156137bd573d6000803e3d6000fd5b505050506040513d60208110156137d357600080fd5b8101908080519060200190929190505050613856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5472616e73666572206661696c6564000000000000000000000000000000000081525060200191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156138f557600080fd5b505afa158015613909573d6000803e3d6000fd5b505050506040513d602081101561391f57600080fd5b810190808051906020019092919050505090507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156139fb57600080fd5b505af1158015613a0f573d6000803e3d6000fd5b505050506040513d6020811015613a2557600080fd5b8101908080519060200190929190505050613a8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806144a56029913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8eda9df7f00000000000000000000000000000000000000000000000000000000000000008330609b6040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018261ffff168152602001945050505050600060405180830381600087803b158015613b9557600080fd5b505af1158015613ba9573d6000803e3d6000fd5b505050505050565b613bb9613164565b73ffffffffffffffffffffffffffffffffffffffff16613bd7611d07565b73ffffffffffffffffffffffffffffffffffffffff1614613c60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b613d276119cd565b15613d9a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613dde613164565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b6000613e2b6127ba565b14613e9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f47616d652068617320616c72656164792073746172746564000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141580613f875750600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff165b613fdc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806145ab6023913960400191505060405180910390fd5b613ff260016003546130dc90919063ffffffff16565b6003819055507f00000000000000000000000000000000000000000000000000000000000000006003541115614073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061436b6027913960400191505060405180910390fd5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff1690506140cf614311565b6040518060e001604052806000151581526020016000151581526020016000151581526020013373ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815250905080600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff02191690831515021790555060608201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151816001015560a0820151816002015560c0820151816003015590505081614297576009339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b3373ffffffffffffffffffffffffffffffffffffffff167f485fd86c2a7d2d9ca3bf02e2ba776ea24271bc62274265b0bd5f478b3b7a1ca47f00000000000000000000000000000000000000000000000000000000000000006040518082815260200191505060405180910390a261430d61326c565b5050565b6040518060e00160405280600015158152602001600015158152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152509056fe52656163686564206d6178207175616e74697479206f6620706c617965727320616c6c6f7765644661696c20746f207472616e7366657220455243323020746f6b656e73206f6e206561726c7920776974686472617752656465656d206f7065726174696f6e20616c72656164792068617070656e656420666f72207468652067616d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734661696c20746f207472616e73666572204552323020746f6b656e7320746f2061646d696e4465706f73697420617661696c61626c65206f6e6c79206265747765656e207365676d656e74203120616e64207365676d656e74206e2d31202870656e756c74696d6174652946756e6473206e6f742072656465656d65642066726f6d2065787465726e616c20706f6f6c4661696c20746f20617070726f766520616c6c6f77616e636520746f206c656e64696e6720706f6f6c4661696c20746f207472616e7366657220455243323020746f6b656e73206f6e207769746864726177536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774661696c20746f207472616e73666572204552323020696e63656e7469766520746f6b656e7320746f2061646d696e596f75206e65656420746f206861766520616c6c6f77616e636520746f20646f207472616e7366657220444149206f6e2074686520736d61727420636f6e7472616374506c6179657220616c72656164792077697468647261772066726f6d2067616d6543616e6e6f74206a6f696e207468652067616d65206d6f7265207468616e206f6e6365506c6179657220616c726561647920706169642063757272656e74207365676d656e744661696c20746f207472616e7366657220455243323020696e63656e7469766520746f6b656e73206f6e207769746864726177506c61796572206469646e277420706179207468652070726576696f7573207365676d656e74202d2067616d65206f76657221a264697066735822122083fae1a594582de23ccaaa1148cb2251932884cd0a6a5aa2a63f2ae5029c716464736f6c634300060b00335f637573746f6d466565206d757374206265206c657373207468616e206f7220657175616c20746f203230255f6d6178506c6179657273436f756e74206d7573742062652067726561746572207468616e207a65726f5f7365676d656e744c656e677468206d7573742062652067726561746572207468616e207a65726f5f6561726c795769746864726177616c466565206d7573742062652067726561746572207468616e207a65726f5f7365676d656e74436f756e74206d7573742062652067726561746572207468616e207a65726f5f7365676d656e745061796d656e74206d7573742062652067726561746572207468616e207a65726f5f6561726c795769746864726177616c466565206d757374206265206c657373207468616e206f7220657175616c20746f20313025696e76616c6964205f6c656e64696e67506f6f6c4164647265737350726f76696465722061646472657373000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a000000000000000000000000d1088091a174d33412a968fa34cb67131188b33200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043d067ed784d9dd2ffeda73775e2cc4c560103a1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102485760003560e01c80638da5cb5b1161013b578063d4f77b1c116100b8578063f2fde38b1161007c578063f2fde38b1461082b578063f4ceab1c1461086f578063f5c9786714610879578063f8dd5ad314610897578063fd6673f5146108a157610248565b8063d4f77b1c14610719578063e0236a1814610723578063e231bff01461072d578063e2eb41ff1461074f578063f18d20be1461080957610248565b8063aad739f5116100ff578063aad739f514610603578063be22f54614610671578063c39b583c146106bb578063caa02e08146106dd578063d013666e146106fb57610248565b80638da5cb5b1461049957806395224b33146104e3578063a2fb117514610501578063a59a99731461056f578063a98a5c94146105b957610248565b80635edafd5a116101c9578063715018a61161018d578063715018a6146104275780637a23032c146104315780637c80e6da1461044f5780637e5f84761461046d5780638456cb591461048f57610248565b80635edafd5a146103335780635faeea37146103575780636338030014610375578063638126f8146103bf5780636a79328a1461040957610248565b80633ccfd60b116102105780633ccfd60b146102d55780633e7433eb146102df5780633f4ba83a146102fd57806340732c89146103075780635c975abb1461031157610248565b80630c8ac6451461024d57806311b2e2d91461026b57806315d74bb31461028957806316330d4014610293578063250a2b0d146102b7575b600080fd5b6102556108bf565b6040518082815260200191505060405180910390f35b6102736108e3565b6040518082815260200191505060405180910390f35b610291610907565b005b61029b610f94565b604051808260ff1660ff16815260200191505060405180910390f35b6102bf610fb8565b6040518082815260200191505060405180910390f35b6102dd610fbe565b005b6102e76114b4565b6040518082815260200191505060405180910390f35b6103056114d8565b005b61030f61160b565b005b6103196119cd565b604051808215151515815260200191505060405180910390f35b61033b6119e3565b604051808260ff1660ff16815260200191505060405180910390f35b61035f611a07565b6040518082815260200191505060405180910390f35b61037d611a0d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103c7611a31565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610411611a55565b6040518082815260200191505060405180910390f35b61042f611a5b565b005b610439611b96565b6040518082815260200191505060405180910390f35b610457611b9c565b6040518082815260200191505060405180910390f35b610475611bc0565b604051808215151515815260200191505060405180910390f35b610497611bd3565b005b6104a1611d07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104eb611d30565b6040518082815260200191505060405180910390f35b61052d6004803603602081101561051757600080fd5b8101908080359060200190929190505050611d36565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610577611d72565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105c1611d98565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61062f6004803603602081101561061957600080fd5b8101908080359060200190929190505050611dbc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610679611df8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106c3611e1c565b604051808215151515815260200191505060405180910390f35b6106e5611e4d565b6040518082815260200191505060405180910390f35b610703611e53565b6040518082815260200191505060405180910390f35b610721611e77565b005b61072b611efc565b005b61073561244c565b604051808215151515815260200191505060405180910390f35b6107916004803603602081101561076557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061245f565b604051808815151515815260200187151515158152602001861515151581526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182815260200197505050505050505060405180910390f35b6108116124e8565b604051808215151515815260200191505060405180910390f35b61086d6004803603602081101561084157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506124fb565b005b6108776126ee565b005b6108816127ba565b6040518082815260200191505060405180910390f35b61089f612826565b005b6108a9612f3d565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000002386f26fc1000081565b7f000000000000000000000000000000000000000000000000000000000000000281565b61090f6119cd565b15610982576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b61098a611e1c565b156109fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f47616d6520697320616c726561647920636f6d706c657465640000000000000081525060200191505060405180910390fd5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816002015411610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f506c6179657220646f6573206e6f74206578697374000000000000000000000081525060200191505060405180910390fd5b8060000160009054906101000a900460ff1615610b3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f506c617965722068617320616c72656164792077697468647261776e0000000081525060200191505060405180910390fd5b60018160000160006101000a81548160ff021916908315150217905550610b726001600354612f4a90919063ffffffff16565b6003819055506000600754118015610b9857508060000160029054906101000a900460ff165b15610c3257610bb36001600754612f4a90919063ffffffff16565b60078190555060008160000160026101000a81548160ff0219169083151502179055506000600a826003015481548110610be957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6000610c97610c846064610c767f000000000000000000000000000000000000000000000000000000000000000160ff168660020154612fcd90919063ffffffff16565b61305390919063ffffffff16565b8360020154612f4a90919063ffffffff16565b9050610cb28260020154600554612f4a90919063ffffffff16565b6005819055506000610cc26127ba565b90506000811415610ceb5760018360000160016101000a81548160ff0219169083151502179055505b3373ffffffffffffffffffffffffffffffffffffffff167f1670585e36568ede58d159518ce92cad99f75ad41c7d8281df3dd4eaa0c855d083600554604051808381526020018281526020019250505060405180910390a2600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a84306040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b158015610e4057600080fd5b505af1158015610e54573d6000803e3d6000fd5b505050507f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610eff57600080fd5b505af1158015610f13573d6000803e3d6000fd5b505050506040513d6020811015610f2957600080fd5b8101908080519060200190929190505050610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614392602f913960400191505060405180910390fd5b505050565b7f000000000000000000000000000000000000000000000000000000000000000181565b60035481565b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600201541161107b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f506c6179657220646f6573206e6f74206578697374000000000000000000000081525060200191505060405180910390fd5b8060000160009054906101000a900460ff1615611100576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f506c617965722068617320616c72656164792077697468647261776e0000000081525060200191505060405180910390fd5b60018160000160006101000a81548160ff021916908315150217905550600060169054906101000a900460ff1661113a57611139612826565b5b600081600201549050600080905061117c60017f0000000000000000000000000000000000000000000000000000000000000002612f4a90919063ffffffff16565b836001015414156111d8576111b06111a160075460045461305390919063ffffffff16565b836130dc90919063ffffffff16565b9150600060025411156111d7576111d460075460025461305390919063ffffffff16565b90505b5b3373ffffffffffffffffffffffffffffffffffffffff167f650fdf669e93aa6c8ff3defe2da9c12b64f1548e5e1e54e803f4c1beb6466c8e8360008460405180848152602001838152602001828152602001935050505060405180910390a27f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156112de57600080fd5b505af11580156112f2573d6000803e3d6000fd5b505050506040513d602081101561130857600080fd5b810190808051906020019092919050505061136e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806144ce6029913960400191505060405180910390fd5b60008111156114af577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561141e57600080fd5b505af1158015611432573d6000803e3d6000fd5b505050506040513d602081101561144857600080fd5b81019080805190602001909291905050506114ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806145f16033913960400191505060405180910390fd5b5b505050565b7f0000000000000000000000000000000000000000000000000000000061b14cc981565b6114e0613164565b73ffffffffffffffffffffffffffffffffffffffff166114fe611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61158f6119cd565b611601576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b61160961316c565b565b6116136119cd565b15611686576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff1615611731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061458a6021913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168160000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146117f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f53656e646572206973206e6f74206120706c617965720000000000000000000081525060200191505060405180910390fd5b60006118006127ba565b905060008111801561183157507f000000000000000000000000000000000000000000000000000000000000000281105b611886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604681526020018061443a6046913960600191505060405180910390fd5b80826001015414156118e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806145ce6023913960400191505060405180910390fd5b6118f7600182612f4a90919063ffffffff16565b826001015414611952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806146246033913960400191505060405180910390fd5b803373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a157f000000000000000000000000000000000000000000000000002386f26fc100006040518082815260200191505060405180910390a36119c961326c565b5050565b60008060149054906101000a900460ff16905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055481565b7f000000000000000000000000d1088091a174d33412a968fa34cb67131188b33281565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025481565b611a63613164565b73ffffffffffffffffffffffffffffffffffffffff16611a81611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611b0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060159054906101000a900460ff16611b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f4e6f7420616c6c6f77656400000000000000000000000000000000000000000081525060200191505060405180910390fd5b611b94613bb1565b565b60065481565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b600060159054906101000a900460ff1681565b611bdb613164565b73ffffffffffffffffffffffffffffffffffffffff16611bf9611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c8a6119cd565b15611cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b611d05613d1f565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60045481565b600a8181548110611d4357fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000918146359264c492bd6934071c6bd31c854edbc381565b60098181548110611dc957fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a81565b60007f0000000000000000000000000000000000000000000000000000000000000002611e476127ba565b11905090565b60075481565b7f000000000000000000000000000000000000000000000000000000000000025881565b611e7f6119cd565b15611ef2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b611efa613e21565b565b611f04613164565b73ffffffffffffffffffffffffffffffffffffffff16611f22611d07565b73ffffffffffffffffffffffffffffffffffffffff1614611fab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611fb3611e1c565b612025576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f47616d65206973206e6f7420636f6d706c65746564000000000000000000000081525060200191505060405180910390fd5b600060169054906101000a900460ff1661208a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806144806025913960400191505060405180910390fd5b600060179054906101000a900460ff161561210d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f41646d696e2068617320616c72656164792077697468647261776e000000000081525060200191505060405180910390fd5b6001600060176101000a81548160ff0219169083151502179055506000809050600060075414801561214157506000600254115b1561214c5760025490505b612154611d07565b73ffffffffffffffffffffffffffffffffffffffff167f80ebcacc706983394bb8fcc88ea7b9241338fb4617fffbea411b68b40ed5627e6004546006548460405180848152602001838152602001828152602001935050505060405180910390a260006006541115612301577f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb612204611d07565b6006546040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561227057600080fd5b505af1158015612284573d6000803e3d6000fd5b505050506040513d602081101561229a57600080fd5b8101908080519060200190929190505050612300576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806144156025913960400191505060405180910390fd5b5b6000811115612449577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61234e611d07565b836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156123b857600080fd5b505af11580156123cc573d6000803e3d6000fd5b505050506040513d60208110156123e257600080fd5b8101908080519060200190929190505050612448576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614518602f913960400191505060405180910390fd5b5b50565b600060169054906101000a900460ff1681565b60086020528060005260406000206000915090508060000160009054906101000a900460ff16908060000160019054906101000a900460ff16908060000160029054906101000a900460ff16908060000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154905087565b600060179054906101000a900460ff1681565b612503613164565b73ffffffffffffffffffffffffffffffffffffffff16612521611d07565b73ffffffffffffffffffffffffffffffffffffffff16146125aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612630576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143ef6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6126f6613164565b73ffffffffffffffffffffffffffffffffffffffff16612714611d07565b73ffffffffffffffffffffffffffffffffffffffff161461279d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600060156101000a81548160ff021916908315150217905550565b60006128217f00000000000000000000000000000000000000000000000000000000000002586128137f0000000000000000000000000000000000000000000000000000000061b14cc942612f4a90919063ffffffff16565b61305390919063ffffffff16565b905090565b61282e611e1c565b6128a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f47616d65206973206e6f7420636f6d706c65746564000000000000000000000081525060200191505060405180910390fd5b600060169054906101000a900460ff1615612906576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806143c1602e913960400191505060405180910390fd5b6001600060166101000a81548160ff02191690831515021790555060007f000000000000000000000000918146359264c492bd6934071c6bd31c854edbc373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156129c057600080fd5b505afa1580156129d4573d6000803e3d6000fd5b505050506040513d60208110156129ea57600080fd5b81019080805190602001909291905050501115612b3757600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff306040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b158015612b1e57600080fd5b505af1158015612b32573d6000803e3d6000fd5b505050505b60007f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612bd657600080fd5b505afa158015612bea573d6000803e3d6000fd5b505050506040513d6020811015612c0057600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1614612d46577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612d0457600080fd5b505afa158015612d18573d6000803e3d6000fd5b505050506040513d6020811015612d2e57600080fd5b81019080805190602001909291905050506002819055505b6000809050600554821115612d6d57612d6a60055483612f4a90919063ffffffff16565b90505b6000807f000000000000000000000000000000000000000000000000000000000000000060ff161115612e0357612de36064612dd57f000000000000000000000000000000000000000000000000000000000000000060ff1685612fcd90919063ffffffff16565b61305390919063ffffffff16565b9050612df88183612f4a90919063ffffffff16565b600481905550612e0f565b60009050816004819055505b60006007541415612e265781600681905550612e2e565b806006819055505b7f28d72925fdcea205b246c820015bd35812a740d1ec1a5cdc84f7784b50940fbb836005546004546000600254604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a17fdbb9607e18553d40c255226e09883b48f92a108f6f895b0f37db6ae0d7fd56e6600a60405180806020018281038252838181548152602001915080548015612f2a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612ee0575b50509250505060405180910390a1505050565b6000600980549050905090565b600082821115612fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b600080831415612fe0576000905061304d565b6000828402905082848281612ff157fe5b0414613048576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806144f76021913960400191505060405180910390fd5b809150505b92915050565b60008082116130ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b8183816130d357fe5b04905092915050565b60008082840190508381101561315a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600033905090565b6131746119cd565b6131e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b60008060146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa613229613164565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b7f000000000000000000000000000000000000000000000000002386f26fc100007f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561335e57600080fd5b505afa158015613372573d6000803e3d6000fd5b505050506040513d602081101561338857600080fd5b810190808051906020019092919050505010156133f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260438152602001806145476043913960600191505060405180910390fd5b60006133fa6127ba565b905080600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506134b87f000000000000000000000000000000000000000000000000002386f26fc10000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546130dc90919063ffffffff16565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018190555061353260017f0000000000000000000000000000000000000000000000000000000000000002612f4a90919063ffffffff16565b81141561367357600a339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506135b56001600a80549050612f4a90919063ffffffff16565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003018190555061361160016007546130dc90919063ffffffff16565b6007819055506001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160026101000a81548160ff0219169083151502179055505b6136a87f000000000000000000000000000000000000000000000000002386f26fc100006005546130dc90919063ffffffff16565b6005819055507f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff166323b872dd33307f000000000000000000000000000000000000000000000000002386f26fc100006040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156137a957600080fd5b505af11580156137bd573d6000803e3d6000fd5b505050506040513d60208110156137d357600080fd5b8101908080519060200190929190505050613856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5472616e73666572206661696c6564000000000000000000000000000000000081525060200191505060405180910390fd5b60007f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156138f557600080fd5b505afa158015613909573d6000803e3d6000fd5b505050506040513d602081101561391f57600080fd5b810190808051906020019092919050505090507f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156139fb57600080fd5b505af1158015613a0f573d6000803e3d6000fd5b505050506040513d6020811015613a2557600080fd5b8101908080519060200190929190505050613a8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806144a56029913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8eda9df7f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a8330609b6040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018261ffff168152602001945050505050600060405180830381600087803b158015613b9557600080fd5b505af1158015613ba9573d6000803e3d6000fd5b505050505050565b613bb9613164565b73ffffffffffffffffffffffffffffffffffffffff16613bd7611d07565b73ffffffffffffffffffffffffffffffffffffffff1614613c60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b613d276119cd565b15613d9a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613dde613164565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b6000613e2b6127ba565b14613e9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f47616d652068617320616c72656164792073746172746564000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141580613f875750600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff165b613fdc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806145ab6023913960400191505060405180910390fd5b613ff260016003546130dc90919063ffffffff16565b6003819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6003541115614073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061436b6027913960400191505060405180910390fd5b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff1690506140cf614311565b6040518060e001604052806000151581526020016000151581526020016000151581526020013373ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815250905080600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff02191690831515021790555060608201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151816001015560a0820151816002015560c0820151816003015590505081614297576009339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b3373ffffffffffffffffffffffffffffffffffffffff167f485fd86c2a7d2d9ca3bf02e2ba776ea24271bc62274265b0bd5f478b3b7a1ca47f000000000000000000000000000000000000000000000000002386f26fc100006040518082815260200191505060405180910390a261430d61326c565b5050565b6040518060e00160405280600015158152602001600015158152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152509056fe52656163686564206d6178207175616e74697479206f6620706c617965727320616c6c6f7765644661696c20746f207472616e7366657220455243323020746f6b656e73206f6e206561726c7920776974686472617752656465656d206f7065726174696f6e20616c72656164792068617070656e656420666f72207468652067616d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734661696c20746f207472616e73666572204552323020746f6b656e7320746f2061646d696e4465706f73697420617661696c61626c65206f6e6c79206265747765656e207365676d656e74203120616e64207365676d656e74206e2d31202870656e756c74696d6174652946756e6473206e6f742072656465656d65642066726f6d2065787465726e616c20706f6f6c4661696c20746f20617070726f766520616c6c6f77616e636520746f206c656e64696e6720706f6f6c4661696c20746f207472616e7366657220455243323020746f6b656e73206f6e207769746864726177536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774661696c20746f207472616e73666572204552323020696e63656e7469766520746f6b656e7320746f2061646d696e596f75206e65656420746f206861766520616c6c6f77616e636520746f20646f207472616e7366657220444149206f6e2074686520736d61727420636f6e7472616374506c6179657220616c72656164792077697468647261772066726f6d2067616d6543616e6e6f74206a6f696e207468652067616d65206d6f7265207468616e206f6e6365506c6179657220616c726561647920706169642063757272656e74207365676d656e744661696c20746f207472616e7366657220455243323020696e63656e7469766520746f6b656e73206f6e207769746864726177506c61796572206469646e277420706179207468652070726576696f7573207365676d656e74202d2067616d65206f76657221a264697066735822122083fae1a594582de23ccaaa1148cb2251932884cd0a6a5aa2a63f2ae5029c716464736f6c634300060b0033