MATIC Price: $1.00 (-1.01%)
Gas: 61 GWei
 

Sponsored

Transaction Hash
Method
Block
From
To
Value
Withdraw405608492023-03-20 9:44:40374 days ago1679305480IN
0xE07601a3...4562337e4
0 MATIC0.00706413124.71541401
Transfer Ownersh...378719392023-01-09 18:21:19444 days ago1673288479IN
0xE07601a3...4562337e4
0 MATIC0.0016432957.25576128
Withdraw366264222022-12-09 17:27:45475 days ago1670606865IN
0xE07601a3...4562337e4
0 MATIC0.00581231102.61485521
Withdraw365594242022-12-08 1:56:35476 days ago1670464595IN
0xE07601a3...4562337e4
0 MATIC0.0021467337.90001432
Withdraw360714342022-11-26 1:26:18488 days ago1669425978IN
0xE07601a3...4562337e4
0 MATIC0.0028887451.00001795
Withdraw360236412022-11-24 21:47:12489 days ago1669326432IN
0xE07601a3...4562337e4
0 MATIC0.0017359330.64745807
Withdraw358823232022-11-21 11:19:46493 days ago1669029586IN
0xE07601a3...4562337e4
0 MATIC0.0025548345.10488817
Withdraw356484962022-11-15 19:01:53499 days ago1668538913IN
0xE07601a3...4562337e4
0 MATIC0.0040352961.82088675
Withdraw356198212022-11-15 2:13:01499 days ago1668478381IN
0xE07601a3...4562337e4
0 MATIC0.002832150.00000002
Withdraw355521732022-11-13 11:08:23501 days ago1668337703IN
0xE07601a3...4562337e4
0 MATIC0.002286535.02927849
Withdraw354268142022-11-10 6:35:58504 days ago1668062158IN
0xE07601a3...4562337e4
0 MATIC0.01132929153.63427649
Withdraw354132432022-11-09 22:47:31504 days ago1668034051IN
0xE07601a3...4562337e4
0 MATIC0.00583412103
Withdraw353882422022-11-09 8:13:06505 days ago1667981586IN
0xE07601a3...4562337e4
0 MATIC0.00796342122
Withdraw352807362022-11-06 17:16:28508 days ago1667754988IN
0xE07601a3...4562337e4
0 MATIC0.00709277125.22111705
Withdraw352710772022-11-06 11:44:15508 days ago1667735055IN
0xE07601a3...4562337e4
0 MATIC0.0065274100
Withdraw352710472022-11-06 11:43:15508 days ago1667734995IN
0xE07601a3...4562337e4
0 MATIC0.0065274100
Withdraw352710252022-11-06 11:42:27508 days ago1667734947IN
0xE07601a3...4562337e4
0 MATIC0.00848562130
Withdraw352710002022-11-06 11:41:37508 days ago1667734897IN
0xE07601a3...4562337e4
0 MATIC0.01109658170
Withdraw352709692022-11-06 11:40:31508 days ago1667734831IN
0xE07601a3...4562337e4
0 MATIC0.0089932137.77618319
Withdraw352709392022-11-06 11:39:31508 days ago1667734771IN
0xE07601a3...4562337e4
0 MATIC0.00724541111
Withdraw352708882022-11-06 11:37:45508 days ago1667734665IN
0xE07601a3...4562337e4
0 MATIC0.00783288120
Withdraw352708552022-11-06 11:36:39508 days ago1667734599IN
0xE07601a3...4562337e4
0 MATIC0.00839264128.57565066
Withdraw352708402022-11-06 11:36:05508 days ago1667734565IN
0xE07601a3...4562337e4
0 MATIC0.00825779126.50968411
Withdraw352707112022-11-06 11:31:39508 days ago1667734299IN
0xE07601a3...4562337e4
0 MATIC0.0097911150
Withdraw352702352022-11-06 11:15:17508 days ago1667733317IN
0xE07601a3...4562337e4
0 MATIC0.01077021165
View all transactions

Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x34962DF6...D6e874d2b
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
GoodGhostingPolygon

Compiler Version
v0.6.11+commit.5ef660b1

Optimization Enabled:
Yes with 1500 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2022-04-19
*/

// File: @openzeppelin/contracts/math/SafeMath.sol



pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol



pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: contracts/aave/ILendingPoolAddressesProvider.sol



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;

}

// File: contracts/aave/ILendingPool.sol



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);
}

// File: contracts/aave/AToken.sol



pragma solidity 0.6.11;

interface AToken {
    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);
}

// File: contracts/aave/IncentiveController.sol



pragma solidity 0.6.11;

interface IncentiveController {
  function getRewardsBalance(address[] calldata assets, address user) external view returns(uint256);

  function claimRewards(
    address[] calldata assets,
    uint256 amount,
    address to
    ) external returns (uint256);
}

// File: @openzeppelin/contracts/utils/Context.sol



pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol



pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: @openzeppelin/contracts/utils/Pausable.sol



pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor () internal {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: contracts/GoodGhosting.sol



pragma solidity 0.6.11;







/// @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();
    }
}

// File: contracts/GoodGhostingPolygon.sol



pragma solidity 0.6.11;







/// @title GoodGhosting Game Contract
/// @author Francis Odisi & Viraz Malhotra
/// @notice Used for the games deployed on Polygon using Aave as the underlying external pool.
contract GoodGhostingPolygon is GoodGhosting {
    IncentiveController public incentiveController;
    IERC20 public immutable matic;
    uint256 public rewardsPerPlayer;

    /**
        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%). Does not accept "decimal" fees like "0.5".
        @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.
        @param _incentiveController matic reward claim contract.
        @param _matic matic token address.
     */
    constructor(
        IERC20 _inboundCurrency,
        ILendingPoolAddressesProvider _lendingPoolAddressProvider,
        uint256 _segmentCount,
        uint256 _segmentLength,
        uint256 _segmentPayment,
        uint8 _earlyWithdrawalFee,
        uint8 _customFee,
        address _dataProvider,
        uint256 _maxPlayersCount,
        IERC20 _incentiveToken,
        address _incentiveController,
        IERC20 _matic
    )
        public
        GoodGhosting(
            _inboundCurrency,
            _lendingPoolAddressProvider,
            _segmentCount,
            _segmentLength,
            _segmentPayment,
            _earlyWithdrawalFee,
            _customFee,
            _dataProvider,
            _maxPlayersCount,
            _incentiveToken
        )
    {
        require(_incentiveController != address(0), "invalid _incentiveController address");
        require(address(_matic) != address(0), "invalid _matic address");
        // initializing incentiveController contract
        incentiveController = IncentiveController(_incentiveController);
        matic = _matic;
    }

    /// @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
        override
        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"
            );
        }

        if (rewardsPerPlayer == 0) {
            uint256 balance = IERC20(matic).balanceOf(address(this));
            require(
                IERC20(matic).transfer(owner(), balance),
                "Fail to transfer ERC20 rewards tokens to admin"
            );
        }
    }

    /// @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 override {
        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;
        uint256 playerReward = 0;
        if (player.mostRecentSegmentPaid == lastSegment.sub(1)) {
            // Player is a winner and gets a bonus!
            payout = payout.add(totalGameInterest.div(winnerCount));
            playerReward = rewardsPerPlayer;
            // If there's additional incentives, distributes them to winners
            if (totalIncentiveAmount > 0) {
                playerIncentive = totalIncentiveAmount.div(winnerCount);
            }
        }
        emit Withdrawal(msg.sender, payout, playerReward, 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"
            );
        }

        if (playerReward > 0) {
            require(
                IERC20(matic).transfer(msg.sender, playerReward),
                "Fail to transfer ERC20 rewards on withdraw"
            );
        }
    }

    /// @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 override 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)
            );
            // Claims the rewards from the external pool
            address[] memory assets = new address[](1);
            assets[0] = address(adaiToken);
            uint256 claimableRewards = incentiveController.getRewardsBalance(
                assets,
                address(this)
            );
            if (claimableRewards > 0) {
                incentiveController.claimRewards(
                    assets,
                    claimableRewards,
                    address(this)
                );
            }
        }

        uint256 totalBalance = IERC20(daiToken).balanceOf(address(this));
        uint256 rewardsAmount = IERC20(matic).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) {
            rewardsPerPlayer = 0;
            adminFeeAmount = grossInterest;
        } else {
            rewardsPerPlayer = rewardsAmount.div(winnerCount);
            adminFeeAmount = _adminFeeAmount;
        }

        emit FundsRedeemedFromExternalPool(
            totalBalance,
            totalGamePrincipal,
            totalGameInterest,
            rewardsAmount,
            totalIncentiveAmount
        );
        emit WinnersAnnouncement(winners);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"_inboundCurrency","type":"address"},{"internalType":"contract ILendingPoolAddressesProvider","name":"_lendingPoolAddressProvider","type":"address"},{"internalType":"uint256","name":"_segmentCount","type":"uint256"},{"internalType":"uint256","name":"_segmentLength","type":"uint256"},{"internalType":"uint256","name":"_segmentPayment","type":"uint256"},{"internalType":"uint8","name":"_earlyWithdrawalFee","type":"uint8"},{"internalType":"uint8","name":"_customFee","type":"uint8"},{"internalType":"address","name":"_dataProvider","type":"address"},{"internalType":"uint256","name":"_maxPlayersCount","type":"uint256"},{"internalType":"contract IERC20","name":"_incentiveToken","type":"address"},{"internalType":"address","name":"_incentiveController","type":"address"},{"internalType":"contract IERC20","name":"_matic","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalGameInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"adminFeeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"adminIncentiveAmount","type":"uint256"}],"name":"AdminWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":true,"internalType":"uint256","name":"segment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalGamePrincipal","type":"uint256"}],"name":"EarlyWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalGamePrincipal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalGameInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalIncentiveAmount","type":"uint256"}],"name":"FundsRedeemedFromExternalPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"JoinedGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"winners","type":"address[]"}],"name":"WinnersAnnouncement","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"playerReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"playerIncentive","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"activePlayersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adaiToken","outputs":[{"internalType":"contract AToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminFeeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminFeeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adminWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowRenouncingOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"customFee","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daiToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earlyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyWithdrawalFee","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"firstSegmentStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSegment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfPlayers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveController","outputs":[{"internalType":"contract IncentiveController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isGameCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"iterablePlayers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"joinGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastSegment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lendingPool","outputs":[{"internalType":"contract ILendingPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lendingPoolAddressProvider","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"makeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"matic","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPlayersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"players","outputs":[{"internalType":"bool","name":"withdrawn","type":"bool"},{"internalType":"bool","name":"canRejoin","type":"bool"},{"internalType":"bool","name":"isWinner","type":"bool"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"mostRecentSegmentPaid","type":"uint256"},{"internalType":"uint256","name":"amountPaid","type":"uint256"},{"internalType":"uint256","name":"winnerIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemFromExternalPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsPerPlayer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"segmentLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"segmentPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGameInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGamePrincipal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalIncentiveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockRenounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"winnerCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102e95760003560e01c80638da5cb5b11610191578063d30858f1116100e3578063f18d20be11610097578063f5c9786711610071578063f5c9786714610530578063f8dd5ad314610538578063fd6673f514610540576102e9565b8063f18d20be146104fa578063f2fde38b14610502578063f4ceab1c14610528576102e9565b8063e0236a18116100c8578063e0236a1814610482578063e231bff01461048a578063e2eb41ff14610492576102e9565b8063d30858f114610472578063d4f77b1c1461047a576102e9565b8063aad739f511610145578063c39b583c1161011f578063c39b583c1461045a578063caa02e0814610462578063d013666e1461046a576102e9565b8063aad739f51461042d578063b6b0b0971461044a578063be22f54614610452576102e9565b8063a2fb117511610176578063a2fb117514610400578063a59a99731461041d578063a98a5c9414610425576102e9565b80638da5cb5b146103f057806395224b33146103f8576102e9565b80635c975abb1161024a5780636a79328a116101fe5780637c80e6da116101d85780637c80e6da146103d85780637e5f8476146103e05780638456cb59146103e8576102e9565b80636a79328a146103c0578063715018a6146103c85780637a23032c146103d0576102e9565b80635faeea371161022f5780635faeea37146103a857806363380300146103b0578063638126f8146103b8576102e9565b80635c975abb146103845780635edafd5a146103a0576102e9565b80633ccfd60b116102a15780633f4ba83a116102865780633f4ba83a1461035057806340732c89146103585780635b9fe37f14610360576102e9565b80633ccfd60b146103405780633e7433eb14610348576102e9565b806315d74bb3116102d257806315d74bb31461031057806316330d401461031a578063250a2b0d14610338576102e9565b80630c8ac645146102ee57806311b2e2d914610308575b600080fd5b6102f6610548565b60408051918252519081900360200190f35b6102f661056c565b610318610590565b005b6103226109e2565b6040805160ff9092168252519081900360200190f35b6102f6610a06565b610318610a0c565b6102f6610e56565b610318610e7a565b610318610f51565b6103686111c1565b604080516001600160a01b039092168252519081900360200190f35b61038c6111d0565b604080519115158252519081900360200190f35b6103226111f1565b6102f6611215565b61036861121b565b61036861123f565b6102f6611263565b610318611269565b6102f6611343565b6102f6611349565b61038c61136d565b61031861137d565b610368611446565b6102f6611455565b6103686004803603602081101561041657600080fd5b503561145b565b610368611482565b610368611491565b6103686004803603602081101561044357600080fd5b50356114b5565b6103686114c2565b6103686114e6565b61038c61150a565b6102f661153b565b6102f6611541565b6102f6611565565b61031861156b565b6103186115c0565b61038c611b56565b6104b8600480360360208110156104a857600080fd5b50356001600160a01b0316611b66565b6040805197151588529515156020880152931515868601526001600160a01b039092166060860152608085015260a084015260c0830152519081900360e00190f35b61038c611bb3565b6103186004803603602081101561051857600080fd5b50356001600160a01b0316611bc3565b610318611ce4565b6102f6611d88565b610318611de3565b6102f66125b6565b7f0000000000000000000000000000000000000000000000004563918244f4000081565b7f000000000000000000000000000000000000000000000000000000000000000481565b6105986111d0565b156105dd576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6105e561150a565b15610637576040805162461bcd60e51b815260206004820152601960248201527f47616d6520697320616c726561647920636f6d706c6574656400000000000000604482015290519081900360640190fd5b336000908152600860205260409020600281015461069c576040805162461bcd60e51b815260206004820152601560248201527f506c6179657220646f6573206e6f742065786973740000000000000000000000604482015290519081900360640190fd5b805460ff16156106f3576040805162461bcd60e51b815260206004820152601c60248201527f506c617965722068617320616c72656164792077697468647261776e00000000604482015290519081900360640190fd5b805460ff1916600190811782556003546107129163ffffffff6125bc16565b6003556007541580159061072d5750805462010000900460ff165b156107975760075461074690600163ffffffff6125bc16565b600755805462ff0000191681556003810154600a805460009290811061076857fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b60006107f86107e760646107db7f000000000000000000000000000000000000000000000000000000000000000560ff16866002015461261e90919063ffffffff16565b9063ffffffff61267e16565b60028401549063ffffffff6125bc16565b905061081382600201546005546125bc90919063ffffffff16565b6005556000610820611d88565b90508061083557825461ff0019166101001783555b600554604080518481526020810192909252805133927f1670585e36568ede58d159518ce92cad99f75ad41c7d8281df3dd4eaa0c855d092908290030190a260015460408051631a4ca37b60e21b81526001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0638116600483015260248201869052306044830152915191909216916369328dec91606480830192600092919082900301818387803b1580156108ef57600080fd5b505af1158015610903573d6000803e3d6000fd5b50506040805163a9059cbb60e01b81523360048201526024810186905290516001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a06316935063a9059cbb925060448083019260209291908290030181600087803b15801561097657600080fd5b505af115801561098a573d6000803e3d6000fd5b505050506040513d60208110156109a057600080fd5b50516109dd5760405162461bcd60e51b815260040180806020018281038252602f8152602001806132e9602f913960400191505060405180910390fd5b505050565b7f000000000000000000000000000000000000000000000000000000000000000581565b60035481565b3360009081526008602052604090206002810154610a71576040805162461bcd60e51b815260206004820152601560248201527f506c6179657220646f6573206e6f742065786973740000000000000000000000604482015290519081900360640190fd5b805460ff1615610ac8576040805162461bcd60e51b815260206004820152601c60248201527f506c617965722068617320616c72656164792077697468647261776e00000000604482015290519081900360640190fd5b805460ff19166001178155600054600160b01b900460ff16610aec57610aec611de3565b6002810154600080610b257f0000000000000000000000000000000000000000000000000000000000000004600163ffffffff6125bc16565b84600101541415610b7f57610b57610b4a60075460045461267e90919063ffffffff16565b849063ffffffff6126e516565b600c54600254919450915015610b7f57600754600254610b7c9163ffffffff61267e16565b91505b6040805184815260208101839052808201849052905133917f650fdf669e93aa6c8ff3defe2da9c12b64f1548e5e1e54e803f4c1beb6466c8e919081900360600190a26040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063169163a9059cbb9160448083019260209291908290030181600087803b158015610c3157600080fd5b505af1158015610c45573d6000803e3d6000fd5b505050506040513d6020811015610c5b57600080fd5b5051610c985760405162461bcd60e51b81526004018080602001828103825260298152602001806134256029913960400191505060405180910390fd5b8115610d74576040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163a9059cbb9160448083019260209291908290030181600087803b158015610d0d57600080fd5b505af1158015610d21573d6000803e3d6000fd5b505050506040513d6020811015610d3757600080fd5b5051610d745760405162461bcd60e51b81526004018080602001828103825260338152602001806135a06033913960400191505060405180910390fd5b8015610e50576040805163a9059cbb60e01b81523360048201526024810183905290516001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270169163a9059cbb9160448083019260209291908290030181600087803b158015610de957600080fd5b505af1158015610dfd573d6000803e3d6000fd5b505050506040513d6020811015610e1357600080fd5b5051610e505760405162461bcd60e51b815260040180806020018281038252602a81526020018061346f602a913960400191505060405180910390fd5b50505050565b7f0000000000000000000000000000000000000000000000000000000063287eb481565b610e8261273f565b6001600160a01b0316610e93611446565b6001600160a01b031614610eee576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610ef66111d0565b610f47576040805162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015290519081900360640190fd5b610f4f612743565b565b610f596111d0565b15610f9e576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b336000908152600860205260409020805460ff1615610fee5760405162461bcd60e51b81526004018080602001828103825260218152602001806135396021913960400191505060405180910390fd5b8054630100000090046001600160a01b03163314611053576040805162461bcd60e51b815260206004820152601660248201527f53656e646572206973206e6f74206120706c6179657200000000000000000000604482015290519081900360640190fd5b600061105d611d88565b905060008111801561108e57507f000000000000000000000000000000000000000000000000000000000000000481105b6110c95760405162461bcd60e51b81526004018080602001828103825260468152602001806133916046913960600191505060405180910390fd5b808260010154141561110c5760405162461bcd60e51b815260040180806020018281038252602381526020018061357d6023913960400191505060405180910390fd5b61111d81600163ffffffff6125bc16565b82600101541461115e5760405162461bcd60e51b81526004018080602001828103825260338152602001806135d36033913960400191505060405180910390fd5b604080517f0000000000000000000000000000000000000000000000004563918244f4000081529051829133917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159181900360200190a36111bd61280a565b5050565b600b546001600160a01b031681565b60005474010000000000000000000000000000000000000000900460ff1690565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055481565b7f000000000000000000000000d05e3e715d945b59290df0ae8ef85c1bdb68474481565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025481565b61127161273f565b6001600160a01b0316611282611446565b6001600160a01b0316146112dd576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600054600160a81b900460ff1661133b576040805162461bcd60e51b815260206004820152600b60248201527f4e6f7420616c6c6f776564000000000000000000000000000000000000000000604482015290519081900360640190fd5b610f4f612e0f565b60065481565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b600054600160a81b900460ff1681565b61138561273f565b6001600160a01b0316611396611446565b6001600160a01b0316146113f1576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6113f96111d0565b1561143e576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b610f4f612eda565b6000546001600160a01b031690565b60045481565b600a818154811061146857fe5b6000918252602090912001546001600160a01b0316905081565b6001546001600160a01b031681565b7f00000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6e81565b6009818154811061146857fe5b7f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127081565b7f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a06381565b60007f0000000000000000000000000000000000000000000000000000000000000004611535611d88565b11905090565b60075481565b7f0000000000000000000000000000000000000000000000000000000000093a8081565b600c5481565b6115736111d0565b156115b8576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b610f4f612f8f565b6115c861273f565b6001600160a01b03166115d9611446565b6001600160a01b031614611634576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61163c61150a565b61168d576040805162461bcd60e51b815260206004820152601560248201527f47616d65206973206e6f7420636f6d706c657465640000000000000000000000604482015290519081900360640190fd5b600054600160b01b900460ff166116d55760405162461bcd60e51b81526004018080602001828103825260258152602001806133d76025913960400191505060405180910390fd5b600054600160b81b900460ff1615611734576040805162461bcd60e51b815260206004820152601b60248201527f41646d696e2068617320616c72656164792077697468647261776e0000000000604482015290519081900360640190fd5b600080547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16600160b81b17815560075415801561177457506000600254115b1561177e57506002545b611786611446565b6001600160a01b03167f80ebcacc706983394bb8fcc88ea7b9241338fb4617fffbea411b68b40ed5627e6004546006548460405180848152602001838152602001828152602001935050505060405180910390a2600654156118d2577f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0636001600160a01b031663a9059cbb611819611446565b6006546040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561186b57600080fd5b505af115801561187f573d6000803e3d6000fd5b505050506040513d602081101561189557600080fd5b50516118d25760405162461bcd60e51b815260040180806020018281038252602581526020018061336c6025913960400191505060405180910390fd5b80156119c6577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb61190f611446565b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561195f57600080fd5b505af1158015611973573d6000803e3d6000fd5b505050506040513d602081101561198957600080fd5b50516119c65760405162461bcd60e51b815260040180806020018281038252602f815260200180613499602f913960400191505060405180910390fd5b600c54611b5357604080516370a0823160e01b815230600482015290516000916001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127016916370a0823191602480820192602092909190829003018186803b158015611a3757600080fd5b505afa158015611a4b573d6000803e3d6000fd5b505050506040513d6020811015611a6157600080fd5b505190506001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12701663a9059cbb611a9c611446565b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611aec57600080fd5b505af1158015611b00573d6000803e3d6000fd5b505050506040513d6020811015611b1657600080fd5b50516111bd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806134c8602e913960400191505060405180910390fd5b50565b600054600160b01b900460ff1681565b600860205260009081526040902080546001820154600283015460039093015460ff8084169461010085048216946201000081049092169363010000009092046001600160a01b03169287565b600054600160b81b900460ff1681565b611bcb61273f565b6001600160a01b0316611bdc611446565b6001600160a01b031614611c37576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116611c7c5760405162461bcd60e51b81526004018080602001828103825260268152602001806133466026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b611cec61273f565b6001600160a01b0316611cfd611446565b6001600160a01b031614611d58576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b179055565b6000611dde7f0000000000000000000000000000000000000000000000000000000000093a806107db427f0000000000000000000000000000000000000000000000000000000063287eb463ffffffff6125bc16565b905090565b611deb61150a565b611e3c576040805162461bcd60e51b815260206004820152601560248201527f47616d65206973206e6f7420636f6d706c657465640000000000000000000000604482015290519081900360640190fd5b600054600160b01b900460ff1615611e855760405162461bcd60e51b815260040180806020018281038252602e815260200180613318602e913960400191505060405180910390fd5b600080547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff16600160b01b178155604080516370a0823160e01b815230600482015290516001600160a01b037f00000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6e16916370a08231916024808301926020929190829003018186803b158015611f1957600080fd5b505afa158015611f2d573d6000803e3d6000fd5b505050506040513d6020811015611f4357600080fd5b505111156122085760015460408051631a4ca37b60e21b81526001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063811660048301526000196024830152306044830152915191909216916369328dec91606480830192600092919082900301818387803b158015611fc757600080fd5b505af1158015611fdb573d6000803e3d6000fd5b5050604080516001808252818301909252606093509150602080830190803683370190505090507f00000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6e8160008151811061203057fe5b6001600160a01b03928316602091820292909201810191909152600b54604080517f8b599f260000000000000000000000000000000000000000000000000000000081523060248201819052600482019283528651604483015286516000969490941694638b599f269488949293839260649091019186820191028083838c5b838110156120c85781810151838201526020016120b0565b50505050905001935050505060206040518083038186803b1580156120ec57600080fd5b505afa158015612100573d6000803e3d6000fd5b505050506040513d602081101561211657600080fd5b50519050801561220557600b546040517f3111e7b30000000000000000000000000000000000000000000000000000000081526024810183905230604482018190526060600483019081528551606484015285516001600160a01b0390941693633111e7b393879387939092909182916084909101906020808801910280838360005b838110156121b1578181015183820152602001612199565b50505050905001945050505050602060405180830381600087803b1580156121d857600080fd5b505af11580156121ec573d6000803e3d6000fd5b505050506040513d602081101561220257600080fd5b50505b50505b604080516370a0823160e01b815230600482015290516000916001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a06316916370a0823191602480820192602092909190829003018186803b15801561227257600080fd5b505afa158015612286573d6000803e3d6000fd5b505050506040513d602081101561229c57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127016916370a08231916024808301926020929190829003018186803b15801561230a57600080fd5b505afa15801561231e573d6000803e3d6000fd5b505050506040513d602081101561233457600080fd5b505190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156123fd57604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b1580156123cd57600080fd5b505afa1580156123e1573d6000803e3d6000fd5b505050506040513d60208110156123f757600080fd5b50516002555b6005546000908311156124215760055461241e90849063ffffffff6125bc16565b90505b600060ff7f0000000000000000000000000000000000000000000000000000000000000000161561249e5761248460646107db8460ff7f00000000000000000000000000000000000000000000000000000000000000001663ffffffff61261e16565b9050612496828263ffffffff6125bc16565b6004556124a7565b50600481905560005b6007546124bd576000600c5560068290556124da565b6007546124d190849063ffffffff61267e16565b600c5560068190555b60055460045460025460408051888152602081019490945283810192909252606083018690526080830152517f28d72925fdcea205b246c820015bd35812a740d1ec1a5cdc84f7784b50940fbb9181900360a00190a17fdbb9607e18553d40c255226e09883b48f92a108f6f895b0f37db6ae0d7fd56e6600a604051808060200182810382528381815481526020019150805480156125a257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612584575b50509250505060405180910390a150505050565b60095490565b600082821115612613576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b60008261262d57506000612618565b8282028284828161263a57fe5b04146126775760405162461bcd60e51b815260040180806020018281038252602181526020018061344e6021913960400191505060405180910390fd5b9392505050565b60008082116126d4576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816126dd57fe5b049392505050565b600082820183811015612677576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b61274b6111d0565b61279c576040805162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6127ed61273f565b604080516001600160a01b039092168252519081900360200190a1565b604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290517f0000000000000000000000000000000000000000000000004563918244f40000916001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063169163dd62ed3e91604480820192602092909190829003018186803b1580156128b257600080fd5b505afa1580156128c6573d6000803e3d6000fd5b505050506040513d60208110156128dc57600080fd5b5051101561291b5760405162461bcd60e51b81526004018080602001828103825260438152602001806134f66043913960600191505060405180910390fd5b6000612925611d88565b3360009081526008602052604090206001810182905560020154909150612972907f0000000000000000000000000000000000000000000000004563918244f4000063ffffffff6126e516565b336000908152600860205260409020600201556129b67f0000000000000000000000000000000000000000000000000000000000000004600163ffffffff6125bc16565b811415612a6857600a80546001818101835560008390527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8909101805473ffffffffffffffffffffffffffffffffffffffff1916331790559054612a1f9163ffffffff6125bc16565b33600090815260086020526040902060030155600754612a4690600163ffffffff6126e516565b600755336000908152600860205260409020805462ff00001916620100001790555b600554612a9b907f0000000000000000000000000000000000000000000000004563918244f4000063ffffffff6126e516565b600555604080517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201527f0000000000000000000000000000000000000000000000004563918244f40000604482015290516001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a06316916323b872dd9160648083019260209291908290030181600087803b158015612b4b57600080fd5b505af1158015612b5f573d6000803e3d6000fd5b505050506040513d6020811015612b7557600080fd5b5051612bc8576040805162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a06316916370a0823191602480820192602092909190829003018186803b158015612c3257600080fd5b505afa158015612c46573d6000803e3d6000fd5b505050506040513d6020811015612c5c57600080fd5b5051600154604080517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0392831660048201526024810184905290519293507f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0639091169163095ea7b3916044808201926020929091908290030181600087803b158015612cf157600080fd5b505af1158015612d05573d6000803e3d6000fd5b505050506040513d6020811015612d1b57600080fd5b5051612d585760405162461bcd60e51b81526004018080602001828103825260298152602001806133fc6029913960400191505060405180910390fd5b600154604080517fe8eda9df0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0638116600483015260248201859052306044830152609b60648301529151919092169163e8eda9df91608480830192600092919082900301818387803b158015612df357600080fd5b505af1158015612e07573d6000803e3d6000fd5b505050505050565b612e1761273f565b6001600160a01b0316612e28611446565b6001600160a01b031614612e83576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b612ee26111d0565b15612f27576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586127ed61273f565b612f97611d88565b15612fe9576040805162461bcd60e51b815260206004820152601860248201527f47616d652068617320616c726561647920737461727465640000000000000000604482015290519081900360640190fd5b33600081815260086020526040902054630100000090046001600160a01b031614158061302a575033600090815260086020526040902054610100900460ff165b6130655760405162461bcd60e51b815260040180806020018281038252602381526020018061355a6023913960400191505060405180910390fd5b60035461307990600163ffffffff6126e516565b60038190557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff10156130dc5760405162461bcd60e51b81526004018080602001828103825260278152602001806132c26027913960400191505060405180910390fd5b33600090815260086020526040902054610100900460ff166130fc613285565b506040805160e0810182526000808252602080830182815283850183815233606086018181526080870186815260a0880187815260c089018881529388526008909652979095208651815494519351965160ff199095169015151761ff001916610100931515939093029290921762ff000019166201000095151595909502949094177fffffffffffffffffff0000000000000000000000000000000000000000ffffff1663010000006001600160a01b039093169290920291909117815593516001850155516002840155516003909201919091558161322757600980546001810182556000919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af01805473ffffffffffffffffffffffffffffffffffffffff1916331790555b604080517f0000000000000000000000000000000000000000000000004563918244f400008152905133917f485fd86c2a7d2d9ca3bf02e2ba776ea24271bc62274265b0bd5f478b3b7a1ca4919081900360200190a26111bd61280a565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091529056fe52656163686564206d6178207175616e74697479206f6620706c617965727320616c6c6f7765644661696c20746f207472616e7366657220455243323020746f6b656e73206f6e206561726c7920776974686472617752656465656d206f7065726174696f6e20616c72656164792068617070656e656420666f72207468652067616d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734661696c20746f207472616e73666572204552323020746f6b656e7320746f2061646d696e4465706f73697420617661696c61626c65206f6e6c79206265747765656e207365676d656e74203120616e64207365676d656e74206e2d31202870656e756c74696d6174652946756e6473206e6f742072656465656d65642066726f6d2065787465726e616c20706f6f6c4661696c20746f20617070726f766520616c6c6f77616e636520746f206c656e64696e6720706f6f6c4661696c20746f207472616e7366657220455243323020746f6b656e73206f6e207769746864726177536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774661696c20746f207472616e736665722045524332302072657761726473206f6e2077697468647261774661696c20746f207472616e73666572204552323020696e63656e7469766520746f6b656e7320746f2061646d696e4661696c20746f207472616e73666572204552433230207265776172647320746f6b656e7320746f2061646d696e596f75206e65656420746f206861766520616c6c6f77616e636520746f20646f207472616e7366657220444149206f6e2074686520736d61727420636f6e7472616374506c6179657220616c72656164792077697468647261772066726f6d2067616d6543616e6e6f74206a6f696e207468652067616d65206d6f7265207468616e206f6e6365506c6179657220616c726561647920706169642063757272656e74207365676d656e744661696c20746f207472616e7366657220455243323020696e63656e7469766520746f6b656e73206f6e207769746864726177506c61796572206469646e277420706179207468652070726576696f7573207365676d656e74202d2067616d65206f76657221a264697066735822122023dd27563e18c20ee4b70bd09c2ee1138236b68e9dba0b1e0dcd7bd0e3d4d4e464736f6c634300060b0033

Deployed Bytecode Sourcemap

41064:9420:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21183:39;;;:::i;:::-;;;;;;;;;;;;;;;;21297:36;;;:::i;29751:1531::-;;;:::i;:::-;;21825:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;20787:37;;;:::i;45598:1664::-;;;:::i;21400:42::-;;;:::i;27636:78::-;;;:::i;32891:1659::-;;;:::i;41116:46::-;;;:::i;:::-;;;;-1:-1:-1;;;;;41116:46:0;;;;;;;;;;;;;;17940:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;21929:32;;;:::i;20989:33::-;;;:::i;20197:73::-;;;:::i;20507:38::-;;;:::i;20636:39::-;;;:::i;27760:158::-;;;:::i;21092:29::-;;;:::i;21631:40::-;;;:::i;19583:44::-;;;:::i;27457:77::-;;;:::i;15648:87::-;;;:::i;20910:32::-;;;:::i;22532:24::-;;;;;;;;;;;;;;;;-1:-1:-1;22532:24:0;;:::i;20315:31::-;;;:::i;20076:33::-;;;:::i;22460:32::-;;;;;;;;;;;;;;;;-1:-1:-1;22460:32:0;;:::i;41169:29::-;;;:::i;19925:32::-;;;:::i;37628:211::-;;;:::i;21733:30::-;;;:::i;21513:38::-;;;:::i;41205:31::-;;;:::i;29461:113::-;;;:::i;43996:1455::-;;;:::i;19705:20::-;;;:::i;22255:41::-;;;;;;;;;;;;;;;;-1:-1:-1;22255:41:0;-1:-1:-1;;;;;22255:41:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22255:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;19804:25;;;:::i;16602:244::-;;;;;;;;;;;;;;;;-1:-1:-1;16602:244:0;-1:-1:-1;;;;;16602:244:0;;:::i;27970:104::-;;;:::i;37361:142::-;;;:::i;47458:3023::-;;;:::i;34649:110::-;;;:::i;21183:39::-;;;:::o;21297:36::-;;;:::o;29751:1531::-;18266:8;:6;:8::i;:::-;18265:9;18257:38;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;;;;23650:17:::1;:15;:17::i;:::-;23649:18;23641:56;;;::::0;;-1:-1:-1;;;23641:56:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;29865:10:::2;29833:21;29857:19:::0;;;:7:::2;:19;::::0;;;;29895:17:::2;::::0;::::2;::::0;29887:55:::2;;;::::0;;-1:-1:-1;;;29887:55:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;29962:16:::0;;::::2;;29961:17;29953:58;;;::::0;;-1:-1:-1;;;29953:58:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;30022:23:::0;;-1:-1:-1;;30022:23:0::2;30041:4;30022:23:::0;;::::2;::::0;;30077:18:::2;::::0;:25:::2;::::0;::::2;:22;:25;:::i;:::-;30056:18;:46:::0;30117:11:::2;::::0;:15;;;;:34:::2;;-1:-1:-1::0;30136:15:0;;;;::::2;;;30117:34;30113:198;;;30182:11;::::0;:24:::2;::::0;30203:1:::2;30182:24;:15;:24;:::i;:::-;30168:11;:38:::0;30221:23;;-1:-1:-1;;30221:23:0::2;::::0;;30267:18:::2;::::0;::::2;::::0;30259:7:::2;:27:::0;;30239:5:::2;::::0;30267:18;30259:27;::::2;;;;;;;;;;;;;:40;;;;;-1:-1:-1::0;;;;;30259:40:0::2;;;;;-1:-1:-1::0;;;;;30259:40:0::2;;;;;;30113:198;30442:22;30480:105;30520:50;30566:3;30520:41;30542:18;30520:41;;:6;:17;;;:21;;:41;;;;:::i;:::-;:45:::0;:50:::2;:45;:50;:::i;:::-;30480:17;::::0;::::2;::::0;;:105:::2;:21;:105;:::i;:::-;30442:143;;30679:41;30702:6;:17;;;30679:18;;:22;;:41;;;;:::i;:::-;30658:18;:62:::0;30731:22:::2;30756:19;:17;:19::i;:::-;30731:44:::0;-1:-1:-1;30879:19:0;30875:75:::2;;30915:23:::0;;-1:-1:-1;;30915:23:0::2;;;::::0;;30875:75:::2;31011:18;::::0;30967:63:::2;::::0;;;;;::::2;::::0;::::2;::::0;;;;;;30983:10:::2;::::0;30967:63:::2;::::0;;;;;;;::::2;31043:11;::::0;:70:::2;::::0;;-1:-1:-1;;;31043:70:0;;-1:-1:-1;;;;;31072:8:0::2;31043:70:::0;::::2;;::::0;::::2;::::0;;;;;;;31107:4:::2;31043:70:::0;;;;;;:11;;;::::2;::::0;:20:::2;::::0;:70;;;;;-1:-1:-1;;31043:70:0;;;;;;;-1:-1:-1;31043:11:0;:70;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;31146:53:0::2;::::0;;-1:-1:-1;;;31146:53:0;;31172:10:::2;31146:53;::::0;::::2;::::0;;;;;;;;;-1:-1:-1;;;;;31153:8:0::2;31146:25;::::0;-1:-1:-1;31146:25:0::2;::::0;-1:-1:-1;31146:53:0;;;;;::::2;::::0;;;;;;;;-1:-1:-1;31146:25:0;:53;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;31146:53:0;31124:150:::2;;;;-1:-1:-1::0;;;31124:150:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23708:1;;;29751:1531::o:0;21825:41::-;;;:::o;20787:37::-;;;;:::o;45598:1664::-;45679:10;45647:21;45671:19;;;:7;:19;;;;;45709:17;;;;45701:55;;;;;-1:-1:-1;;;45701:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45776:16;;;;45775:17;45767:58;;;;;-1:-1:-1;;;45767:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45836:23;;-1:-1:-1;;45836:23:0;45855:4;45836:23;;;:16;45939:8;-1:-1:-1;;;45939:8:0;;45836:23;45939:8;45934:66;;45964:24;:22;:24::i;:::-;46029:17;;;;46012:14;;46166:18;:11;46182:1;46166:18;:15;:18;:::i;:::-;46134:6;:28;;;:50;46130:449;;;46263:46;46274:34;46296:11;;46274:17;;:21;;:34;;;;:::i;:::-;46263:6;;:46;:10;:46;:::i;:::-;46339:16;;46452:20;;46254:55;;-1:-1:-1;46339:16:0;-1:-1:-1;46452:24:0;46448:120;;46540:11;;46515:20;;:37;;;:24;:37;:::i;:::-;46497:55;;46448:120;46594:61;;;;;;;;;;;;;;;;;;;;46605:10;;46594:61;;;;;;;;;;46690:45;;;-1:-1:-1;;;46690:45:0;;46716:10;46690:45;;;;;;;;;;;;-1:-1:-1;;;;;46697:8:0;46690:25;;;;:45;;;;;;;;;;;;;;-1:-1:-1;46690:25:0;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46690:45:0;46668:136;;;;-1:-1:-1;;;46668:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46821:19;;46817:225;;46883:60;;;-1:-1:-1;;;46883:60:0;;46915:10;46883:60;;;;;;;;;;;;-1:-1:-1;;;;;46890:14:0;46883:31;;;;:60;;;;;;;;;;;;;;-1:-1:-1;46883:31:0;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46883:60:0;46857:173;;;;-1:-1:-1;;;46857:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47058:16;;47054:201;;47117:48;;;-1:-1:-1;;;47117:48:0;;47140:10;47117:48;;;;;;;;;;;;-1:-1:-1;;;;;47124:5:0;47117:22;;;;:48;;;;;;;;;;;;;;-1:-1:-1;47117:22:0;:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47117:48:0;47091:152;;;;-1:-1:-1;;;47091:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45598:1664;;;;:::o;21400:42::-;;;:::o;27636:78::-;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18543:8:::1;:6;:8::i;:::-;18535:41;;;::::0;;-1:-1:-1;;;18535:41:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;27696:10:::2;:8;:10::i;:::-;27636:78::o:0;32891:1659::-;18266:8;:6;:8::i;:::-;18265:9;18257:38;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;;;;32980:10:::1;32948:21;32972:19:::0;;;:7:::1;:19;::::0;;;;33025:16;;::::1;;33024:17;33002:100;;;;-1:-1:-1::0;;;33002:100:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33183:11:::0;;;;::::1;-1:-1:-1::0;;;;;33183:11:0::1;33198:10;33183:25;33161:97;;;::::0;;-1:-1:-1;;;33161:97:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;33271:22;33296:19;:17;:19::i;:::-;33271:44;;33866:1;33849:14;:18;:50;;;;;33888:11;33871:14;:28;33849:50;33827:170;;;;-1:-1:-1::0;;;33827:170:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34120:14;34088:6;:28;;;:46;;34066:131;;;;-1:-1:-1::0;;;34066:131:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34337:21;:14:::0;34356:1:::1;34337:21;:18;:21;:::i;:::-;34305:6;:28;;;:53;34283:154;;;;-1:-1:-1::0;;;34283:154:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34456:51;::::0;;34492:14:::1;34456:51:::0;;;;34476:14;;34464:10:::1;::::0;34456:51:::1;::::0;;;;::::1;::::0;;::::1;34518:24;:22;:24::i;:::-;18306:1;;32891:1659::o:0;41116:46::-;;;-1:-1:-1;;;;;41116:46:0;;:::o;17940:86::-;17987:4;18011:7;;;;;;;17940:86::o;21929:32::-;;;:::o;20989:33::-;;;;:::o;20197:73::-;;;:::o;20507:38::-;;;:::o;20636:39::-;;;;:::o;27760:158::-;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27834:24:::1;::::0;-1:-1:-1;;;27834:24:0;::::1;;;27826:48;;;::::0;;-1:-1:-1;;;27826:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;27885:25;:23;:25::i;21092:29::-:0;;;;:::o;21631:40::-;;;:::o;19583:44::-;;;-1:-1:-1;;;19583:44:0;;;;;:::o;27457:77::-;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18266:8:::1;:6;:8::i;:::-;18265:9;18257:38;;;::::0;;-1:-1:-1;;;18257:38:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;;::::1;;27518:8:::2;:6;:8::i;15648:87::-:0;15694:7;15721:6;-1:-1:-1;;;;;15721:6:0;15648:87;:::o;20910:32::-;;;;:::o;22532:24::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22532:24:0;;-1:-1:-1;22532:24:0;:::o;20315:31::-;;;-1:-1:-1;;;;;20315:31:0;;:::o;20076:33::-;;;:::o;22460:32::-;;;;;;;;;;41169:29;;;:::o;19925:32::-;;;:::o;37628:211::-;37676:4;37820:11;37798:19;:17;:19::i;:::-;:33;37791:40;;37628:211;:::o;21733:30::-;;;;:::o;21513:38::-;;;:::o;41205:31::-;;;;:::o;29461:113::-;18266:8;:6;:8::i;:::-;18265:9;18257:38;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;;;;29555:11:::1;:9;:11::i;43996:1455::-:0;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23525:17:::1;:15;:17::i;:::-;23517:51;;;::::0;;-1:-1:-1;;;23517:51:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;44132:8:::2;::::0;-1:-1:-1;;;44132:8:0;::::2;;;44124:58;;;;-1:-1:-1::0;;;44124:58:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44202:13;::::0;-1:-1:-1;;;44202:13:0;::::2;;;44201:14;44193:54;;;::::0;;-1:-1:-1;;;44193:54:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;44258:13;:20:::0;;;::::2;-1:-1:-1::0;;;44258:20:0::2;::::0;;44492:11:::2;::::0;:16;:44;::::2;;;;44535:1;44512:20;;:24;44492:44;44488:120;;;-1:-1:-1::0;44576:20:0::2;::::0;44488:120:::2;44641:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;44625:81:0::2;;44650:17;;44669:14;;44685:20;44625:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44723:14;::::0;:18;44719:200:::2;;44791:8;-1:-1:-1::0;;;;;44784:25:0::2;;44810:7;:5;:7::i;:::-;44819:14;;44784:50;;;;;;;;;;;;;-1:-1:-1::0;;;;;44784:50:0::2;-1:-1:-1::0;;;;;44784:50:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;44784:50:0;44758:149:::2;;;;-1:-1:-1::0;;;44758:149:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44935:24:::0;;44931:228:::2;;45009:14;-1:-1:-1::0;;;;;45002:31:0::2;;45034:7;:5;:7::i;:::-;45043:20;45002:62;;;;;;;;;;;;;-1:-1:-1::0;;;;;45002:62:0::2;-1:-1:-1::0;;;;;45002:62:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;45002:62:0;44976:171:::2;;;;-1:-1:-1::0;;;44976:171:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45175:16;::::0;45171:273:::2;;45231:38;::::0;;-1:-1:-1;;;45231:38:0;;45263:4:::2;45231:38;::::0;::::2;::::0;;;45213:15:::2;::::0;-1:-1:-1;;;;;45238:5:0::2;45231:23;::::0;::::2;::::0;:38;;;;;::::2;::::0;;;;;;;;;:23;:38;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;45231:38:0;;-1:-1:-1;;;;;;45317:5:0::2;45310:22;;45333:7;:5;:7::i;:::-;45342;45310:40;;;;;;;;;;;;;-1:-1:-1::0;;;;;45310:40:0::2;-1:-1:-1::0;;;;;45310:40:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;45310:40:0;45284:148:::2;;;;-1:-1:-1::0;;;45284:148:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45171:273;23579:1;43996:1455::o:0;19705:20::-;;;-1:-1:-1;;;19705:20:0;;;;;:::o;22255:41::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22255:41:0;;;:::o;19804:25::-;;;-1:-1:-1;;;19804:25:0;;;;;:::o;16602:244::-;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16691:22:0;::::1;16683:73;;;;-1:-1:-1::0;;;16683:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16793:6;::::0;;16772:38:::1;::::0;-1:-1:-1;;;;;16772:38:0;;::::1;::::0;16793:6;::::1;::::0;16772:38:::1;::::0;::::1;16821:6;:17:::0;;-1:-1:-1;;16821:17:0::1;-1:-1:-1::0;;;;;16821:17:0;;;::::1;::::0;;;::::1;::::0;;16602:244::o;27970:104::-;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28035:24:::1;:31:::0;;;::::1;-1:-1:-1::0;;;28035:31:0::1;::::0;;27970:104::o;37361:142::-;37411:7;37438:57;37481:13;37438:38;:15;37458:17;37438:38;:19;:38;:::i;:57::-;37431:64;;37361:142;:::o;47458:3023::-;23525:17;:15;:17::i;:::-;23517:51;;;;;-1:-1:-1;;;23517:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47548:8:::1;::::0;-1:-1:-1;;;47548:8:0;::::1;;;47547:9;47539:68;;;;-1:-1:-1::0;;;47539:68:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47618:8;:15:::0;;;::::1;-1:-1:-1::0;;;47618:15:0::1;::::0;;47728:34:::1;::::0;;-1:-1:-1;;;47728:34:0;;47756:4:::1;47728:34;::::0;::::1;::::0;;;-1:-1:-1;;;;;47728:9:0::1;:19;::::0;::::1;::::0;:34;;;;;::::1;::::0;;;;;;;;:19;:34;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;47728:34:0;:38:::1;47724:751;;;47783:11;::::0;:139:::1;::::0;;-1:-1:-1;;;47783:139:0;;-1:-1:-1;;;;;47830:8:0::1;47783:139:::0;::::1;;::::0;::::1;::::0;-1:-1:-1;;47783:139:0;;;;47902:4:::1;47783:139:::0;;;;;;:11;;;::::1;::::0;:20:::1;::::0;:139;;;;;-1:-1:-1;;47783:139:0;;;;;;;-1:-1:-1;47783:11:0;:139;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;48021:16:0::1;::::0;;48035:1:::1;48021:16:::0;;;;;::::1;::::0;;;47995:23:::1;::::0;-1:-1:-1;48021:16:0;-1:-1:-1;48021:16:0::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;48021:16:0::1;47995:42;;48072:9;48052:6;48059:1;48052:9;;;;;;;;-1:-1:-1::0;;;;;48052:30:0;;::::1;:9;::::0;;::::1;::::0;;;;;;:30;;;;48124:19:::1;::::0;:109:::1;::::0;;;;;48213:4:::1;48124:109:::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;48097:24:::1;::::0;48124:19;;;::::1;::::0;:37:::1;::::0;48180:6;;48213:4;;48124:109;;;;;;;;;::::1;::::0;::::1;::::0;;;48097:24;48124:109:::1;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;48124:109:0;;-1:-1:-1;48252:20:0;;48248:216:::1;;48293:19;::::0;:155:::1;::::0;;;;;;;;;;48424:4:::1;48293:155:::0;;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;-1:-1:-1;;;;;48293:19:0;;::::1;::::0;:32:::1;::::0;48348:6;;48377:16;;48424:4;;48293:155;;;;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;:19:::1;:155;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;;48248:216:0::1;47724:751;;;48510:41;::::0;;-1:-1:-1;;;48510:41:0;;48545:4:::1;48510:41;::::0;::::1;::::0;;;48487:20:::1;::::0;-1:-1:-1;;;;;48517:8:0::1;48510:26;::::0;::::1;::::0;:41;;;;;::::1;::::0;;;;;;;;;:26;:41;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;48510:41:0;48586:38:::1;::::0;;-1:-1:-1;;;48586:38:0;;48618:4:::1;48586:38;::::0;::::1;::::0;;;48510:41;;-1:-1:-1;48562:21:0::1;::::0;-1:-1:-1;;;;;48593:5:0::1;48586:23;::::0;::::1;::::0;:38;;;;;48510:41:::1;::::0;48586:38;;;;;;;:23;:38;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;48586:38:0;;-1:-1:-1;48771:14:0::1;-1:-1:-1::0;;;;;48763:37:0::1;::::0;48759:140:::1;;48840:47;::::0;;-1:-1:-1;;;48840:47:0;;48881:4:::1;48840:47;::::0;::::1;::::0;;;-1:-1:-1;;;;;48847:14:0::1;48840:32;::::0;::::1;::::0;:47;;;;;::::1;::::0;;;;;;;;:32;:47;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;48840:47:0;48817:20:::1;:70:::0;48759:140:::1;49251:18;::::0;48947:21:::1;::::0;49236:33;::::1;49232:118;;;49319:18;::::0;49302:36:::1;::::0;:12;;:36:::1;:16;:36;:::i;:::-;49286:52;;49232:118;49580:23;49618:13;:9;:13;::::0;49614:272:::1;;49666:39;49701:3;49667:28;:13:::0;:28:::1;49685:9;49667:28;;:17;:28;:::i;49666:39::-;49648:57:::0;-1:-1:-1;49740:34:0::1;:13:::0;49648:57;49740:34:::1;:17;:34;:::i;:::-;49720:17;:54:::0;49614:272:::1;;;-1:-1:-1::0;49841:17:0::1;:33:::0;;;49825:1:::1;49614:272;49978:11;::::0;49974:243:::1;;50030:1;50011:16;:20:::0;50046:14:::1;:30:::0;;;49974:243:::1;;;50146:11;::::0;50128:30:::1;::::0;:13;;:30:::1;:17;:30;:::i;:::-;50109:16;:49:::0;50173:14:::1;:32:::0;;;49974:243:::1;50305:18;::::0;50338:17:::1;::::0;50398:20:::1;::::0;50234:195:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;::::1;::::0;;;;;;;::::1;50445:28;50465:7;50445:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;50445:28:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;;;;;;;23579:1;;;;47458:3023::o:0;34649:110::-;34729:15;:22;34649:110;:::o;3259:158::-;3317:7;3350:1;3345;:6;;3337:49;;;;;-1:-1:-1;;;3337:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3404:5:0;;;3259:158;;;;;:::o;3676:220::-;3734:7;3758:6;3754:20;;-1:-1:-1;3773:1:0;3766:8;;3754:20;3797:5;;;3801:1;3797;:5;:1;3821:5;;;;;:10;3813:56;;;;-1:-1:-1;;;3813:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3887:1;3676:220;-1:-1:-1;;;3676:220:0:o;4374:153::-;4432:7;4464:1;4460;:5;4452:44;;;;;-1:-1:-1;;;4452:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;4518:1;4514;:5;;;;;;;4374:153;-1:-1:-1;;;4374:153:0:o;2797:179::-;2855:7;2887:5;;;2911:6;;;;2903:46;;;;;-1:-1:-1;;;2903:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;14183:106;14271:10;14183:106;:::o;18999:120::-;18543:8;:6;:8::i;:::-;18535:41;;;;;-1:-1:-1;;;18535:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;19068:5:::1;19058:15:::0;;;::::1;::::0;;19089:22:::1;19098:12;:10;:12::i;:::-;19089:22;::::0;;-1:-1:-1;;;;;19089:22:0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;18999:120::o:0;38040:1630::-;38116:45;;;;;;38135:10;38116:45;;;;38155:4;38116:45;;;;;;38165:14;;-1:-1:-1;;;;;38116:8:0;:18;;;;:45;;;;;;;;;;;;;;;:18;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38116:45:0;:63;;38094:180;;;;-1:-1:-1;;;38094:180:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38287:22;38312:19;:17;:19::i;:::-;38350:10;38342:19;;;;:7;:19;;;;;:41;;;:58;;;38444:30;;;38287:44;;-1:-1:-1;38444:74:0;;38493:14;38444:74;:34;:74;:::i;:::-;38419:10;38411:19;;;;:7;:19;;;;;:30;;:107;38729:18;:11;38745:1;38729:18;:15;:18;:::i;:::-;38711:14;:36;38707:315;;;38764:7;:24;;;;;;;;-1:-1:-1;38764:24:0;;;;;;;;;-1:-1:-1;;38764:24:0;38777:10;38764:24;;;38880:14;;:27;;;:18;:27;:::i;:::-;38854:10;38846:19;;;;:7;:19;;;;;:31;;:61;38936:11;;:24;;38957:1;38936:24;:15;:24;:::i;:::-;38922:11;:38;38983:10;38975:19;;;;:7;:19;;;;;:35;;-1:-1:-1;;38975:35:0;;;;;38707:315;39063:18;;:38;;39086:14;39063:38;:22;:38;:::i;:::-;39042:18;:59;39134:64;;;;;;39156:10;39134:64;;;;39176:4;39134:64;;;;39183:14;39134:64;;;;;;-1:-1:-1;;;;;39134:8:0;:21;;;;:64;;;;;;;;;;;;;;-1:-1:-1;39134:21:0;:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39134:64:0;39112:129;;;;;-1:-1:-1;;;39112:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39384:33;;;-1:-1:-1;;;39384:33:0;;39411:4;39384:33;;;;;;39358:23;;-1:-1:-1;;;;;39384:8:0;:18;;;;:33;;;;;;;;;;;;;;;:18;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39384:33:0;39475:11;;39450:55;;;;;;-1:-1:-1;;;;;39475:11:0;;;39450:55;;;;;;;;;;;;39384:33;;-1:-1:-1;39450:8:0;:16;;;;;;:55;;;;;39384:33;;39450:55;;;;;;;;-1:-1:-1;39450:16:0;:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39450:55:0;39428:146;;;;-1:-1:-1;;;39428:146:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39587:11;;:75;;;;;;-1:-1:-1;;;;;39615:8:0;39587:75;;;;;;;;;;;;39651:4;39587:75;;;;39658:3;39587:75;;;;;;:11;;;;;:19;;:75;;;;;-1:-1:-1;;39587:75:0;;;;;;;-1:-1:-1;39587:11:0;:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38040:1630;;:::o;16299:148::-;15879:12;:10;:12::i;:::-;-1:-1:-1;;;;;15868:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;15868:23:0;;15860:68;;;;;-1:-1:-1;;;15860:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16406:1:::1;16390:6:::0;;16369:40:::1;::::0;-1:-1:-1;;;;;16390:6:0;;::::1;::::0;16369:40:::1;::::0;16406:1;;16369:40:::1;16437:1;16420:19:::0;;-1:-1:-1;;16420:19:0::1;::::0;;16299:148::o;18740:118::-;18266:8;:6;:8::i;:::-;18265:9;18257:38;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;-1:-1:-1;;;18257:38:0;;;;;;;;;;;;;;;18800:7:::1;:14:::0;;;::::1;::::0;::::1;::::0;;18830:20:::1;18837:12;:10;:12::i;39741:1048::-:0;39790:19;:17;:19::i;:::-;:24;39782:61;;;;;-1:-1:-1;;;39782:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39904:10;39876:19;;;;:7;:19;;;;;:24;;;;-1:-1:-1;;;;;39876:24:0;:38;;;:88;;-1:-1:-1;39943:10:0;39935:19;;;;:7;:19;;;;;:29;;;;;;39876:88;39854:173;;;;-1:-1:-1;;;39854:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40061:18;;:25;;40084:1;40061:25;:22;:25;:::i;:::-;40040:18;:46;;;40127:15;-1:-1:-1;40105:37:0;40097:89;;;;-1:-1:-1;;;40097:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40224:10;40199:14;40216:19;;;:7;:19;;;;;:29;;;;;;40256:23;;:::i;:::-;-1:-1:-1;40295:270:0;;;;;;;;-1:-1:-1;40295:270:0;;;;;;;;;;;;;;;;40327:10;40295:270;;;;;;;;;;;;;;;;;;;;;;;;40576:19;;;:7;:19;;;;;;;:31;;;;;;;;;;-1:-1:-1;;40576:31:0;;;;;;;-1:-1:-1;;40576:31:0;;;;;;;;;;;;;-1:-1:-1;;40576:31:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40576:31:0;;;;;;;;;;;;;;;-1:-1:-1;40576:31:0;;;;;;;;;;;;;;;;;40623:9;40618:75;;40649:15;:32;;;;;;;-1:-1:-1;40649:32:0;;;;;;;;-1:-1:-1;;40649:32:0;40670:10;40649:32;;;40618:75;40708:38;;;40731:14;40708:38;;;;40719:10;;40708:38;;;;;;;;;;40757:24;:22;:24::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://23dd27563e18c20ee4b70bd09c2ee1138236b68e9dba0b1e0dcd7bd0e3d4d4e4

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.