Token WAVE Token

 

Overview ERC-20

Price
$0.00 @ 0.000000 MATIC
Fully Diluted Market Cap
Total Supply:
10,000,000 WAVE

Holders:
315 addresses

Transfers:
-

Contract:
0x4DE7FEA447b837d7E77848a4B6C0662a64A84E140x4DE7FEA447b837d7E77848a4B6C0662a64A84E14

Decimals:
18

Social Profiles:
Not Available, Update ?

 
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
WAVE

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-07-26
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;

/// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library
/// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point
// representation. When it does not, it is annonated in the function's NatSpec documentation.
library PRBMathCommon {
	/// @dev How many trailing decimals can be represented.
	uint256 internal constant SCALE = 1e18;

	/// @dev Largest power of two divisor of SCALE.
	uint256 internal constant SCALE_LPOTD = 262144;

	/// @dev SCALE inverted mod 2^256.
	uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661508869554232690281;

	/// @notice Calculates the binary exponent of x using the binary fraction method.
	/// @dev Uses 128.128-bit fixed-point numbers - it is the most efficient way.
	/// @param x The exponent as an unsigned 128.128-bit fixed-point number.
	/// @return result The result as an unsigned 60x18 decimal fixed-point number.
	function exp2(uint256 x) internal pure returns (uint256 result) {
		unchecked {
			// Start from 0.5 in the 128.128-bit fixed-point format. We need to use uint256 because the intermediary
			// may get very close to 2^256, which doesn't fit in int256.
			result = 0x80000000000000000000000000000000;

			// Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows
			// because the initial result is 2^127 and all magic factors are less than 2^129.
			if (x & 0x80000000000000000000000000000000 > 0) result = (result * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128;
			if (x & 0x40000000000000000000000000000000 > 0) result = (result * 0x1306FE0A31B7152DE8D5A46305C85EDED) >> 128;
			if (x & 0x20000000000000000000000000000000 > 0) result = (result * 0x1172B83C7D517ADCDF7C8C50EB14A7920) >> 128;
			if (x & 0x10000000000000000000000000000000 > 0) result = (result * 0x10B5586CF9890F6298B92B71842A98364) >> 128;
			if (x & 0x8000000000000000000000000000000 > 0) result = (result * 0x1059B0D31585743AE7C548EB68CA417FE) >> 128;
			if (x & 0x4000000000000000000000000000000 > 0) result = (result * 0x102C9A3E778060EE6F7CACA4F7A29BDE9) >> 128;
			if (x & 0x2000000000000000000000000000000 > 0) result = (result * 0x10163DA9FB33356D84A66AE336DCDFA40) >> 128;
			if (x & 0x1000000000000000000000000000000 > 0) result = (result * 0x100B1AFA5ABCBED6129AB13EC11DC9544) >> 128;
			if (x & 0x800000000000000000000000000000 > 0) result = (result * 0x10058C86DA1C09EA1FF19D294CF2F679C) >> 128;
			if (x & 0x400000000000000000000000000000 > 0) result = (result * 0x1002C605E2E8CEC506D21BFC89A23A011) >> 128;
			if (x & 0x200000000000000000000000000000 > 0) result = (result * 0x100162F3904051FA128BCA9C55C31E5E0) >> 128;
			if (x & 0x100000000000000000000000000000 > 0) result = (result * 0x1000B175EFFDC76BA38E31671CA939726) >> 128;
			if (x & 0x80000000000000000000000000000 > 0) result = (result * 0x100058BA01FB9F96D6CACD4B180917C3E) >> 128;
			if (x & 0x40000000000000000000000000000 > 0) result = (result * 0x10002C5CC37DA9491D0985C348C68E7B4) >> 128;
			if (x & 0x20000000000000000000000000000 > 0) result = (result * 0x1000162E525EE054754457D5995292027) >> 128;
			if (x & 0x10000000000000000000000000000 > 0) result = (result * 0x10000B17255775C040618BF4A4ADE83FD) >> 128;
			if (x & 0x8000000000000000000000000000 > 0) result = (result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAC) >> 128;
			if (x & 0x4000000000000000000000000000 > 0) result = (result * 0x100002C5C89D5EC6CA4D7C8ACC017B7CA) >> 128;
			if (x & 0x2000000000000000000000000000 > 0) result = (result * 0x10000162E43F4F831060E02D839A9D16D) >> 128;
			if (x & 0x1000000000000000000000000000 > 0) result = (result * 0x100000B1721BCFC99D9F890EA06911763) >> 128;
			if (x & 0x800000000000000000000000000 > 0) result = (result * 0x10000058B90CF1E6D97F9CA14DBCC1629) >> 128;
			if (x & 0x400000000000000000000000000 > 0) result = (result * 0x1000002C5C863B73F016468F6BAC5CA2C) >> 128;
			if (x & 0x200000000000000000000000000 > 0) result = (result * 0x100000162E430E5A18F6119E3C02282A6) >> 128;
			if (x & 0x100000000000000000000000000 > 0) result = (result * 0x1000000B1721835514B86E6D96EFD1BFF) >> 128;
			if (x & 0x80000000000000000000000000 > 0) result = (result * 0x100000058B90C0B48C6BE5DF846C5B2F0) >> 128;
			if (x & 0x40000000000000000000000000 > 0) result = (result * 0x10000002C5C8601CC6B9E94213C72737B) >> 128;
			if (x & 0x20000000000000000000000000 > 0) result = (result * 0x1000000162E42FFF037DF38AA2B219F07) >> 128;
			if (x & 0x10000000000000000000000000 > 0) result = (result * 0x10000000B17217FBA9C739AA5819F44FA) >> 128;
			if (x & 0x8000000000000000000000000 > 0) result = (result * 0x1000000058B90BFCDEE5ACD3C1CEDC824) >> 128;
			if (x & 0x4000000000000000000000000 > 0) result = (result * 0x100000002C5C85FE31F35A6A30DA1BE51) >> 128;
			if (x & 0x2000000000000000000000000 > 0) result = (result * 0x10000000162E42FF0999CE3541B9FFFD0) >> 128;
			if (x & 0x1000000000000000000000000 > 0) result = (result * 0x100000000B17217F80F4EF5AADDA45554) >> 128;
			if (x & 0x800000000000000000000000 > 0) result = (result * 0x10000000058B90BFBF8479BD5A81B51AE) >> 128;
			if (x & 0x400000000000000000000000 > 0) result = (result * 0x1000000002C5C85FDF84BD62AE30A74CD) >> 128;
			if (x & 0x200000000000000000000000 > 0) result = (result * 0x100000000162E42FEFB2FED257559BDAA) >> 128;
			if (x & 0x100000000000000000000000 > 0) result = (result * 0x1000000000B17217F7D5A7716BBA4A9AF) >> 128;
			if (x & 0x80000000000000000000000 > 0) result = (result * 0x100000000058B90BFBE9DDBAC5E109CCF) >> 128;
			if (x & 0x40000000000000000000000 > 0) result = (result * 0x10000000002C5C85FDF4B15DE6F17EB0E) >> 128;
			if (x & 0x20000000000000000000000 > 0) result = (result * 0x1000000000162E42FEFA494F1478FDE05) >> 128;
			if (x & 0x10000000000000000000000 > 0) result = (result * 0x10000000000B17217F7D20CF927C8E94D) >> 128;
			if (x & 0x8000000000000000000000 > 0) result = (result * 0x1000000000058B90BFBE8F71CB4E4B33E) >> 128;
			if (x & 0x4000000000000000000000 > 0) result = (result * 0x100000000002C5C85FDF477B662B26946) >> 128;
			if (x & 0x2000000000000000000000 > 0) result = (result * 0x10000000000162E42FEFA3AE53369388D) >> 128;
			if (x & 0x1000000000000000000000 > 0) result = (result * 0x100000000000B17217F7D1D351A389D41) >> 128;
			if (x & 0x800000000000000000000 > 0) result = (result * 0x10000000000058B90BFBE8E8B2D3D4EDF) >> 128;
			if (x & 0x400000000000000000000 > 0) result = (result * 0x1000000000002C5C85FDF4741BEA6E77F) >> 128;
			if (x & 0x200000000000000000000 > 0) result = (result * 0x100000000000162E42FEFA39FE95583C3) >> 128;
			if (x & 0x100000000000000000000 > 0) result = (result * 0x1000000000000B17217F7D1CFB72B45E3) >> 128;
			if (x & 0x80000000000000000000 > 0) result = (result * 0x100000000000058B90BFBE8E7CC35C3F2) >> 128;
			if (x & 0x40000000000000000000 > 0) result = (result * 0x10000000000002C5C85FDF473E242EA39) >> 128;
			if (x & 0x20000000000000000000 > 0) result = (result * 0x1000000000000162E42FEFA39F02B772C) >> 128;
			if (x & 0x10000000000000000000 > 0) result = (result * 0x10000000000000B17217F7D1CF7D83C1A) >> 128;
			if (x & 0x8000000000000000000 > 0) result = (result * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128;
			if (x & 0x4000000000000000000 > 0) result = (result * 0x100000000000002C5C85FDF473DEA871F) >> 128;
			if (x & 0x2000000000000000000 > 0) result = (result * 0x10000000000000162E42FEFA39EF44D92) >> 128;
			if (x & 0x1000000000000000000 > 0) result = (result * 0x100000000000000B17217F7D1CF79E949) >> 128;
			if (x & 0x800000000000000000 > 0) result = (result * 0x10000000000000058B90BFBE8E7BCE545) >> 128;
			if (x & 0x400000000000000000 > 0) result = (result * 0x1000000000000002C5C85FDF473DE6ECA) >> 128;
			if (x & 0x200000000000000000 > 0) result = (result * 0x100000000000000162E42FEFA39EF366F) >> 128;
			if (x & 0x100000000000000000 > 0) result = (result * 0x1000000000000000B17217F7D1CF79AFA) >> 128;
			if (x & 0x80000000000000000 > 0) result = (result * 0x100000000000000058B90BFBE8E7BCD6E) >> 128;
			if (x & 0x40000000000000000 > 0) result = (result * 0x10000000000000002C5C85FDF473DE6B3) >> 128;
			if (x & 0x20000000000000000 > 0) result = (result * 0x1000000000000000162E42FEFA39EF359) >> 128;
			if (x & 0x10000000000000000 > 0) result = (result * 0x10000000000000000B17217F7D1CF79AC) >> 128;

			// Multiply the result by the integer part 2^n + 1. We have to shift by one bit extra because we have already divided
			// by two when we set the result equal to 0.5 above.
			result = result << ((x >> 128) + 1);

			// Convert the result to the signed 60.18-decimal fixed-point format.
			result = PRBMathCommon.mulDiv(result, 1e18, 2**128);
		}
	}

	/// @notice Finds the zero-based index of the first one in the binary representation of x.
	/// @dev See the note on msb in the "Find First Set" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set
	/// @param x The uint256 number for which to find the index of the most significant bit.
	/// @return msb The index of the most significant bit as an uint256.
	function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) {
		if (x >= 2**128) {
			x >>= 128;
			msb += 128;
		}
		if (x >= 2**64) {
			x >>= 64;
			msb += 64;
		}
		if (x >= 2**32) {
			x >>= 32;
			msb += 32;
		}
		if (x >= 2**16) {
			x >>= 16;
			msb += 16;
		}
		if (x >= 2**8) {
			x >>= 8;
			msb += 8;
		}
		if (x >= 2**4) {
			x >>= 4;
			msb += 4;
		}
		if (x >= 2**2) {
			x >>= 2;
			msb += 2;
		}
		if (x >= 2**1) {
			// No need to shift x any more.
			msb += 1;
		}
	}

	/// @notice Calculates floor(x*y÷denominator) with full precision.
	///
	/// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.
	///
	/// Requirements:
	/// - The denominator cannot be zero.
	/// - The result must fit within uint256.
	///
	/// Caveats:
	/// - This function does not work with fixed-point numbers.
	///
	/// @param x The multiplicand as an uint256.
	/// @param y The multiplier as an uint256.
	/// @param denominator The divisor as an uint256.
	/// @return result The result as an uint256.
	function mulDiv(
		uint256 x,
		uint256 y,
		uint256 denominator
	) internal pure returns (uint256 result) {
		// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2**256 and mod 2**256 - 1, then use
		// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
		// variables such that product = prod1 * 2**256 + prod0.
		uint256 prod0; // Least significant 256 bits of the product
		uint256 prod1; // Most significant 256 bits of the product
		assembly {
			let mm := mulmod(x, y, not(0))
			prod0 := mul(x, y)
			prod1 := sub(sub(mm, prod0), lt(mm, prod0))
		}

		// Handle non-overflow cases, 256 by 256 division
		if (prod1 == 0) {
			require(denominator > 0);
			assembly {
				result := div(prod0, denominator)
			}
			return result;
		}

		// Make sure the result is less than 2**256. Also prevents denominator == 0.
		require(denominator > prod1);

		///////////////////////////////////////////////
		// 512 by 256 division.
		///////////////////////////////////////////////

		// Make division exact by subtracting the remainder from [prod1 prod0].
		uint256 remainder;
		assembly {
			// Compute remainder using mulmod.
			remainder := mulmod(x, y, denominator)

			// Subtract 256 bit number from 512 bit number
			prod1 := sub(prod1, gt(remainder, prod0))
			prod0 := sub(prod0, remainder)
		}

		// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
		// See https://cs.stackexchange.com/q/138556/92363.
		unchecked {
			// Does not overflow because the denominator cannot be zero at this stage in the function.
			uint256 lpotdod = denominator & (~denominator + 1);
			assembly {
				// Divide denominator by lpotdod.
				denominator := div(denominator, lpotdod)

				// Divide [prod1 prod0] by lpotdod.
				prod0 := div(prod0, lpotdod)

				// Flip lpotdod such that it is 2**256 / lpotdod. If lpotdod is zero, then it becomes one.
				lpotdod := add(div(sub(0, lpotdod), lpotdod), 1)
			}

			// Shift in bits from prod1 into prod0.
			prod0 |= prod1 * lpotdod;

			// Invert denominator mod 2**256. Now that denominator is an odd number, it has an inverse modulo 2**256 such
			// that denominator * inv = 1 mod 2**256. Compute the inverse by starting with a seed that is correct for
			// four bits. That is, denominator * inv = 1 mod 2**4
			uint256 inverse = (3 * denominator) ^ 2;

			// Now use Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
			// in modular arithmetic, doubling the correct bits in each step.
			inverse *= 2 - denominator * inverse; // inverse mod 2**8
			inverse *= 2 - denominator * inverse; // inverse mod 2**16
			inverse *= 2 - denominator * inverse; // inverse mod 2**32
			inverse *= 2 - denominator * inverse; // inverse mod 2**64
			inverse *= 2 - denominator * inverse; // inverse mod 2**128
			inverse *= 2 - denominator * inverse; // inverse mod 2**256

			// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
			// This will give us the correct result modulo 2**256. Since the precoditions guarantee that the outcome is
			// less than 2**256, this is the final result. We don't need to compute the high bits of the result and prod1
			// is no longer required.
			result = prod0 * inverse;
			return result;
		}
	}

	/// @notice Calculates floor(x*y÷1e18) with full precision.
	///
	/// @dev Variant of "mulDiv" with constant folding, i.e. in which the denominator is always 1e18. Before returning the
	/// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of
	/// being rounded to 1e-18.  See "Listing 6" and text above it at https://accu.org/index.php/journals/1717.
	///
	/// Requirements:
	/// - The result must fit within uint256.
	///
	/// Caveats:
	/// - The body is purposely left uncommented; see the NatSpec comments in "PRBMathCommon.mulDiv" to understand how this works.
	/// - It is assumed that the result can never be type(uint256).max when x and y solve the following two queations:
	///     1) x * y = type(uint256).max * SCALE
	///     2) (x * y) % SCALE >= SCALE / 2
	///
	/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.
	/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.
	/// @return result The result as an unsigned 60.18-decimal fixed-point number.
	function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) {
		uint256 prod0;
		uint256 prod1;
		assembly {
			let mm := mulmod(x, y, not(0))
			prod0 := mul(x, y)
			prod1 := sub(sub(mm, prod0), lt(mm, prod0))
		}

		uint256 remainder;
		uint256 roundUpUnit;
		assembly {
			remainder := mulmod(x, y, SCALE)
			roundUpUnit := gt(remainder, 499999999999999999)
		}

		if (prod1 == 0) {
			unchecked {
				result = (prod0 / SCALE) + roundUpUnit;
				return result;
			}
		}

		require(SCALE > prod1);

		assembly {
			result := add(
				mul(
					or(
						div(sub(prod0, remainder), SCALE_LPOTD),
						mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1))
					),
					SCALE_INVERSE
				),
				roundUpUnit
			)
		}
	}

	/// @notice Calculates the square root of x, rounding down.
	/// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
	///
	/// Caveats:
	/// - This function does not work with fixed-point numbers.
	///
	/// @param x The uint256 number for which to calculate the square root.
	/// @return result The result as an uint256.
	function sqrt(uint256 x) internal pure returns (uint256 result) {
		if (x == 0) {
			return 0;
		}

		// Calculate the square root of the perfect square of a power of two that is the closest to x.
		uint256 xAux = uint256(x);
		result = 1;
		if (xAux >= 0x100000000000000000000000000000000) {
			xAux >>= 128;
			result <<= 64;
		}
		if (xAux >= 0x10000000000000000) {
			xAux >>= 64;
			result <<= 32;
		}
		if (xAux >= 0x100000000) {
			xAux >>= 32;
			result <<= 16;
		}
		if (xAux >= 0x10000) {
			xAux >>= 16;
			result <<= 8;
		}
		if (xAux >= 0x100) {
			xAux >>= 8;
			result <<= 4;
		}
		if (xAux >= 0x10) {
			xAux >>= 4;
			result <<= 2;
		}
		if (xAux >= 0x8) {
			result <<= 1;
		}

		// The operations can never overflow because the result is max 2^127 when it enters this block.
		unchecked {
			result = (result + x / result) >> 1;
			result = (result + x / result) >> 1;
			result = (result + x / result) >> 1;
			result = (result + x / result) >> 1;
			result = (result + x / result) >> 1;
			result = (result + x / result) >> 1;
			result = (result + x / result) >> 1; // Seven iterations should be enough
			uint256 roundedDownResult = x / result;
			return result >= roundedDownResult ? roundedDownResult : result;
		}
	}
}

/// @title PRBMathUD60x18
/// @author Paul Razvan Berg
/// @notice Smart contract library for advanced fixed-point math. It works with uint256 numbers considered to have 18
/// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60
/// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the
/// maximum values permitted by the Solidity type uint256.
library PRBMathUD60x18 {
	/// @dev Half the SCALE number.
	uint256 internal constant HALF_SCALE = 5e17;

	/// @dev log2(e) as an unsigned 60.18-decimal fixed-point number.
	uint256 internal constant LOG2_E = 1442695040888963407;

	/// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have.
	uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;

	/// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have.
	uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000;

	/// @dev How many trailing decimals can be represented.
	uint256 internal constant SCALE = 1e18;

	/// @notice Calculates arithmetic average of x and y, rounding down.
	/// @param x The first operand as an unsigned 60.18-decimal fixed-point number.
	/// @param y The second operand as an unsigned 60.18-decimal fixed-point number.
	/// @return result The arithmetic average as an usigned 60.18-decimal fixed-point number.
	function avg(uint256 x, uint256 y) internal pure returns (uint256 result) {
		// The operations can never overflow.
		unchecked {
			// The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need
			// to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.
			result = (x >> 1) + (y >> 1) + (x & y & 1);
		}
	}

	/// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x.
	///
	/// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.
	/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
	///
	/// Requirements:
	/// - x must be less than or equal to MAX_WHOLE_UD60x18.
	///
	/// @param x The unsigned 60.18-decimal fixed-point number to ceil.
	/// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number.
	function ceil(uint256 x) internal pure returns (uint256 result) {
		require(x <= MAX_WHOLE_UD60x18);
		assembly {
			// Equivalent to "x % SCALE" but faster.
			let remainder := mod(x, SCALE)

			// Equivalent to "SCALE - remainder" but faster.
			let delta := sub(SCALE, remainder)

			// Equivalent to "x + delta * (remainder > 0 ? 1 : 0)" but faster.
			result := add(x, mul(delta, gt(remainder, 0)))
		}
	}

	/// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number.
	///
	/// @dev Uses mulDiv to enable overflow-safe multiplication and division.
	///
	/// Requirements:
	/// - y cannot be zero.
	///
	/// @param x The numerator as an unsigned 60.18-decimal fixed-point number.
	/// @param y The denominator as an unsigned 60.18-decimal fixed-point number.
	/// @param result The quotient as an unsigned 60.18-decimal fixed-point number.
	function div(uint256 x, uint256 y) internal pure returns (uint256 result) {
		result = PRBMathCommon.mulDiv(x, SCALE, y);
	}

	/// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number.
	/// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).
	function e() internal pure returns (uint256 result) {
		result = 2718281828459045235;
	}

	/// @notice Calculates the natural exponent of x.
	///
	/// @dev Based on the insight that e^x = 2^(x * log2(e)).
	///
	/// Requirements:
	/// - All from "log2".
	/// - x must be less than 88722839111672999628.
	///
	/// @param x The exponent as an unsigned 60.18-decimal fixed-point number.
	/// @return result The result as an unsigned 60.18-decimal fixed-point number.
	function exp(uint256 x) internal pure returns (uint256 result) {
		// Without this check, the value passed to "exp2" would be greater than 128e18.
		require(x < 88722839111672999628);

		// Do the fixed-point multiplication inline to save gas.
		unchecked {
			uint256 doubleScaleProduct = x * LOG2_E;
			result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);
		}
	}

	/// @notice Calculates the binary exponent of x using the binary fraction method.
	///
	/// @dev See https://ethereum.stackexchange.com/q/79903/24693.
	///
	/// Requirements:
	/// - x must be 128e18 or less.
	/// - The result must fit within MAX_UD60x18.
	///
	/// @param x The exponent as an unsigned 60.18-decimal fixed-point number.
	/// @return result The result as an unsigned 60.18-decimal fixed-point number.
	function exp2(uint256 x) internal pure returns (uint256 result) {
		// 2**128 doesn't fit within the 128.128-bit format used internally in this function.
		require(x < 128e18);

		unchecked {
			// Convert x to the 128.128-bit fixed-point format.
			uint256 x128x128 = (x << 128) / SCALE;

			// Pass x to the PRBMathCommon.exp2 function, which uses the 128.128-bit fixed-point number representation.
			result = PRBMathCommon.exp2(x128x128);
		}
	}

	/// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x.
	/// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.
	/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
	/// @param x The unsigned 60.18-decimal fixed-point number to floor.
	/// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number.
	function floor(uint256 x) internal pure returns (uint256 result) {
		assembly {
			// Equivalent to "x % SCALE" but faster.
			let remainder := mod(x, SCALE)

			// Equivalent to "x - remainder * (remainder > 0 ? 1 : 0)" but faster.
			result := sub(x, mul(remainder, gt(remainder, 0)))
		}
	}

	/// @notice Yields the excess beyond the floor of x.
	/// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part.
	/// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of.
	/// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number.
	function frac(uint256 x) internal pure returns (uint256 result) {
		assembly {
			result := mod(x, SCALE)
		}
	}

	/// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.
	///
	/// @dev Requirements:
	/// - x * y must fit within MAX_UD60x18, lest it overflows.
	///
	/// @param x The first operand as an unsigned 60.18-decimal fixed-point number.
	/// @param y The second operand as an unsigned 60.18-decimal fixed-point number.
	/// @return result The result as an unsigned 60.18-decimal fixed-point number.
	function gm(uint256 x, uint256 y) internal pure returns (uint256 result) {
		if (x == 0) {
			return 0;
		}

		unchecked {
			// Checking for overflow this way is faster than letting Solidity do it.
			uint256 xy = x * y;
			require(xy / x == y);

			// We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE
			// during multiplication. See the comments within the "sqrt" function.
			result = PRBMathCommon.sqrt(xy);
		}
	}

	/// @notice Calculates 1 / x, rounding towards zero.
	///
	/// @dev Requirements:
	/// - x cannot be zero.
	///
	/// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse.
	/// @return result The inverse as an unsigned 60.18-decimal fixed-point number.
	function inv(uint256 x) internal pure returns (uint256 result) {
		unchecked {
			// 1e36 is SCALE * SCALE.
			result = 1e36 / x;
		}
	}

	/// @notice Calculates the natural logarithm of x.
	///
	/// @dev Based on the insight that ln(x) = log2(x) / log2(e).
	///
	/// Requirements:
	/// - All from "log2".
	///
	/// Caveats:
	/// - All from "log2".
	/// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.
	///
	/// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm.
	/// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number.
	function ln(uint256 x) internal pure returns (uint256 result) {
		// Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)
		// can return is 196205294292027477728.
		unchecked { result = (log2(x) * SCALE) / LOG2_E; }
	}

	/// @notice Calculates the common logarithm of x.
	///
	/// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common
	/// logarithm based on the insight that log10(x) = log2(x) / log2(10).
	///
	/// Requirements:
	/// - All from "log2".
	///
	/// Caveats:
	/// - All from "log2".
	///
	/// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm.
	/// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number.
	function log10(uint256 x) internal pure returns (uint256 result) {
		require(x >= SCALE);

		// Note that the "mul" in this block is the assembly mul operation, not the "mul" function defined in this contract.
		// prettier-ignore
		assembly {
			switch x
			case 1 { result := mul(SCALE, sub(0, 18)) }
			case 10 { result := mul(SCALE, sub(1, 18)) }
			case 100 { result := mul(SCALE, sub(2, 18)) }
			case 1000 { result := mul(SCALE, sub(3, 18)) }
			case 10000 { result := mul(SCALE, sub(4, 18)) }
			case 100000 { result := mul(SCALE, sub(5, 18)) }
			case 1000000 { result := mul(SCALE, sub(6, 18)) }
			case 10000000 { result := mul(SCALE, sub(7, 18)) }
			case 100000000 { result := mul(SCALE, sub(8, 18)) }
			case 1000000000 { result := mul(SCALE, sub(9, 18)) }
			case 10000000000 { result := mul(SCALE, sub(10, 18)) }
			case 100000000000 { result := mul(SCALE, sub(11, 18)) }
			case 1000000000000 { result := mul(SCALE, sub(12, 18)) }
			case 10000000000000 { result := mul(SCALE, sub(13, 18)) }
			case 100000000000000 { result := mul(SCALE, sub(14, 18)) }
			case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }
			case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }
			case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }
			case 1000000000000000000 { result := 0 }
			case 10000000000000000000 { result := SCALE }
			case 100000000000000000000 { result := mul(SCALE, 2) }
			case 1000000000000000000000 { result := mul(SCALE, 3) }
			case 10000000000000000000000 { result := mul(SCALE, 4) }
			case 100000000000000000000000 { result := mul(SCALE, 5) }
			case 1000000000000000000000000 { result := mul(SCALE, 6) }
			case 10000000000000000000000000 { result := mul(SCALE, 7) }
			case 100000000000000000000000000 { result := mul(SCALE, 8) }
			case 1000000000000000000000000000 { result := mul(SCALE, 9) }
			case 10000000000000000000000000000 { result := mul(SCALE, 10) }
			case 100000000000000000000000000000 { result := mul(SCALE, 11) }
			case 1000000000000000000000000000000 { result := mul(SCALE, 12) }
			case 10000000000000000000000000000000 { result := mul(SCALE, 13) }
			case 100000000000000000000000000000000 { result := mul(SCALE, 14) }
			case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }
			case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }
			case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }
			case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }
			case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }
			case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }
			case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }
			case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }
			case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }
			case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }
			case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }
			case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }
			case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }
			case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }
			case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }
			case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }
			case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }
			case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }
			case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }
			case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }
			case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }
			case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }
			case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }
			case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }
			case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }
			case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }
			case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }
			case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }
			case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }
			case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }
			case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }
			case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }
			case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }
			case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }
			case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }
			case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }
			case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }
			case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }
			case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }
			case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }
			case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }
			case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }
			case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }
			case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }
			case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) }
			default {
				result := MAX_UD60x18
			}
		}

		if (result == MAX_UD60x18) {
			// Do the fixed-point division inline to save gas. The denominator is log2(10).
			unchecked { result = (log2(x) * SCALE) / 332192809488736234; }
		}
	}

	/// @notice Calculates the binary logarithm of x.
	///
	/// @dev Based on the iterative approximation algorithm.
	/// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation
	///
	/// Requirements:
	/// - x must be greater than or equal to SCALE, otherwise the result would be negative.
	///
	/// Caveats:
	/// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.
	///
	/// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm.
	/// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number.
	function log2(uint256 x) internal pure returns (uint256 result) {
		require(x >= SCALE);
		unchecked {
			// Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).
			uint256 n = PRBMathCommon.mostSignificantBit(x / SCALE);

			// The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow
			// because n is maximum 255 and SCALE is 1e18.
			result = n * SCALE;

			// This is y = x * 2^(-n).
			uint256 y = x >> n;

			// If y = 1, the fractional part is zero.
			if (y == SCALE) {
				return result;
			}

			// Calculate the fractional part via the iterative approximation.
			// The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster.
			for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) {
				y = (y * y) / SCALE;

				// Is y^2 > 2 and so in the range [2,4)?
				if (y >= 2 * SCALE) {
					// Add the 2^(-m) factor to the logarithm.
					result += delta;

					// Corresponds to z/2 on Wikipedia.
					y >>= 1;
				}
			}
		}
	}

	/// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal
	/// fixed-point number.
	/// @dev See the documentation for the "PRBMathCommon.mulDivFixedPoint" function.
	/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.
	/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.
	/// @return result The result as an unsigned 60.18-decimal fixed-point number.
	function mul(uint256 x, uint256 y) internal pure returns (uint256 result) {
		result = PRBMathCommon.mulDivFixedPoint(x, y);
	}

	/// @notice Retrieves PI as an unsigned 60.18-decimal fixed-point number.
	function pi() internal pure returns (uint256 result) {
		result = 3141592653589793238;
	}

	/// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the
	/// famous algorithm "exponentiation by squaring".
	///
	/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring
	///
	/// Requirements:
	/// - The result must fit within MAX_UD60x18.
	///
	/// Caveats:
	/// - All from "mul".
	/// - Assumes 0^0 is 1.
	///
	/// @param x The base as an unsigned 60.18-decimal fixed-point number.
	/// @param y The exponent as an uint256.
	/// @return result The result as an unsigned 60.18-decimal fixed-point number.
	function pow(uint256 x, uint256 y) internal pure returns (uint256 result) {
		// Calculate the first iteration of the loop in advance.
		result = y & 1 > 0 ? x : SCALE;

		// Equivalent to "for(y /= 2; y > 0; y /= 2)" but faster.
		for (y >>= 1; y > 0; y >>= 1) {
			x = mul(x, x);

			// Equivalent to "y % 2 == 1" but faster.
			if (y & 1 > 0) {
				result = mul(result, x);
			}
		}
	}

	/// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number.
	function scale() internal pure returns (uint256 result) {
		result = SCALE;
	}

	/// @notice Calculates the square root of x, rounding down.
	/// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
	///
	/// Requirements:
	/// - x must be less than MAX_UD60x18 / SCALE.
	///
	/// Caveats:
	/// - The maximum fixed-point number permitted is 115792089237316195423570985008687907853269.984665640564039458.
	///
	/// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root.
	/// @return result The result as an unsigned 60.18-decimal fixed-point .
	function sqrt(uint256 x) internal pure returns (uint256 result) {
		require(x < 115792089237316195423570985008687907853269984665640564039458);
		unchecked {
			// Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned
			// 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).
			result = PRBMathCommon.sqrt(x * SCALE);
		}
	}
}

interface Callable {
	function tokenCallback(address _from, uint256 _tokens, bytes calldata _data) external returns (bool);
}

interface Router {
	function WETH() external pure returns (address);
	function factory() external pure returns (address);
	function addLiquidityETH(address _token, uint256 _amountTokenDesired, uint256 _amountTokenMin, uint256 _amountETHMin, address _to, uint256 _deadline) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
	function swapExactETHForTokens(uint256 _amountOutMin, address[] calldata _path, address _to, uint256 _deadline) external payable returns (uint256[] memory);
	function swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 _amountIn, uint256 _amountOutMin, address[] calldata _path, address _to, uint256 _deadline) external;
}

interface Factory {
	function getPair(address, address) external view returns (address);
	function createPair(address, address) external returns (address);
}

interface Pair {
	function token0() external view returns (address);
	function totalSupply() external view returns (uint256);
	function balanceOf(address) external view returns (uint256);
	function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}

interface ERC20 {
	function decimals() external view returns (uint8);
	function totalSupply() external view returns (uint256);
	function balanceOf(address) external view returns (uint256);
	function allowance(address, address) external view returns (uint256);
	function approve(address, uint256) external returns (bool);
	function transfer(address, uint256) external returns (bool);
	function transferFrom(address, address, uint256) external returns (bool);
}

interface WMATIC {
	function deposit() external payable;
	function withdraw(uint256) external;
}


contract Distributor {

	uint256 constant private LIQUIDITY_PERCENT = 40; // 40%

	struct Info {
		uint256 initialWAVE;
		uint256 totalDeposited;
		mapping(address => uint256) deposited;
		Router router;
		WAVE wave;
		bool active;
		uint256 targetTimestamp;
		address treasury;
	}
	Info private info;

	event Deposit(address indexed user, uint256 amount);
	event Claim(address indexed user, uint256 amount, uint256 tokens);

	constructor(uint256 _distributorEndTimestamp, address _treasury) {
		info.targetTimestamp = _distributorEndTimestamp;
		info.router = Router(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff);
		info.wave = WAVE(msg.sender);
		info.treasury = _treasury;
	}

	receive() external payable {
		deposit();
	}

	function deposit() public payable {
		require(!info.active);
		require(msg.value > 0);
		info.deposited[msg.sender] += msg.value;
		emit Deposit(msg.sender, msg.value);

		if (block.timestamp >= info.targetTimestamp) {
			require(msg.sender == tx.origin);
			address _this = address(this);
			info.initialWAVE = info.wave.balanceOf(_this);
			info.totalDeposited = _this.balance;
			uint256 _amount = info.initialWAVE * LIQUIDITY_PERCENT / 100;
			info.wave.approve(address(info.router), _amount);
			info.router.addLiquidityETH{value: _this.balance}(address(info.wave), _amount, 0, 0, _this, block.timestamp);
			ERC20 _pair = ERC20(info.wave.pairAddress());
			_pair.transfer(0xFaDED72464D6e76e37300B467673b36ECc4d2ccF, _pair.balanceOf(_this) / 20); // 5% developer fee
			_pair.transfer(info.treasury, _pair.balanceOf(_this));
			info.active = true;
		}
	}

	function claim() external {
		require(info.active);
		uint256 _deposited = info.deposited[msg.sender];
		if (_deposited > 0) {
			uint256 _maxClaimable = info.initialWAVE * (100 - LIQUIDITY_PERCENT) / 100;
			uint256 _claimable = _maxClaimable * _deposited / info.totalDeposited;
			info.deposited[msg.sender] = 0;
			info.wave.transfer(msg.sender, _claimable);
			emit Claim(msg.sender, _deposited, _claimable);
		}
	}

	function allInfoFor(address _user) external view returns (uint256 totalDeposited, uint256 maticBalance, uint256 targetTimestamp, uint256 userMATIC, uint256 userDeposited) {
		return (info.totalDeposited, address(this).balance, info.targetTimestamp, _user.balance, info.deposited[_user]);
	}
}


contract WAVE {

	uint256 constant private UINT_MAX = type(uint256).max;
	uint256 constant private TOTAL_SUPPLY = 1e25; // 10M WAVE

	string constant public name = "WAVE Token";
	string constant public symbol = "WAVE";
	uint8 constant public decimals = 18;

	struct User {
		uint256 balance;
		mapping(address => uint256) allowance;
	}

	struct Info {
		mapping(address => User) users;
		Router router;
		Pair pair;
		bool wmatic0;
		address distributor;
		address polywave;
	}
	Info private info;


	event Transfer(address indexed from, address indexed to, uint256 tokens);
	event Approval(address indexed owner, address indexed spender, uint256 tokens);


	constructor(uint256 _distributorTime, address _treasury) {
		info.router = Router(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff);
		info.pair = Pair(Factory(info.router.factory()).createPair(info.router.WETH(), address(this)));
		info.wmatic0 = info.pair.token0() == info.router.WETH();
		uint256 _half = TOTAL_SUPPLY / 2;
		info.polywave = msg.sender;
		info.users[info.polywave].balance = _half;
		emit Transfer(address(0x0), info.polywave, _half);
		info.distributor = address(new Distributor(_distributorTime, _treasury));
		info.users[address(info.distributor)].balance = _half;
		emit Transfer(address(0x0), address(info.distributor), _half);
	}

	function transfer(address _to, uint256 _tokens) external returns (bool) {
		return _transfer(msg.sender, _to, _tokens);
	}

	function approve(address _spender, uint256 _tokens) external returns (bool) {
		info.users[msg.sender].allowance[_spender] = _tokens;
		emit Approval(msg.sender, _spender, _tokens);
		return true;
	}

	function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool) {
		uint256 _allowance = allowance(_from, msg.sender);
		require(_allowance >= _tokens);
		if (_allowance != UINT_MAX) {
			info.users[_from].allowance[msg.sender] -= _tokens;
		}
		return _transfer(_from, _to, _tokens);
	}

	function transferAndCall(address _to, uint256 _tokens, bytes calldata _data) external returns (bool) {
		_transfer(msg.sender, _to, _tokens);
		uint32 _size;
		assembly {
			_size := extcodesize(_to)
		}
		if (_size > 0) {
			require(Callable(_to).tokenCallback(msg.sender, _tokens, _data));
		}
		return true;
	}
	

	function pairAddress() public view returns (address) {
		return address(info.pair);
	}
	
	function totalSupply() public pure returns (uint256) {
		return TOTAL_SUPPLY;
	}

	function circulatingSupply() public view returns (uint256) {
		return totalSupply() - balanceOf(info.distributor) - balanceOf(info.polywave) - balanceOf(pairAddress());
	}

	function balanceOf(address _user) public view returns (uint256) {
		return info.users[_user].balance;
	}

	function allowance(address _user, address _spender) public view returns (uint256) {
		return info.users[_user].allowance[_spender];
	}

	function allInfoFor(address _user) external view returns (uint256 totalTokens, uint256 circulatingTokens, uint256 totalLPTokens, uint256 wmaticReserve, uint256 waveReserve, uint256 userBalance, uint256 userLPBalance) {
		totalTokens = totalSupply();
		circulatingTokens = circulatingSupply();
		totalLPTokens = info.pair.totalSupply();
		(uint256 _res0, uint256 _res1, ) = info.pair.getReserves();
		wmaticReserve = info.wmatic0 ? _res0 : _res1;
		waveReserve = info.wmatic0 ? _res1 : _res0;
		userBalance = balanceOf(_user);
		userLPBalance = info.pair.balanceOf(_user);
	}


	function _transfer(address _from, address _to, uint256 _tokens) internal returns (bool) {
		require(balanceOf(_from) >= _tokens);
		info.users[_from].balance -= _tokens;
		info.users[_to].balance += _tokens;
		emit Transfer(_from, _to, _tokens);
		return true;
	}
}


contract Treasury {

	address public owner;

	constructor(address _owner) {
		owner = _owner;
	}

	function updateOwner(address _newOwner) external {
		require(msg.sender == owner);
		owner = _newOwner;
	}

	function transferToken(ERC20 _token, address _receiver, uint256 _amount) external {
		require(msg.sender == owner);
		_token.transfer(_receiver, _amount);
	}
}


contract polyWAVE {

	using PRBMathUD60x18 for uint256;

	uint256 constant private FLOAT_SCALAR = 2**64;
	uint256 constant private PERCENT_PRECISION = 1000; // 1 = 0.1%
	uint256 constant private X_TICK = 30 days;

	struct PoolUser {
		uint256 deposited;
		int256 scaledPayout;
	}

	struct Pool {
		address token;
		uint256 shares;
		uint256 lastUpdated;
		uint256 pendingFee;
		uint256 depositFee;
		uint256 withdrawFee;
		address extraSwapPath;
		uint256 scaledRewardsPerToken;
		uint256 totalDeposited;
		mapping(address => PoolUser) users;
	}

	struct Info {
		address owner;
		uint256 totalRewards;
		uint256 startTime;
		uint256 totalPools;
		uint256 totalPoolShares;
		mapping(uint256 => Pool) pools;
		mapping(address => uint256) indexOf;
		Router router;
		WAVE wave;
		address treasury;
	}
	Info private info;


	event PoolCreated(uint256 indexed index, address indexed token, uint256 shares, uint256 depositFee, uint256 withdrawFee, address extraSwapPath);
	event Deposit(uint256 indexed index, address indexed user, uint256 amount, uint256 fee);
	event Withdraw(uint256 indexed index, address indexed user, uint256 amount, uint256 fee);
	event Claim(uint256 indexed index, address indexed user, uint256 amount);
	event Reinvest(uint256 indexed index, address indexed user, uint256 amount);
	event PoolReward(uint256 indexed index, uint256 amount);


	constructor(uint256 _distributorEndTimestamp, uint256 _farmingStartTimestamp) {
		info.router = Router(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff);
		info.owner = msg.sender;
		info.treasury = address(new Treasury(msg.sender));
		info.startTime = _farmingStartTimestamp;
		info.wave = new WAVE(_distributorEndTimestamp, info.treasury);
		info.totalRewards = info.wave.balanceOf(address(this));
		_addInitialPools();
	}

	receive() external payable {
		require(msg.sender != tx.origin);
	}

	function updateOwner(address _newOwner) external {
		require(msg.sender == info.owner);
		info.owner = _newOwner;
	}

	function addPool(address _token, uint256 _shares, uint256 _depositFee, uint256 _withdrawFee, address _extraSwapPath) public {
		require(msg.sender == info.owner);
		require(info.indexOf[_token] == 0);
		require(_token == info.wave.pairAddress() || _token == info.router.WETH() || Factory(info.router.factory()).getPair(_token, _extraSwapPath == address(0x0) ? info.router.WETH() : _extraSwapPath) != address(0x0));
		require(_shares > 0);
		require(_depositFee < PERCENT_PRECISION);
		require(_withdrawFee < PERCENT_PRECISION);
		updateAllPools();
		Pool storage _newPool = info.pools[info.totalPools++];
		info.indexOf[_token] = info.totalPools;
		_newPool.token = _token;
		_newPool.shares = _shares;
		info.totalPoolShares += _shares;
		_newPool.depositFee = _depositFee;
		_newPool.withdrawFee = _withdrawFee;
		_newPool.extraSwapPath = _extraSwapPath;
		_newPool.lastUpdated = block.timestamp < info.startTime ? info.startTime : block.timestamp;
		emit PoolCreated(info.totalPools - 1, _token, _shares, _depositFee, _withdrawFee, _extraSwapPath);
	}

	function updateAllPools() public {
		for (uint256 i = 0; i < info.totalPools; i++) {
			updatePool(i);
		}
	}

	function updatePool(uint256 _index) public {
		require(_index < info.totalPools);
		Pool storage _pool = info.pools[_index];
		uint256 _now = block.timestamp;
		if (_now > _pool.lastUpdated && _pool.totalDeposited > 0) {
			uint256 _totalRewards = info.totalRewards.mul(_delta(_getX(_pool.lastUpdated), _getX(_now)));
			uint256 _poolRewards = _pool.shares * _totalRewards / info.totalPoolShares;
			_pool.scaledRewardsPerToken += _poolRewards * FLOAT_SCALAR / _pool.totalDeposited;
			_pool.lastUpdated = _now;
			emit PoolReward(_index, _poolRewards);
			if (_pool.pendingFee > 0) {
				_processFee(_pool, _pool.pendingFee);
				_pool.pendingFee = 0;
			}
		}
	}

	function deposit(uint256 _index, uint256 _amount) external {
		depositFor(msg.sender, _index, _amount);
	}

	function depositFor(address _user, uint256 _index, uint256 _amount) public {
		require(_index < info.totalPools);
		require(_amount > 0);
		updatePool(_index);
		Pool storage _pool = info.pools[_index];
		ERC20 _token = ERC20(_pool.token);
		_token.transferFrom(msg.sender, address(this), _amount);
		_deposit(_pool, _user, _amount);
	}

	function depositMATIC() external payable {
		require(msg.value > 0);
		uint256 _index = indexOfToken(info.router.WETH());
		updatePool(_index);
		Pool storage _pool = info.pools[_index];
		WMATIC(_pool.token).deposit{value: msg.value}();
		_deposit(_pool, msg.sender, msg.value);
	}

	function withdrawEverything() external {
		for (uint256 i = 0; i < info.totalPools; i++) {
			withdrawAll(i);
		}
	}

	function withdrawAll(uint256 _index) public {
		uint256 _deposited = info.pools[_index].users[msg.sender].deposited;
		if (_deposited > 0) {
			withdraw(_index, _deposited);
		}
	}

	function withdraw(uint256 _index, uint256 _amount) public {
		require(_index < info.totalPools);
		Pool storage _pool = info.pools[_index];
		require(_amount > 0 && _amount <= _pool.users[msg.sender].deposited);
		updatePool(_index);
		_pool.totalDeposited -= _amount;
		_pool.users[msg.sender].deposited -= _amount;
		_pool.users[msg.sender].scaledPayout -= int256(_amount * _pool.scaledRewardsPerToken);
		uint256 _fee = _calculateWithdrawFee(_pool, _amount);
		ERC20(_pool.token).transfer(msg.sender, _amount - _fee);
		_processFee(_pool, _fee);
		emit Withdraw(_index, msg.sender, _amount, _fee);
	}

	function claimEverything() external {
		for (uint256 i = 0; i < info.totalPools; i++) {
			claim(i);
		}
	}

	function claim(uint256 _index) public {
		if (isUserInPool(msg.sender, _index)) {
			updatePool(_index);
			uint256 _rewards = rewardsOf(msg.sender, _index);
			if (_rewards > 0) {
				info.pools[_index].users[msg.sender].scaledPayout += int256(_rewards * FLOAT_SCALAR);
				info.wave.transfer(msg.sender, _rewards);
				emit Claim(_index, msg.sender, _rewards);
			}
		}
	}

	function reinvestEverything() external {
		for (uint256 i = 0; i < info.totalPools; i++) {
			reinvest(i);
		}
	}

	function reinvest(uint256 _index) public {
		if (isUserInPool(msg.sender, _index)) {
			updatePool(_index);
			uint256 _rewards = rewardsOf(msg.sender, _index);
			if (_rewards > 0) {
				info.pools[_index].users[msg.sender].scaledPayout += int256(_rewards * FLOAT_SCALAR);
				uint256 _waveIndex = indexOfToken(address(info.wave));
				if (_waveIndex != _index) {
					updatePool(_waveIndex);
				}
				_deposit(info.pools[_waveIndex], msg.sender, _rewards);
				emit Reinvest(_index, msg.sender, _rewards);
			}
		}
	}

	
	function indexOfToken(address _token) public view returns (uint256) {
		uint256 _index = info.indexOf[_token];
		require(_index > 0);
		return _index - 1;
	}

	function isUserInPool(address _user, uint256 _index) public view returns (bool) {
		require(_index < info.totalPools);
		return info.pools[_index].users[_user].deposited > 0 || rewardsOf(_user, _index) > 0;
	}
	
	function rewardsOf(address _user, uint256 _index) public view returns (uint256) {
		require(_index < info.totalPools);
		Pool storage _pool = info.pools[_index];
		return uint256(int256(_pool.scaledRewardsPerToken * _pool.users[_user].deposited) - _pool.users[_user].scaledPayout) / FLOAT_SCALAR;
	}
	
	function currentRatePerDay() public view returns (uint256) {
		if (block.timestamp < info.startTime) {
			return 0;
		} else {
			return info.totalRewards.mul(_delta(_getX(block.timestamp), _getX(block.timestamp + 24 hours)));
		}
	}

	function totalDistributed() public view returns (uint256) {
		return info.totalRewards.mul(_sum(_getX(block.timestamp)));
	}

	function poolInfoFor(address _user, uint256 _index) public view returns (address tokenAddress, address extraSwapPath, uint256[11] memory compressedInfo) {
		require(_index < info.totalPools);
		Pool storage _pool = info.pools[_index];
		tokenAddress = _pool.token;
		extraSwapPath = _pool.extraSwapPath;
		compressedInfo[0] = _pool.shares;
		compressedInfo[1] = _calculateDepositFee(_pool, 1e20);
		compressedInfo[2] = _calculateWithdrawFee(_pool, 1e20);
		compressedInfo[3] = _pool.totalDeposited;
		compressedInfo[4] = block.timestamp > _pool.lastUpdated ? _pool.shares * info.totalRewards.mul(_delta(_getX(_pool.lastUpdated), _getX(block.timestamp))) / info.totalPoolShares : 0;
		ERC20 _token = ERC20(tokenAddress);
		if (tokenAddress == info.wave.pairAddress()) {
			if (_token.totalSupply() > 0) {
				compressedInfo[5] = 2e18 * ERC20(info.router.WETH()).balanceOf(tokenAddress) / _token.totalSupply();
			}
		} else if (tokenAddress == info.router.WETH()) {
			compressedInfo[5] = 1e18;
		} else {
			Pair _pair = Pair(Factory(info.router.factory()).getPair(tokenAddress, extraSwapPath == address(0x0) ? info.router.WETH() : extraSwapPath));
			(uint256 _res0, uint256 _res1, ) = _pair.getReserves();
			bool _token0 = _pair.token0() == tokenAddress;
			if (extraSwapPath == address(0x0)) {
				if (_token0) {
					compressedInfo[5] = _res0 > 0 ? 10**(_token.decimals()) * _res1 / _res0 : 0;
				} else {
					compressedInfo[5] = _res1 > 0 ? 10**(_token.decimals()) * _res0 / _res1 : 0;
				}
			} else {
				Pair _extraPair = Pair(Factory(info.router.factory()).getPair(extraSwapPath, info.router.WETH()));
				(uint256 _extraRes0, uint256 _extraRes1, ) = _extraPair.getReserves();
				bool _extraToken0 = _extraPair.token0() == extraSwapPath;
				ERC20 _extraToken = ERC20(extraSwapPath);
				uint256 _preRate = 0;
				if (_token0) {
					_preRate = _res0 > 0 ? 10**(18 + _token.decimals() - _extraToken.decimals()) * _res1 / _res0 : 0;
				} else {
					_preRate = _res1 > 0 ? 10**(18 + _token.decimals() - _extraToken.decimals()) * _res0 / _res1 : 0;
				}
				if (_extraToken0) {
					compressedInfo[5] = _preRate > 0 && _extraRes0 > 0 ? _preRate * _extraRes1 / _extraRes0 / 10**(18 - _extraToken.decimals()) : 0;
				} else {
					compressedInfo[5] = _preRate > 0 && _extraRes1 > 0 ? _preRate * _extraRes0 / _extraRes1 / 10**(18 - _extraToken.decimals()) : 0;
				}
			}
		}
		compressedInfo[6] = _token.decimals();
		compressedInfo[7] = _pool.users[_user].deposited;
		compressedInfo[8] = rewardsOf(_user, _index);
		compressedInfo[9] = _token.balanceOf(_user);
		compressedInfo[10] = _token.allowance(_user, address(this));
	}

	function allInfoFor(address _user) external view returns (uint256 startTime, uint256 totalRewardsDistributed, uint256 rewardsRatePerDay, uint256 userMATIC, address[] memory tokenAddresses, address[] memory extraSwapPaths, uint256[11][] memory compressedInfos) {
		startTime = info.startTime;
		totalRewardsDistributed = totalDistributed();
		rewardsRatePerDay = currentRatePerDay();
		userMATIC = _user.balance;
		uint256 _length = info.totalPools;
		tokenAddresses = new address[](_length);
		extraSwapPaths = new address[](_length);
		compressedInfos = new uint256[11][](_length);
		for (uint256 i = 0; i < _length; i++) {
			(tokenAddresses[i], extraSwapPaths[i], compressedInfos[i]) = poolInfoFor(_user, i);
		}
	}


	function _addInitialPools() internal {
		address _weth = 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619;
		address _usdc = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
		address _surf = 0x1E42EDbe5376e717C1B22904C59e406426E8173F;

		addPool(address(info.wave), 100, 50, 50, address(0x0)); // WAVE
		addPool(info.wave.pairAddress(), 100, 0, 0, address(0x0)); // WAVE/MATIC LP
		addPool(_surf, 80, 0, 0, address(0x0)); // SURF
		addPool(0x1E946cA17b893Ab0f22cF1951137624eE9E689EF, 45, 0, 0, address(0x0)); // TOWEL
		addPool(_usdc, 40, 25, 15, address(0x0)); // USDC
		addPool(0xc2132D05D31c914a87C6611C10748AEb04B58e8F, 40, 25, 15, _usdc); // USDT
		addPool(0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063, 40, 25, 15, _usdc); // DAI
		addPool(info.router.WETH(), 35, 25, 15, address(0x0)); // WMATIC
		addPool(_weth, 35, 25, 15, address(0x0)); // WETH
		addPool(0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6, 35, 25, 15, _weth); // WBTC
		addPool(0xb33EaAd8d922B1083446DC23f610c2567fB5180f, 25, 25, 15, _weth); // UNI
		addPool(0x831753DD7087CaC61aB5644b308642cc1c33Dc13, 25, 25, 15, address(0x0)); // QUICK
		addPool(0xD6DF932A45C0f255f85145f286eA0b292B21C90B, 25, 25, 15, _weth); // AAVE
		addPool(0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39, 25, 25, 15, _weth); // LINK
		addPool(0x37D1EbC3Af809b8fADB45DCE7077eFc629b2B5BB, 10, 25, 15, _surf); // pCOMB
		addPool(0xDa6f81C2426131337B0CF73768B94c2004390b0E, 10, 25, 15, _surf); // LMAO
		addPool(0xaAa5B9e6c589642f98a1cDA99B9D024B8407285A, 10, 25, 15, _weth); // TITAN
		addPool(0xA5d447757daC8C5FaAB1858B13DA4aF701aDf4bb, 5, 0, 0, _weth); // wRBT
		addPool(0xEB7f7955730A7DBA1427A6567950eb4a98DfCbdF, 5, 0, 0, _surf); // WLEV
	}

	function _deposit(Pool storage _pool, address _user, uint256 _amount) internal {
		uint256 _fee = _calculateDepositFee(_pool, _amount);
		uint256 _deposited = _amount - _fee;
		_pool.totalDeposited += _deposited;
		_pool.users[_user].deposited += _deposited;
		_pool.users[_user].scaledPayout += int256(_deposited * _pool.scaledRewardsPerToken);
		_processFee(_pool, _fee);
		emit Deposit(indexOfToken(_pool.token), _user, _amount, _fee);
	}
	
	function _processFee(Pool storage _pool, uint256 _fee) internal {
		if (_fee > 0) {
			if (block.timestamp < info.startTime) {
				_pool.pendingFee += _fee;
			} else {
				if (_pool.token == address(info.wave)) {
					_pool.scaledRewardsPerToken += _fee * FLOAT_SCALAR / _pool.totalDeposited;
					emit PoolReward(indexOfToken(_pool.token), _fee);
				} else {

					// fee breakdown:
					// 33.3% -> treasury (as tokens)
					// 33.3% -> buying WAVE
					//  - half is distributed as pool rewards
					//  - half is supplied as liquidity and locked
					// 16.7% -> supplied with WAVE for liquidity (as MATIC)
					// 16.7% -> buying TOWEL
					
					uint256 _treasuryFee = _fee / 3;
					ERC20(_pool.token).transfer(info.treasury, _treasuryFee);

					address _this = address(this);
					address[] memory _path;
					if (_pool.token == info.router.WETH()) {
						WMATIC(_pool.token).withdraw(_fee - _treasuryFee);
					} else {
						_path = new address[](_pool.extraSwapPath == address(0x0) ? 2 : 3);
						_path[0] = _pool.token;
						if (_pool.extraSwapPath == address(0x0)) {
							_path[1] = info.router.WETH();
						} else {
							_path[1] = _pool.extraSwapPath;
							_path[2] = info.router.WETH();
						}
						ERC20(_pool.token).approve(address(info.router), _fee - _treasuryFee);
						info.router.swapExactTokensForETHSupportingFeeOnTransferTokens(_fee - _treasuryFee, 0, _path, _this, block.timestamp);
					}

					_path = new address[](2);
					_path[0] = info.router.WETH();
					_path[1] = address(info.wave);
					uint256 _balanceBefore = info.wave.balanceOf(_this);
					info.router.swapExactETHForTokens{value: _this.balance / 2}(0, _path, _this, block.timestamp);
					uint256 _amountReceived = info.wave.balanceOf(_this) - _balanceBefore;
					uint256 _half = _amountReceived / 2;
					info.wave.approve(address(info.router), _half);
					info.router.addLiquidityETH{value: _this.balance}(address(info.wave), _half, 0, 0, info.treasury, block.timestamp);
					_pool.scaledRewardsPerToken += _half * FLOAT_SCALAR / _pool.totalDeposited;
					emit PoolReward(indexOfToken(_pool.token), _half);

					if (_this.balance > 0) {
						_path[1] = 0x1E946cA17b893Ab0f22cF1951137624eE9E689EF;
						info.router.swapExactETHForTokens{value: _this.balance}(0, _path, info.treasury, block.timestamp);
					}
				}
			}
		}
	}

	function _calculateDepositFee(Pool storage _pool, uint256 _amount) internal view returns (uint256) {
		return (_amount * _pool.depositFee / PERCENT_PRECISION).mul(1e18 - _sum(_getX(block.timestamp)));
	}

	function _calculateWithdrawFee(Pool storage _pool, uint256 _amount) internal view returns (uint256) {
		return (_amount * _pool.withdrawFee / PERCENT_PRECISION).mul(1e18 - _sum(_getX(block.timestamp)) / 2);
	}
	
	function _getX(uint256 t) internal view returns (uint256) {
		uint256 _start = info.startTime;
		if (t < _start) {
			return 0;
		} else {
			return ((t - _start) * 1e18).div(X_TICK * 1e18);
		}
	}

	function _sum(uint256 x) internal pure returns (uint256) {
		uint256 _e2x = x.exp2();
		return (_e2x - 1e18).div(_e2x);
	}

	function _delta(uint256 x1, uint256 x2) internal pure returns (uint256) {
		require(x2 >= x1);
		return _sum(x2) - _sum(x1);
	}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_distributorTime","type":"uint256"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"allInfoFor","outputs":[{"internalType":"uint256","name":"totalTokens","type":"uint256"},{"internalType":"uint256","name":"circulatingTokens","type":"uint256"},{"internalType":"uint256","name":"totalLPTokens","type":"uint256"},{"internalType":"uint256","name":"wmaticReserve","type":"uint256"},{"internalType":"uint256","name":"waveReserve","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"},{"internalType":"uint256","name":"userLPBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"transferAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200198138038062001981833981016040819052620000349162000492565b600180546001600160a01b03191673a5e0829caced8ffdd4de3c43696c57f7d7a678ff9081179091556040805163c45a015560e01b8152905163c45a015591600480820192602092909190829003018186803b1580156200009457600080fd5b505afa158015620000a9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000cf91906200046d565b600154604080516315ab88c960e31b815290516001600160a01b039384169363c9c6539693169163ad5c4648916004808301926020929190829003018186803b1580156200011c57600080fd5b505afa15801562000131573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200015791906200046d565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381600087803b1580156200019f57600080fd5b505af1158015620001b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001da91906200046d565b600280546001600160a01b0319166001600160a01b03928316179055600154604080516315ab88c960e31b81529051919092169163ad5c4648916004808301926020929190829003018186803b1580156200023457600080fd5b505afa15801562000249573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200026f91906200046d565b6001600160a01b0316600060020160009054906101000a90046001600160a01b03166001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015620002ca57600080fd5b505afa158015620002df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200030591906200046d565b6001600160a01b031614600060020160146101000a81548160ff021916908315150217905550600060026a084595161401484a000000620003479190620004c1565b600480546001600160a01b031916339081178255600090815260208181526040808320859055925492518481529394506001600160a01b0390921692909160008051602062001961833981519152910160405180910390a38282604051620003af9062000442565b9182526001600160a01b03166020820152604001604051809103906000f080158015620003e0573d6000803e3d6000fd5b50600380546001600160a01b0319166001600160a01b039283169081178255600090815260208181526040808320869055925492518581529290931692909160008051602062001961833981519152910160405180910390a3505050620004e4565b6109b28062000faf83390190565b80516001600160a01b03811681146200046857600080fd5b919050565b6000602082840312156200048057600080fd5b6200048b8262000450565b9392505050565b60008060408385031215620004a657600080fd5b82519150620004b86020840162000450565b90509250929050565b600082620004df57634e487b7160e01b600052601260045260246000fd5b500490565b610abb80620004f46000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806357f6b8121161008c57806395d89b411161006657806395d89b411461020a578063a8b089821461022d578063a9059cbb14610248578063dd62ed3e1461025b57600080fd5b806357f6b8121461019157806370a08231146101d95780639358928b1461020257600080fd5b806306fdde03146100d4578063095ea7b31461011357806318160ddd1461013657806323b872dd14610151578063313ce567146101645780634000aea01461017e575b600080fd5b6100fd6040518060400160405280600a8152602001692ba0ab22902a37b5b2b760b11b81525081565b60405161010a91906109eb565b60405180910390f35b610126610121366004610867565b610296565b604051901515815260200161010a565b6a084595161401484a0000005b60405190815260200161010a565b61012661015f36600461082b565b6102ff565b61016c601281565b60405160ff909116815260200161010a565b61012661018c366004610891565b610388565b6101a461019f3660046107dd565b61043d565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e00161010a565b6101436101e73660046107dd565b6001600160a01b031660009081526020819052604090205490565b610143610650565b6100fd604051806040016040528060048152602001635741564560e01b81525081565b6002546040516001600160a01b03909116815260200161010a565b610126610256366004610867565b6106be565b6101436102693660046107f8565b6001600160a01b039182166000908152602081815260408083209390941682526001909201909152205490565b336000818152602081815260408083206001600160a01b0387168085526001909101835281842086905590518581529293909290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350600192915050565b6001600160a01b0383166000908152602081815260408083203384526001019091528120548281101561033157600080fd5b6000198114610374576001600160a01b0385166000908152602081815260408083203384526001019091528120805485929061036e908490610a58565b90915550505b61037f8585856106d2565b95945050505050565b60006103953386866106d2565b50843b63ffffffff81161561043157604051636be32e7360e01b81526001600160a01b03871690636be32e73906103d69033908990899089906004016109a3565b602060405180830381600087803b1580156103f057600080fd5b505af1158015610404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104289190610918565b61043157600080fd5b50600195945050505050565b6a084595161401484a00000060008080808080610458610650565b600254604080516318160ddd60e01b815290519298506001600160a01b03909116916318160ddd91600480820192602092909190829003018186803b1580156104a057600080fd5b505afa1580156104b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d8919061098a565b60025460408051630240bc6b60e21b8152905192975060009283926001600160a01b031691630902f1ac916004808301926060929190829003018186803b15801561052257600080fd5b505afa158015610536573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055a919061093a565b506002546001600160701b03928316945091169150600160a01b900460ff166105835780610585565b815b600254909650600160a01b900460ff1661059f57816105a1565b805b94506105c28a6001600160a01b031660009081526020819052604090205490565b6002546040516370a0823160e01b81526001600160a01b038d811660048301529296509116906370a082319060240160206040518083038186803b15801561060957600080fd5b505afa15801561061d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610641919061098a565b92505050919395979092949650565b60006106676101e76002546001600160a01b031690565b6004546001600160a01b039081166000908152602081905260408082205460035490931682529020546106a5906a084595161401484a000000610a58565b6106af9190610a58565b6106b99190610a58565b905090565b60006106cb3384846106d2565b9392505050565b6001600160a01b0383166000908152602081905260408120548211156106f757600080fd5b6001600160a01b0384166000908152602081905260408120805484929061071f908490610a58565b90915550506001600160a01b0383166000908152602081905260408120805484929061074c908490610a40565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161079891815260200190565b60405180910390a35060019392505050565b80356001600160a01b03811681146107c157600080fd5b919050565b80516001600160701b03811681146107c157600080fd5b6000602082840312156107ef57600080fd5b6106cb826107aa565b6000806040838503121561080b57600080fd5b610814836107aa565b9150610822602084016107aa565b90509250929050565b60008060006060848603121561084057600080fd5b610849846107aa565b9250610857602085016107aa565b9150604084013590509250925092565b6000806040838503121561087a57600080fd5b610883836107aa565b946020939093013593505050565b600080600080606085870312156108a757600080fd5b6108b0856107aa565b935060208501359250604085013567ffffffffffffffff808211156108d457600080fd5b818701915087601f8301126108e857600080fd5b8135818111156108f757600080fd5b88602082850101111561090957600080fd5b95989497505060200194505050565b60006020828403121561092a57600080fd5b815180151581146106cb57600080fd5b60008060006060848603121561094f57600080fd5b610958846107c6565b9250610966602085016107c6565b9150604084015163ffffffff8116811461097f57600080fd5b809150509250925092565b60006020828403121561099c57600080fd5b5051919050565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600060208083528351808285015260005b81811015610a18578581018301518582016040015282016109fc565b81811115610a2a576000604083870101525b50601f01601f1916929092016040019392505050565b60008219821115610a5357610a53610a6f565b500190565b600082821015610a6a57610a6a610a6f565b500390565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220af817e70bc196c9243f6cf31aa1e5af9bf4486d06814d76c73002372ee0b14bd64736f6c63430008060033608060405234801561001057600080fd5b506040516109b23803806109b283398101604081905261002f91610086565b6005919091556003805473a5e0829caced8ffdd4de3c43696c57f7d7a678ff6001600160a01b0319918216179091556004805433908316179055600680549091166001600160a01b039092169190911790556100c3565b6000806040838503121561009957600080fd5b825160208401519092506001600160a01b03811681146100b857600080fd5b809150509250929050565b6108e0806100d26000396000f3fe6080604052600436106100385760003560e01c80634e71d92d1461004c57806357f6b81214610061578063d0e30db0146100d457600080fd5b36610047576100456100d8565b005b600080fd5b34801561005857600080fd5b50610045610618565b34801561006d57600080fd5b506100a861007c366004610765565b6001546005546001600160a01b0392909216600081815260026020526040902054919347939291319190565b604080519586526020860194909452928401919091526060830152608082015260a00160405180910390f35b6100455b600454600160a01b900460ff16156100ef57600080fd5b600034116100fc57600080fd5b336000908152600260205260408120805434929061011b90849061080f565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a260055442106106165733321461016a57600080fd5b600480546040516370a0823160e01b8152309281018390526001600160a01b03909116906370a082319060240160206040518083038186803b1580156101af57600080fd5b505afa1580156101c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e791906107c8565b60008181556001600160a01b038316316001559060649061020a90602890610849565b6102149190610827565b6004805460035460405163095ea7b360e01b81526001600160a01b039182169381019390935260248301849052929350919091169063095ea7b390604401602060405180830381600087803b15801561026c57600080fd5b505af1158015610280573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a491906107a6565b506003546004805460405163f305d71960e01b81526001600160a01b0391821692810192909252602482018490526000604483018190526064830152848116608483018190524260a484015292169163f305d7199190319060c4016060604051808303818588803b15801561031857600080fd5b505af115801561032c573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061035191906107e1565b5050600480546040805163545844c160e11b81529051600094506001600160a01b039092169263a8b08982928282019260209290829003018186803b15801561039957600080fd5b505afa1580156103ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d19190610789565b6040516370a0823160e01b81526001600160a01b0385811660048301529192509082169063a9059cbb9073faded72464d6e76e37300b467673b36ecc4d2ccf9060149084906370a082319060240160206040518083038186803b15801561043757600080fd5b505afa15801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046f91906107c8565b6104799190610827565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156104bf57600080fd5b505af11580156104d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f791906107a6565b506006546040516370a0823160e01b81526001600160a01b0385811660048301528381169263a9059cbb9291169083906370a082319060240160206040518083038186803b15801561054857600080fd5b505afa15801561055c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058091906107c8565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156105c657600080fd5b505af11580156105da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105fe91906107a6565b50506004805460ff60a01b1916600160a01b17905550505b565b600454600160a01b900460ff1661062e57600080fd5b3360009081526002602052604090205480156107625760006064610653602882610868565b6000546106609190610849565b61066a9190610827565b60015490915060009061067d8484610849565b6106879190610827565b336000818152600260205260408082209190915560048054915163a9059cbb60e01b815290810192909252602482018390529192506001600160a01b039091169063a9059cbb90604401602060405180830381600087803b1580156106eb57600080fd5b505af11580156106ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072391906107a6565b50604080518481526020810183905233917f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf7910160405180910390a250505b50565b60006020828403121561077757600080fd5b813561078281610895565b9392505050565b60006020828403121561079b57600080fd5b815161078281610895565b6000602082840312156107b857600080fd5b8151801515811461078257600080fd5b6000602082840312156107da57600080fd5b5051919050565b6000806000606084860312156107f657600080fd5b8351925060208401519150604084015190509250925092565b600082198211156108225761082261087f565b500190565b60008261084457634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156108635761086361087f565b500290565b60008282101561087a5761087a61087f565b500390565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461076257600080fdfea2646970667358221220733c7ed29492638bb56449a1b0e51955937d202949f3d017a6c3895d4089a29964736f6c63430008060033ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000000000000000000000000000000000006105f210000000000000000000000000de4c22d69afe3c49ca3acad20bb4777eb5aebd75

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000006105f210000000000000000000000000de4c22d69afe3c49ca3acad20bb4777eb5aebd75

-----Decoded View---------------
Arg [0] : _distributorTime (uint256): 1627779600
Arg [1] : _treasury (address): 0xde4c22d69afe3c49ca3acad20bb4777eb5aebd75

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000006105f210
Arg [1] : 000000000000000000000000de4c22d69afe3c49ca3acad20bb4777eb5aebd75


Deployed ByteCode Sourcemap

42721:3819:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42860:42;;;;;;;;;;;;;-1:-1:-1;;;42860:42:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;44202:203;;;;;;:::i;:::-;;:::i;:::-;;;4034:14:1;;4027:22;4009:41;;3997:2;3982:18;44202:203:0;3964:92:1;45161:82:0;42838:4;45161:82;;;4809:25:1;;;4797:2;4782:18;45161:82:0;4764:76:1;44410:321:0;;;;;;:::i;:::-;;:::i;42948:35::-;;42981:2;42948:35;;;;;5629:4:1;5617:17;;;5599:36;;5587:2;5572:18;42948:35:0;5554:87:1;44736:323:0;;;;;;:::i;:::-;;:::i;45678:583::-;;;;;;:::i;:::-;;:::i;:::-;;;;5160:25:1;;;5216:2;5201:18;;5194:34;;;;5244:18;;;5237:34;;;;5302:2;5287:18;;5280:34;;;;5345:3;5330:19;;5323:35;5389:3;5374:19;;5367:35;5433:3;5418:19;;5411:35;5147:3;5132:19;45678:583:0;5114:338:1;45426:106:0;;;;;;:::i;:::-;-1:-1:-1;;;;;45502:17:0;45481:7;45502:17;;;;;;;;;;:25;;45426:106;45248:173;;;:::i;42906:38::-;;;;;;;;;;;;;-1:-1:-1;;;42906:38:0;;;;;;;;45067:88;45140:9;;45067:88;;-1:-1:-1;;;;;45140:9:0;;;3243:51:1;;3231:2;3216:18;45067:88:0;3198:102:1;44073:124:0;;;;;;:::i;:::-;;:::i;45537:136::-;;;;;;:::i;:::-;-1:-1:-1;;;;;45631:17:0;;;45610:7;45631:17;;;;;;;;;;;:37;;;;;;-1:-1:-1;45631:27:0;;;:37;;;;;;45537:136;44202:203;44294:10;44272:4;44283:22;;;;;;;;;;;-1:-1:-1;;;;;44283:42:0;;;;;-1:-1:-1;44283:32:0;;;:42;;;;;:52;;;44345:39;;4809:25:1;;;44345:39:0;;44272:4;;44283:42;;44294:10;;44345:39;;;;;;;;-1:-1:-1;44396:4:0;44202:203;;;;:::o;44410:321::-;-1:-1:-1;;;;;45631:17:0;;44495:4;45631:17;;;;;;;;;;;44544:10;45631:37;;-1:-1:-1;45631:27:0;:37;;;;;;44568:21;;;;44560:30;;;;;;-1:-1:-1;;44599:22:0;;44595:90;;-1:-1:-1;;;;;44629:17:0;;:4;:17;;;;;;;;;;;44657:10;44629:39;;-1:-1:-1;44629:27:0;:39;;;;;:50;;44672:7;;44629:4;:50;;44672:7;;44629:50;:::i;:::-;;;;-1:-1:-1;;44595:90:0;44696:30;44706:5;44713:3;44718:7;44696:9;:30::i;:::-;44689:37;44410:321;-1:-1:-1;;;;;44410:321:0:o;44736:323::-;44831:4;44842:35;44852:10;44864:3;44869:7;44842:9;:35::i;:::-;-1:-1:-1;44923:16:0;;44952:9;;;;44948:91;;44977:55;;-1:-1:-1;;;44977:55:0;;-1:-1:-1;;;;;44977:27:0;;;-1:-1:-1;;44977:55:0;;45005:10;;45017:7;;45026:5;;;;44977:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44969:64;;;;;;-1:-1:-1;45050:4:0;;44736:323;-1:-1:-1;;;;;44736:323:0:o;45678:583::-;42838:4;45736:19;;;;;;45952;:17;:19::i;:::-;45992:9;;:23;;;-1:-1:-1;;;45992:23:0;;;;45932:39;;-1:-1:-1;;;;;;45992:9:0;;;;-1:-1:-1;;45992:23:0;;;;;;;;;;;;;;;:9;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46055:9;;:23;;;-1:-1:-1;;;46055:23:0;;;;45976:39;;-1:-1:-1;46021:13:0;;;;-1:-1:-1;;;;;46055:9:0;;:21;;:23;;;;;;;;;;;;;;:9;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;46099:12:0;;-1:-1:-1;;;;;46020:58:0;;;;-1:-1:-1;46020:58:0;;;-1:-1:-1;;;;46099:12:0;;;;:28;;46122:5;46099:28;;;46114:5;46099:28;46146:12;;46083:44;;-1:-1:-1;;;;46146:12:0;;;;:28;;46169:5;46146:28;;;46161:5;46146:28;-1:-1:-1;;;;;45502:17:0;;45481:7;45502:17;;;;;;;;;;:25;46132:42;;-1:-1:-1;46230:9:0;;:26;;-1:-1:-1;;;46230:26:0;;-1:-1:-1;;;;;3261:32:1;;;46230:26:0;;;3243:51:1;46179:30:0;;-1:-1:-1;46230:9:0;;;:19;;3216:18:1;;46230:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46214:42;;45895:366;;45678:583;;;;;;;;;:::o;45248:173::-;45140:9;;45298:7;;45392:24;;-1:-1:-1;;;;;45140:9:0;45402:13;45067:88;45392:24;45375:13;;-1:-1:-1;;;;;45375:13:0;;;45481:7;45502:17;;;;;;;;;;;:25;45345:16;;;;;45502:17;;;;:25;45319:43;;42838:4;45319:43;:::i;:::-;:70;;;;:::i;:::-;:97;;;;:::i;:::-;45312:104;;45248:173;:::o;44073:124::-;44139:4;44157:35;44167:10;44179:3;44184:7;44157:9;:35::i;:::-;44150:42;44073:124;-1:-1:-1;;;44073:124:0:o;46268:269::-;-1:-1:-1;;;;;45502:17:0;;46350:4;45502:17;;;;;;;;;;:25;-1:-1:-1;;46369:27:0;46361:36;;;;;;-1:-1:-1;;;;;46402:17:0;;:4;:17;;;;;;;;;;:36;;46431:7;;46402:4;:36;;46431:7;;46402:36;:::i;:::-;;;;-1:-1:-1;;;;;;;46443:15:0;;:4;:15;;;;;;;;;;:34;;46470:7;;46443:4;:34;;46470:7;;46443:34;:::i;:::-;;;;-1:-1:-1;;46487:29:0;;4809:25:1;;;-1:-1:-1;;;;;46487:29:0;;;;;;;;;;4797:2:1;4782:18;46487:29:0;;;;;;;-1:-1:-1;46528:4:0;46268:269;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:188::-;271:13;;-1:-1:-1;;;;;313:42:1;;303:53;;293:2;;370:1;367;360:12;385:186;444:6;497:2;485:9;476:7;472:23;468:32;465:2;;;513:1;510;503:12;465:2;536:29;555:9;536:29;:::i;576:260::-;644:6;652;705:2;693:9;684:7;680:23;676:32;673:2;;;721:1;718;711:12;673:2;744:29;763:9;744:29;:::i;:::-;734:39;;792:38;826:2;815:9;811:18;792:38;:::i;:::-;782:48;;663:173;;;;;:::o;841:328::-;918:6;926;934;987:2;975:9;966:7;962:23;958:32;955:2;;;1003:1;1000;993:12;955:2;1026:29;1045:9;1026:29;:::i;:::-;1016:39;;1074:38;1108:2;1097:9;1093:18;1074:38;:::i;:::-;1064:48;;1159:2;1148:9;1144:18;1131:32;1121:42;;945:224;;;;;:::o;1174:254::-;1242:6;1250;1303:2;1291:9;1282:7;1278:23;1274:32;1271:2;;;1319:1;1316;1309:12;1271:2;1342:29;1361:9;1342:29;:::i;:::-;1332:39;1418:2;1403:18;;;;1390:32;;-1:-1:-1;;;1261:167:1:o;1433:733::-;1521:6;1529;1537;1545;1598:2;1586:9;1577:7;1573:23;1569:32;1566:2;;;1614:1;1611;1604:12;1566:2;1637:29;1656:9;1637:29;:::i;:::-;1627:39;;1713:2;1702:9;1698:18;1685:32;1675:42;;1768:2;1757:9;1753:18;1740:32;1791:18;1832:2;1824:6;1821:14;1818:2;;;1848:1;1845;1838:12;1818:2;1886:6;1875:9;1871:22;1861:32;;1931:7;1924:4;1920:2;1916:13;1912:27;1902:2;;1953:1;1950;1943:12;1902:2;1993;1980:16;2019:2;2011:6;2008:14;2005:2;;;2035:1;2032;2025:12;2005:2;2080:7;2075:2;2066:6;2062:2;2058:15;2054:24;2051:37;2048:2;;;2101:1;2098;2091:12;2048:2;1556:610;;;;-1:-1:-1;;2132:2:1;2124:11;;-1:-1:-1;;;1556:610:1:o;2171:277::-;2238:6;2291:2;2279:9;2270:7;2266:23;2262:32;2259:2;;;2307:1;2304;2297:12;2259:2;2339:9;2333:16;2392:5;2385:13;2378:21;2371:5;2368:32;2358:2;;2414:1;2411;2404:12;2453:450;2540:6;2548;2556;2609:2;2597:9;2588:7;2584:23;2580:32;2577:2;;;2625:1;2622;2615:12;2577:2;2648:40;2678:9;2648:40;:::i;:::-;2638:50;;2707:49;2752:2;2741:9;2737:18;2707:49;:::i;:::-;2697:59;;2799:2;2788:9;2784:18;2778:25;2843:10;2836:5;2832:22;2825:5;2822:33;2812:2;;2869:1;2866;2859:12;2812:2;2892:5;2882:15;;;2567:336;;;;;:::o;2908:184::-;2978:6;3031:2;3019:9;3010:7;3006:23;3002:32;2999:2;;;3047:1;3044;3037:12;2999:2;-1:-1:-1;3070:16:1;;2989:103;-1:-1:-1;2989:103:1:o;3305:559::-;-1:-1:-1;;;;;3518:32:1;;3500:51;;3582:2;3567:18;;3560:34;;;3630:2;3625;3610:18;;3603:30;;;3649:18;;3642:34;;;;3719:6;3713:3;3698:19;;3685:49;3784:1;3754:22;;;3778:3;3750:32;;;3743:43;;;;3847:2;3826:15;;;-1:-1:-1;;3822:29:1;3807:45;3803:55;;3490:374;-1:-1:-1;;;3490:374:1:o;4061:597::-;4173:4;4202:2;4231;4220:9;4213:21;4263:6;4257:13;4306:6;4301:2;4290:9;4286:18;4279:34;4331:1;4341:140;4355:6;4352:1;4349:13;4341:140;;;4450:14;;;4446:23;;4440:30;4416:17;;;4435:2;4412:26;4405:66;4370:10;;4341:140;;;4499:6;4496:1;4493:13;4490:2;;;4569:1;4564:2;4555:6;4544:9;4540:22;4536:31;4529:42;4490:2;-1:-1:-1;4642:2:1;4621:15;-1:-1:-1;;4617:29:1;4602:45;;;;4649:2;4598:54;;4182:476;-1:-1:-1;;;4182:476:1:o;5646:128::-;5686:3;5717:1;5713:6;5710:1;5707:13;5704:2;;;5723:18;;:::i;:::-;-1:-1:-1;5759:9:1;;5694:80::o;5779:125::-;5819:4;5847:1;5844;5841:8;5838:2;;;5852:18;;:::i;:::-;-1:-1:-1;5889:9:1;;5828:76::o;5909:127::-;5970:10;5965:3;5961:20;5958:1;5951:31;6001:4;5998:1;5991:15;6025:4;6022:1;6015:15

Swarm Source

ipfs://733c7ed29492638bb56449a1b0e51955937d202949f3d017a6c3895d4089a299
Loading