// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
// BurnWars V27.4.0 — standalone Remix build (single .sol, no imports).
// 70% of every entry is sent to 0x...dEaD; 30% is swapped to WETH and remains in the POT.
// The configured fee distributor can deposit the POT half of pons creator fees.
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function decimals() external view returns (uint8);
}
library SafeERC20 {
error SafeERC20FailedOperation(address token);
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory callData = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, callData)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, callData);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
(bool success, bytes memory returndata) = address(token).call(data);
if (!success || (returndata.length != 0 && !abi.decode(returndata, (bool)))) {
revert SafeERC20FailedOperation(address(token));
}
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status = NOT_ENTERED;
error ReentrancyGuardReentrantCall();
modifier nonReentrant() {
if (_status == ENTERED) revert ReentrancyGuardReentrantCall();
_status = ENTERED;
_;
_status = NOT_ENTERED;
}
}
abstract contract Ownable2Step {
address private _owner;
address private _pendingOwner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) revert OwnableInvalidOwner(address(0));
_owner = initialOwner;
emit OwnershipTransferred(address(0), initialOwner);
}
modifier onlyOwner() {
if (msg.sender != _owner) revert OwnableUnauthorizedAccount(msg.sender);
_;
}
function owner() public view returns (address) { return _owner; }
function pendingOwner() public view returns (address) { return _pendingOwner; }
function transferOwnership(address newOwner) public onlyOwner {
if (newOwner == address(0)) revert OwnableInvalidOwner(address(0));
_pendingOwner = newOwner;
emit OwnershipTransferStarted(_owner, newOwner);
}
function acceptOwnership() public {
if (msg.sender != _pendingOwner) revert OwnableUnauthorizedAccount(msg.sender);
address oldOwner = _owner;
_owner = msg.sender;
_pendingOwner = address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
/// @notice Ownership renunciation is intentionally disabled because operational
/// roles must remain rotatable if a backend key is compromised.
function renounceOwnership() public view onlyOwner {
revert OwnableInvalidOwner(address(0));
}
}
interface IUniswapV3Pool {
function token0() external view returns (address);
function token1() external view returns (address);
function fee() external view returns (uint24);
function slot0()
external
view
returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
);
function observe(uint32[] calldata secondsAgos)
external
view
returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);
function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;
function liquidity() external view returns (uint128);
}
interface ISwapRouter02 {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
}
/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath {
/// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return result The 256-bit result
/// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
function mulDiv(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = a * b
// Compute the product mod 2**256 and mod 2**256 - 1
// then 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(a, b, not(0))
prod0 := mul(a, b)
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]
// Compute remainder using mulmod
uint256 remainder;
assembly {
remainder := mulmod(a, b, denominator)
}
// Subtract 256 bit number from 512 bit number
assembly {
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator
// Compute largest power of two divisor of denominator.
// Always >= 1.
uint256 twos = (~denominator + 1) & denominator;
// Divide denominator by power of two
assembly {
denominator := div(denominator, twos)
}
// Divide [prod1 prod0] by the factors of two
assembly {
prod0 := div(prod0, twos)
}
// Shift in bits from prod1 into prod0. For this we need
// to flip `twos` such that it is 2**256 / twos.
// If twos is zero, then it becomes one
assembly {
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
// 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
// correct for four bits. That is, denominator * inv = 1 mod 2**4
uint256 inv = (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.
inv *= 2 - denominator * inv; // inverse mod 2**8
inv *= 2 - denominator * inv; // inverse mod 2**16
inv *= 2 - denominator * inv; // inverse mod 2**32
inv *= 2 - denominator * inv; // inverse mod 2**64
inv *= 2 - denominator * inv; // inverse mod 2**128
inv *= 2 - denominator * inv; // 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 * inv;
return result;
}
}
/// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return result The 256-bit result
function mulDivRoundingUp(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
result = mulDiv(a, b, denominator);
if (mulmod(a, b, denominator) > 0) {
require(result < type(uint256).max);
result++;
}
}
}
/// @title Math library for computing sqrt prices from ticks and vice versa
/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports
/// prices between 2**-128 and 2**128
library TickMath {
/// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128
int24 internal constant MIN_TICK = -887272;
/// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128
int24 internal constant MAX_TICK = -MIN_TICK;
/// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
/// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)
uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
/// @notice Calculates sqrt(1.0001^tick) * 2^96
/// @dev Throws if |tick| > max tick
/// @param tick The input tick for the above formula
/// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)
/// at the given tick
function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
require(absTick <= uint256(int256(MAX_TICK)), 'T');
uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;
if (tick > 0) ratio = type(uint256).max / ratio;
// this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.
// we then downcast because we know the result always fits within 160 bits due to our tick input constraint
// we round up in the division so getTickAtSqrtRatio of the output price is always consistent
sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
}
/// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio
/// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may
/// ever return.
/// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96
/// @return tick The greatest tick for which the ratio is less than or equal to the input ratio
function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
// second inequality must be < because the price can never reach the price at the max tick
require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');
uint256 ratio = uint256(sqrtPriceX96) << 32;
uint256 r = ratio;
uint256 msb = 0;
assembly {
let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(5, gt(r, 0xFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(4, gt(r, 0xFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(3, gt(r, 0xFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(2, gt(r, 0xF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(1, gt(r, 0x3))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := gt(r, 0x1)
msb := or(msb, f)
}
if (msb >= 128) r = ratio >> (msb - 127);
else r = ratio << (127 - msb);
int256 log_2 = (int256(msb) - 128) << 64;
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(63, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(62, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(61, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(60, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(59, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(58, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(57, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(56, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(55, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(54, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(53, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(52, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(51, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(50, f))
}
int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number
int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);
tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
}
}
/// @notice Solidity 0.8 adaptation of the Uniswap V3 OracleLibrary functions used by BurnWars.
library OracleQuoteLibrary {
function consult(address pool, uint32 secondsAgo) internal view returns (int24 arithmeticMeanTick) {
require(secondsAgo != 0, "TWAP_WINDOW_ZERO");
uint32[] memory secondsAgos = new uint32[](2);
secondsAgos[0] = secondsAgo;
secondsAgos[1] = 0;
(int56[] memory tickCumulatives,) = IUniswapV3Pool(pool).observe(secondsAgos);
int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0];
arithmeticMeanTick = int24(tickCumulativesDelta / int56(uint56(secondsAgo)));
if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int56(uint56(secondsAgo)) != 0)) {
arithmeticMeanTick--;
}
}
function getQuoteAtTick(int24 tick, uint128 baseAmount, address baseToken, address quoteToken)
internal
pure
returns (uint256 quoteAmount)
{
uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);
if (sqrtRatioX96 <= type(uint128).max) {
uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;
quoteAmount = baseToken < quoteToken
? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192)
: FullMath.mulDiv(1 << 192, baseAmount, ratioX192);
} else {
uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);
quoteAmount = baseToken < quoteToken
? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128)
: FullMath.mulDiv(1 << 128, baseAmount, ratioX128);
}
}
}
/// @title BurnWarsGameV27_4
/// @notice Burn-to-enter game. This contract is also the non-custodial WETH prize pot.
/// @dev Rewards are pushed from this contract in permissionless batches during the cooldown.
/// The caller pays gas; WETH always leaves this contract only for recorded winners.
contract BurnWarsGameV27_4 is ReentrancyGuard, Ownable2Step {
using SafeERC20 for IERC20;
enum RoundState {
Waiting,
Active,
RandomPending,
Settled,
Cooldown
}
enum WinnerType {
None,
LastBurner,
SecondLast,
ThirdLast,
Random
}
struct Entry {
address player;
uint256 tokensIn;
uint256 tokensBurned;
uint256 tokensSold;
uint256 wethAddedToPot;
uint64 burnedAt;
}
struct Round {
RoundState state;
uint64 startTime;
uint64 endTime;
uint64 finalizedAt;
uint64 cooldownEnd;
uint256 minimumBurn;
uint256 startingPotWeth;
uint256 finalPotWeth;
uint256 totalTokensIn;
uint32 entryCount;
uint32 uniquePlayers;
uint32 payoutCursor;
uint32 winnerAllocationCount;
uint8 randomWinnerCount;
uint64 randomnessBlock;
uint64 randomnessFallbackTime;
bool randomnessFallbackActive;
bytes32 randomnessCommitment;
}
struct WinnerAllocation {
address wallet;
uint256 amount;
WinnerType winnerType;
uint256 entryIndex;
bool paid;
}
/// @dev Groups finalization calculations in memory to avoid Solidity's "stack too deep" limit.
struct FinalizationAmounts {
uint256 firstPrize;
uint256 secondPrize;
uint256 thirdPrize;
uint256 randomPool;
uint256 eligibleRandomWallets;
}
/// @dev Keeps random-draw arithmetic grouped to remain compatible with Remix's legacy code generator.
struct RandomSelectionAmounts {
uint256 eligibleWallets;
uint256 winnerCount;
uint256 randomPool;
uint256 share;
}
/// @dev Struct return values prevent Solidity's legacy code generator from
/// exhausting the EVM stack when encoding large round summaries.
struct CurrentRoundView {
uint256 roundId;
uint8 state;
uint64 startTime;
uint64 endTime;
uint64 cooldownEnd;
uint256 minimumBurn;
uint256 startingPotWeth;
uint256 totalTokensIn;
uint32 entryCount;
uint32 uniquePlayers;
uint32 payoutCursor;
uint32 winnerAllocationCount;
}
struct RoundSummaryView {
uint8 state;
uint64 startTime;
uint64 endTime;
uint64 finalizedAt;
uint64 cooldownEnd;
uint256 minimumBurn;
uint256 startingPotWeth;
uint256 finalPotWeth;
uint256 totalTokensIn;
uint32 entryCount;
uint32 uniquePlayers;
uint8 randomWinnerCount;
uint32 payoutCursor;
uint32 winnerAllocationCount;
}
uint256 public constant BPS = 10_000;
uint256 public constant BURN_BPS = 7_000;
uint256 public constant SWAP_BPS = 3_000;
uint256 public constant FIRST_BPS = 5_000;
uint256 public constant SECOND_BPS = 2_000;
uint256 public constant THIRD_BPS = 1_000;
uint256 public constant RANDOM_BPS = 2_000;
uint64 public constant INITIAL_DURATION = 1 hours;
uint64 public constant EXTENSION = 30 seconds;
uint64 public constant MAX_REMAINING = 24 hours;
uint64 public constant COOLDOWN = 10 minutes;
uint64 public constant BURN_AMOUNT_ACTIVATION_DELAY = 1 minutes;
uint64 public constant BURN_UPDATE_MIN_INTERVAL = 5 minutes;
uint32 public constant MAX_TWAP_WINDOW = 1 days;
uint16 public constant MAX_CONFIGURABLE_SLIPPAGE_BPS = 2_000;
uint16 public constant ORACLE_CARDINALITY_TARGET = 64;
uint64 public constant RANDOMNESS_BLOCK_DELAY = 8;
uint64 public constant RANDOMNESS_FALLBACK_DELAY = 24 hours;
uint8 public constant MAX_RANDOM_WINNERS = 50;
uint8 public constant MAX_WINNERS_PER_ROUND = 53;
uint8 public constant MAX_PAYOUTS_PER_TX = 10;
address public constant DEAD = 0x000000000000000000000000000000000000dEaD;
IERC20 public immutable token;
IERC20 public immutable weth;
ISwapRouter02 public immutable swapRouter;
IUniswapV3Pool public immutable pool;
uint24 public immutable poolFee;
uint32 public immutable twapWindow;
uint16 public immutable maxSwapSlippageBps;
uint8 public immutable tokenDecimals;
uint256 public immutable tokenUnit;
address public feeDistributor;
address public burnPriceUpdater;
address public randomnessCommitter;
bool public gameStarted;
bool public participationPaused;
uint256 public currentRoundId;
uint256 public nextMinimumBurn;
uint256 public pendingMinimumBurn;
uint64 public pendingBurnActivationTime;
uint64 public lastBurnScheduleTime;
bytes32 public nextRandomnessCommitment;
/// @notice WETH frozen for completed rounds but not yet transferred to winners.
uint256 public totalClaimableWeth;
/// @notice External creator-fee WETH reserved for the next round.
uint256 public nextRoundCarryoverWeth;
mapping(uint256 => Round) private _rounds;
mapping(uint256 => mapping(uint256 => Entry)) private _entries;
mapping(uint256 => mapping(address => bool)) private _seenPlayer;
mapping(uint256 => address[]) private _uniquePlayers;
mapping(uint256 => mapping(address => uint256)) private _firstEntryIndexByPlayer;
mapping(uint256 => WinnerAllocation[]) private _winnerAllocations;
mapping(uint256 => mapping(address => uint256)) public claimable;
mapping(uint256 => bytes32) public roundEntropy;
event GameStarted(uint256 indexed roundId, uint64 startTime, uint64 endTime);
event BurnRegistered(
uint256 indexed roundId,
uint256 indexed entryIndex,
address indexed player,
uint256 tokensIn,
uint256 burnedTokens,
uint256 soldTokens,
uint256 wethAddedToPot,
uint64 newEndTime,
uint64 burnedAt
);
event RoundStarted(
uint256 indexed roundId,
uint64 startTime,
uint64 endTime,
uint256 minimumBurn,
uint256 startingPotWeth
);
event RoundFinalized(
uint256 indexed roundId,
uint256 finalPotWeth,
uint256 firstEntryIndex,
uint256 secondEntryIndex,
uint256 thirdEntryIndex,
uint64 finalizedAt
);
event FeeDistributorUpdated(address indexed previousDistributor, address indexed newDistributor);
event BurnPriceUpdaterUpdated(address indexed previousUpdater, address indexed newUpdater);
event RandomnessCommitterUpdated(address indexed previousCommitter, address indexed newCommitter);
event ParticipationPauseUpdated(bool paused);
event NextRandomnessCommitted(uint256 indexed targetRoundId, bytes32 indexed commitment);
event BurnAmountScheduled(uint256 indexed roundId, uint256 currentAmount, uint256 pendingAmount, uint64 activationTime);
event BurnAmountActivated(uint256 indexed roundId, uint256 previousAmount, uint256 newAmount);
event BurnAmountScheduleCancelled(uint256 indexed roundId, uint256 cancelledAmount);
event RandomnessScheduled(uint256 indexed roundId, uint64 targetBlock);
event RandomnessFallbackActivated(uint256 indexed roundId, uint64 targetBlock);
event RandomnessFallbackUsed(uint256 indexed roundId, bytes32 seed);
event RandomWinnersSelected(uint256 indexed roundId, uint256 winnerCount, bytes32 seed);
event PrizeAllocated(
uint256 indexed roundId,
address indexed winner,
uint256 amount,
WinnerType winnerType,
uint256 entryIndex
);
event PrizePaid(
uint256 indexed roundId,
address indexed winner,
uint256 amount,
WinnerType winnerType,
uint256 entryIndex
);
event PayoutBatchProcessed(uint256 indexed roundId, uint256 fromIndex, uint256 toIndex, uint256 payments);
event AllWinnersPaid(uint256 indexed roundId, uint256 payments);
event RoundPaymentsCompleted(uint256 indexed roundId, uint256 totalPaid, uint64 completedAt);
event CreatorFeesDeposited(
uint256 indexed creditedRoundId,
address indexed distributor,
uint256 amount,
bool carriedToNextRound
);
error GameAlreadyStarted();
error GameNotStarted();
error RoundNotActive();
error RoundStillRunning();
error RoundNotReady();
error InvalidAddress();
error InvalidAmount();
error InvalidPool();
error InvalidSwapQuote();
error SwapOutputTooLow();
error InsolventPot();
error InvalidBatchSize();
error PaymentsPending();
error UnauthorizedFeeDistributor();
error UnauthorizedBurnPriceUpdater();
error BurnAmountChanged(uint256 expectedAmount, uint256 currentAmount);
error BurnAmountMustBeWholeTokens();
error BurnUpdateTooSoon(uint64 nextAllowedTime);
error BurnUpdateWindowClosed();
error RandomnessNotReady();
error RandomnessExpired();
error InvalidRandomnessReveal();
error RandomnessCommitmentMissing();
error UnauthorizedRandomnessCommitter();
error ParticipationPaused();
error BurnChangeTooLarge(uint256 currentAmount, uint256 requestedAmount);
error TooManyWinnerAllocations();
constructor(
address initialOwner,
address tokenAddress,
address wethAddress,
address swapRouterAddress,
address poolAddress,
address feeDistributorAddress,
uint256 initialMinimumBurn,
uint32 twapWindowSeconds,
uint16 maximumSwapSlippageBps
) Ownable2Step(initialOwner) {
if (
initialOwner == address(0) || initialOwner == DEAD || tokenAddress == address(0)
|| wethAddress == address(0) || swapRouterAddress == address(0) || poolAddress == address(0)
|| feeDistributorAddress == address(0) || feeDistributorAddress == DEAD
) revert InvalidAddress();
if (
tokenAddress.code.length == 0 || wethAddress.code.length == 0
|| swapRouterAddress.code.length == 0 || poolAddress.code.length == 0
) revert InvalidAddress();
if (
initialMinimumBurn == 0 || twapWindowSeconds < 30 || twapWindowSeconds > MAX_TWAP_WINDOW
|| maximumSwapSlippageBps == 0
|| maximumSwapSlippageBps > MAX_CONFIGURABLE_SLIPPAGE_BPS
) revert InvalidAmount();
token = IERC20(tokenAddress);
weth = IERC20(wethAddress);
swapRouter = ISwapRouter02(swapRouterAddress);
pool = IUniswapV3Pool(poolAddress);
feeDistributor = feeDistributorAddress;
burnPriceUpdater = feeDistributorAddress;
randomnessCommitter = feeDistributorAddress;
{
uint8 decimals_ = IERC20(tokenAddress).decimals();
if (decimals_ > 36) revert InvalidAmount();
uint256 unit_ = 10 ** uint256(decimals_);
if (
initialMinimumBurn % unit_ != 0
|| initialMinimumBurn > IERC20(tokenAddress).totalSupply()
) revert BurnAmountMustBeWholeTokens();
tokenDecimals = decimals_;
tokenUnit = unit_;
}
nextMinimumBurn = initialMinimumBurn;
twapWindow = twapWindowSeconds;
maxSwapSlippageBps = maximumSwapSlippageBps;
{
address token0 = IUniswapV3Pool(poolAddress).token0();
address token1 = IUniswapV3Pool(poolAddress).token1();
bool correctPair = (token0 == tokenAddress && token1 == wethAddress)
|| (token0 == wethAddress && token1 == tokenAddress);
if (!correctPair) revert InvalidPool();
}
uint24 poolFee_ = IUniswapV3Pool(poolAddress).fee();
if (poolFee_ == 0) revert InvalidPool();
poolFee = poolFee_;
{
(uint160 sqrtPriceX96, , , , , ,) = IUniswapV3Pool(poolAddress).slot0();
if (sqrtPriceX96 == 0) revert InvalidPool();
}
// Best effort: expanding the observation buffer makes the configured TWAP
// available sooner on fresh pools. Failure does not block deployment.
try IUniswapV3Pool(poolAddress).increaseObservationCardinalityNext(ORACLE_CARDINALITY_TARGET) {} catch {}
}
/// @notice Human-readable contract release.
function contractVersion() external pure returns (string memory) {
return "27.4.0";
}
/// @notice Changes the backend wallet allowed to schedule burn-price updates.
/// @dev This role can only schedule a new amount with the mandatory one-minute delay.
function setBurnPriceUpdater(address newUpdater) external onlyOwner {
if (newUpdater == address(0) || newUpdater == DEAD) revert InvalidAddress();
address previousUpdater = burnPriceUpdater;
burnPriceUpdater = newUpdater;
emit BurnPriceUpdaterUpdated(previousUpdater, newUpdater);
}
/// @notice Changes the wallet authorized to deposit the POT share of creator fees.
/// @dev This never grants withdrawal rights over the POT.
function setFeeDistributor(address newDistributor) external onlyOwner {
if (newDistributor == address(0) || newDistributor == DEAD) revert InvalidAddress();
address previousDistributor = feeDistributor;
feeDistributor = newDistributor;
emit FeeDistributorUpdated(previousDistributor, newDistributor);
}
/// @notice Changes the wallet that precommits the hidden entropy used by the automatic random draw.
/// @dev It may be the same operational Distributor wallet. This role cannot withdraw the POT.
function setRandomnessCommitter(address newCommitter) external onlyOwner {
if (newCommitter == address(0) || newCommitter == DEAD) revert InvalidAddress();
address previousCommitter = randomnessCommitter;
randomnessCommitter = newCommitter;
emit RandomnessCommitterUpdated(previousCommitter, newCommitter);
}
/// @notice Pauses only new burn entries during an incident. Finalization and payouts remain permissionless.
function setParticipationPaused(bool paused) external onlyOwner {
participationPaused = paused;
emit ParticipationPauseUpdated(paused);
}
/// @notice Stores the commitment for the next round before any participant can enter it.
/// @dev commitment = keccak256(abi.encode(address(this), targetRoundId, secret)).
function prepareNextRoundRandomness(bytes32 commitment) public {
if (msg.sender != randomnessCommitter && msg.sender != owner()) revert UnauthorizedRandomnessCommitter();
if (commitment == bytes32(0)) revert RandomnessCommitmentMissing();
uint256 targetRoundId = currentRoundId + 1;
nextRandomnessCommitment = commitment;
emit NextRandomnessCommitted(targetRoundId, commitment);
}
/// @notice Starts Round 1 exactly once with entropy committed before the first entry.
function startGame(bytes32 firstRoundCommitment) external onlyOwner {
if (gameStarted) revert GameAlreadyStarted();
prepareNextRoundRandomness(firstRoundCommitment);
_oracleQuoteForCurrentMinimum(nextMinimumBurn);
gameStarted = true;
_startNextRound();
Round storage round = _rounds[currentRoundId];
emit GameStarted(currentRoundId, round.startTime, round.endTime);
}
/// @notice Schedules the rounded BWARS entry amount calculated by the backend.
/// @dev The contract enforces a five-minute minimum between actual schedules and
/// a one-minute public activation delay. The USD calculation remains an
/// off-chain keeper responsibility and is auditable through emitted events.
function scheduleBurnAmount(uint256 amount) external {
if (msg.sender != burnPriceUpdater && msg.sender != owner()) revert UnauthorizedBurnPriceUpdater();
if (!gameStarted) revert GameNotStarted();
if (amount == 0 || amount > token.totalSupply()) revert InvalidAmount();
if (amount % tokenUnit != 0) revert BurnAmountMustBeWholeTokens();
Round storage round = _rounds[currentRoundId];
if (round.state != RoundState.Active || block.timestamp >= round.endTime) revert RoundNotActive();
_activatePendingBurnAmount(round);
if (amount == round.minimumBurn) {
_cancelPendingBurnAmount(currentRoundId);
return;
}
if (pendingMinimumBurn == amount) return;
uint64 nowTime = uint64(block.timestamp);
uint64 nextAllowed = lastBurnScheduleTime + BURN_UPDATE_MIN_INTERVAL;
if (lastBurnScheduleTime != 0 && nowTime < nextAllowed) revert BurnUpdateTooSoon(nextAllowed);
uint64 activationTime = nowTime + BURN_AMOUNT_ACTIVATION_DELAY;
if (activationTime >= round.endTime) revert BurnUpdateWindowClosed();
uint256 currentAmount = round.minimumBurn;
uint256 maximumAmount = currentAmount * 2;
uint256 minimumAmount = (currentAmount + 1) / 2;
if (amount > maximumAmount || amount < minimumAmount) {
revert BurnChangeTooLarge(currentAmount, amount);
}
// Reject an amount that cannot produce a non-zero, representable TWAP quote.
_oracleQuoteForCurrentMinimum(amount);
pendingMinimumBurn = amount;
pendingBurnActivationTime = activationTime;
lastBurnScheduleTime = nowTime;
emit BurnAmountScheduled(currentRoundId, round.minimumBurn, amount, activationTime);
}
/// @notice Permissionless state synchronization after the one-minute countdown.
function applyPendingBurnAmount() external returns (bool activated) {
if (!gameStarted) return false;
Round storage round = _rounds[currentRoundId];
if (round.state != RoundState.Active || block.timestamp >= round.endTime) return false;
return _activatePendingBurnAmount(round);
}
/// @notice Returns the effective amount and any valid future scheduled amount.
function getBurnPricing()
external
view
returns (uint256 currentAmount, uint256 pendingAmount, uint64 activationTime, uint64 secondsUntilActivation)
{
Round storage round = _rounds[currentRoundId];
currentAmount = round.minimumBurn;
pendingAmount = pendingMinimumBurn;
activationTime = pendingBurnActivationTime;
bool validPending = pendingAmount != 0 && activationTime != 0 && activationTime < round.endTime;
if (!validPending) return (currentAmount, 0, 0, 0);
if (block.timestamp >= activationTime && block.timestamp < round.endTime) {
currentAmount = pendingAmount;
} else if (block.timestamp < activationTime) {
secondsUntilActivation = activationTime - uint64(block.timestamp);
}
}
/// @notice Atomically burns 70%, swaps 30% to WETH and leaves the WETH in this contract.
/// @param expectedBurnAmount Amount displayed when the user signed. A stale amount reverts before token transfer.
function burnAndEnter(uint256 expectedBurnAmount) external nonReentrant {
if (!gameStarted) revert GameNotStarted();
if (participationPaused) revert ParticipationPaused();
uint256 roundId = currentRoundId;
Round storage round = _rounds[roundId];
if (round.state != RoundState.Active || block.timestamp >= round.endTime) revert RoundNotActive();
_activatePendingBurnAmount(round);
if (expectedBurnAmount != round.minimumBurn) {
revert BurnAmountChanged(expectedBurnAmount, round.minimumBurn);
}
Entry memory entry = _collectBurnAndSwap(expectedBurnAmount, msg.sender);
uint256 entryIndex = _recordBurnEntry(roundId, round, entry);
_emitBurnRegistered(roundId, entryIndex);
}
function _collectBurnAndSwap(uint256 requiredAmount, address player)
internal
returns (Entry memory entry)
{
uint256 tokenBalanceBefore = token.balanceOf(address(this));
token.safeTransferFrom(player, address(this), requiredAmount);
entry.tokensIn = token.balanceOf(address(this)) - tokenBalanceBefore;
if (entry.tokensIn != requiredAmount) revert InvalidAmount();
entry.player = player;
entry.tokensBurned = FullMath.mulDiv(entry.tokensIn, BURN_BPS, BPS);
entry.tokensSold = entry.tokensIn - entry.tokensBurned;
entry.burnedAt = uint64(block.timestamp);
token.safeTransfer(DEAD, entry.tokensBurned);
entry.wethAddedToPot = _swapEntryTokensForWeth(entry.tokensSold);
}
function _swapEntryTokensForWeth(uint256 amountIn) internal returns (uint256 amountOut) {
uint256 minimumOut = _minimumWethOut(amountIn);
uint256 wethBalanceBefore = weth.balanceOf(address(this));
ISwapRouter02.ExactInputSingleParams memory params = ISwapRouter02.ExactInputSingleParams({
tokenIn: address(token),
tokenOut: address(weth),
fee: poolFee,
recipient: address(this),
amountIn: amountIn,
amountOutMinimum: minimumOut,
sqrtPriceLimitX96: 0
});
token.forceApprove(address(swapRouter), amountIn);
swapRouter.exactInputSingle(params);
token.forceApprove(address(swapRouter), 0);
amountOut = weth.balanceOf(address(this)) - wethBalanceBefore;
if (amountOut < minimumOut) revert SwapOutputTooLow();
}
function _recordBurnEntry(uint256 roundId, Round storage round, Entry memory entry)
internal
returns (uint256 entryIndex)
{
entryIndex = round.entryCount;
_entries[roundId][entryIndex] = entry;
round.entryCount += 1;
round.totalTokensIn += entry.tokensIn;
if (!_seenPlayer[roundId][entry.player]) {
_seenPlayer[roundId][entry.player] = true;
_firstEntryIndexByPlayer[roundId][entry.player] = entryIndex;
_uniquePlayers[roundId].push(entry.player);
round.uniquePlayers += 1;
}
roundEntropy[roundId] = keccak256(
abi.encode(roundEntropy[roundId], entry.player, entryIndex, entry.tokensIn, block.number, blockhash(block.number - 1))
);
uint256 extendedEnd = uint256(round.endTime) + EXTENSION;
uint256 maximumEnd = block.timestamp + MAX_REMAINING;
round.endTime = uint64(extendedEnd > maximumEnd ? maximumEnd : extendedEnd);
}
function _emitBurnRegistered(uint256 roundId, uint256 entryIndex) internal {
Entry storage entry = _entries[roundId][entryIndex];
emit BurnRegistered(
roundId,
entryIndex,
entry.player,
entry.tokensIn,
entry.tokensBurned,
entry.tokensSold,
entry.wethAddedToPot,
_rounds[roundId].endTime,
entry.burnedAt
);
}
/// @notice Pulls the distributor's 50% creator-fee share into the game POT.
/// @dev During an active timer it credits the current round. Otherwise it is reserved for the next round.
function depositCreatorFees(uint256 amount) external nonReentrant {
if (msg.sender != feeDistributor) revert UnauthorizedFeeDistributor();
if (amount == 0) revert InvalidAmount();
weth.safeTransferFrom(msg.sender, address(this), amount);
bool carryover = true;
uint256 creditedRoundId = gameStarted ? currentRoundId + 1 : 1;
if (gameStarted) {
Round storage round = _rounds[currentRoundId];
if (round.state == RoundState.Active && block.timestamp < round.endTime) {
carryover = false;
creditedRoundId = currentRoundId;
}
}
if (carryover) nextRoundCarryoverWeth += amount;
emit CreatorFeesDeposited(creditedRoundId, msg.sender, amount, carryover);
}
/// @notice WETH currently available to the active round, excluding frozen rewards and next-round carryover.
function availablePotBalance() public view returns (uint256) {
uint256 balance = weth.balanceOf(address(this));
uint256 unavailable = totalClaimableWeth + nextRoundCarryoverWeth;
if (balance < unavailable) revert InsolventPot();
return balance - unavailable;
}
function getPotStatus()
external
view
returns (uint256 contractWethBalance, uint256 reservedForWinners, uint256 availablePot)
{
contractWethBalance = weth.balanceOf(address(this));
reservedForWinners = totalClaimableWeth;
uint256 unavailable = reservedForWinners + nextRoundCarryoverWeth;
if (contractWethBalance < unavailable) revert InsolventPot();
availablePot = contractWethBalance - unavailable;
}
function getPotAccounting()
external
view
returns (
uint256 contractWethBalance,
uint256 reservedForWinners,
uint256 activeRoundPot,
uint256 nextRoundCarryover
)
{
contractWethBalance = weth.balanceOf(address(this));
reservedForWinners = totalClaimableWeth;
nextRoundCarryover = nextRoundCarryoverWeth;
uint256 unavailable = reservedForWinners + nextRoundCarryover;
if (contractWethBalance < unavailable) revert InsolventPot();
activeRoundPot = contractWethBalance - unavailable;
}
function quoteCurrentEntryWethOut() external view returns (uint256 oracleQuote, uint256 minimumOut) {
if (!gameStarted) return (0, 0);
uint256 effectiveAmount = _effectiveMinimumBurn(_rounds[currentRoundId]);
uint256 sellAmount = FullMath.mulDiv(effectiveAmount, SWAP_BPS, BPS);
oracleQuote = _oracleQuote(sellAmount);
minimumOut = FullMath.mulDiv(oracleQuote, BPS - maxSwapSlippageBps, BPS);
}
/// @notice Freezes the current pot and creates the winner allocations.
/// @dev Anyone can call this after the timer reaches zero. The caller pays gas.
function finalizeRound() external nonReentrant {
if (!gameStarted) revert GameNotStarted();
uint256 roundId = currentRoundId;
Round storage round = _rounds[roundId];
if (round.state != RoundState.Active) revert RoundNotReady();
if (block.timestamp < round.endTime) revert RoundStillRunning();
_finalizePendingBurnAmount(round);
_cancelPendingBurnAmount(roundId);
round.finalizedAt = uint64(block.timestamp);
round.cooldownEnd = uint64(block.timestamp + COOLDOWN);
uint256 count = round.entryCount;
if (count == 0) {
_finalizeEmptyRound(roundId, round);
return;
}
uint256 eligibleRandomWallets = _freezePotAndAllocateFixedPrizes(roundId, round, count);
if (eligibleRandomWallets == 0) {
_openPayoutCooldown(roundId, round);
return;
}
round.state = RoundState.RandomPending;
round.randomnessBlock = uint64(block.number + RANDOMNESS_BLOCK_DELAY);
round.randomnessFallbackTime = uint64(block.timestamp + RANDOMNESS_FALLBACK_DELAY);
round.randomnessFallbackActive = false;
emit RandomnessScheduled(roundId, round.randomnessBlock);
}
function _finalizeEmptyRound(uint256 roundId, Round storage round) internal {
uint256 noEntry = type(uint256).max;
round.finalPotWeth = 0;
round.state = RoundState.Settled;
emit RoundFinalized(roundId, 0, noEntry, noEntry, noEntry, round.finalizedAt);
emit RoundPaymentsCompleted(roundId, 0, uint64(block.timestamp));
}
function _freezePotAndAllocateFixedPrizes(uint256 roundId, Round storage round, uint256 count)
internal
returns (uint256 eligibleRandomWallets)
{
round.finalPotWeth = availablePotBalance();
totalClaimableWeth += round.finalPotWeth;
uint256 firstEntry = count - 1;
uint256 secondEntry = count > 1 ? count - 2 : type(uint256).max;
uint256 thirdEntry = count > 2 ? count - 3 : type(uint256).max;
eligibleRandomWallets = _eligibleRandomWalletCount(roundId, round.uniquePlayers, count);
FinalizationAmounts memory amounts = _calculateFinalizationAmounts(
round.finalPotWeth,
count,
eligibleRandomWallets
);
_allocate(roundId, firstEntry, amounts.firstPrize, WinnerType.LastBurner);
if (count > 1) _allocate(roundId, secondEntry, amounts.secondPrize, WinnerType.SecondLast);
if (count > 2) _allocate(roundId, thirdEntry, amounts.thirdPrize, WinnerType.ThirdLast);
_emitRoundFinalized(roundId, round, firstEntry, secondEntry, thirdEntry);
return amounts.eligibleRandomWallets;
}
function _eligibleRandomWalletCount(uint256 roundId, uint256 uniquePlayers, uint256 count)
internal
view
returns (uint256)
{
address firstWallet = _entries[roundId][count - 1].player;
address secondWallet = count > 1 ? _entries[roundId][count - 2].player : address(0);
address thirdWallet = count > 2 ? _entries[roundId][count - 3].player : address(0);
uint256 excluded = 1;
if (secondWallet != address(0) && secondWallet != firstWallet) excluded += 1;
if (thirdWallet != address(0) && thirdWallet != firstWallet && thirdWallet != secondWallet) excluded += 1;
return uniquePlayers > excluded ? uniquePlayers - excluded : 0;
}
function _isTopThreeWallet(uint256 roundId, uint256 count, address wallet) internal view returns (bool) {
if (_entries[roundId][count - 1].player == wallet) return true;
if (count > 1 && _entries[roundId][count - 2].player == wallet) return true;
return count > 2 && _entries[roundId][count - 3].player == wallet;
}
function _calculateFinalizationAmounts(uint256 pot, uint256 count, uint256 eligibleRandomWallets)
internal
pure
returns (FinalizationAmounts memory amounts)
{
amounts.firstPrize = FullMath.mulDiv(pot, FIRST_BPS, BPS);
amounts.secondPrize = count > 1 ? FullMath.mulDiv(pot, SECOND_BPS, BPS) : 0;
amounts.thirdPrize = count > 2 ? FullMath.mulDiv(pot, THIRD_BPS, BPS) : 0;
amounts.eligibleRandomWallets = eligibleRandomWallets;
amounts.randomPool = eligibleRandomWallets > 0 ? FullMath.mulDiv(pot, RANDOM_BPS, BPS) : 0;
// Reassign unavailable categories to the last burner so 100% of the frozen pot is payable.
if (count < 2) amounts.firstPrize += FullMath.mulDiv(pot, SECOND_BPS, BPS);
if (count < 3) amounts.firstPrize += FullMath.mulDiv(pot, THIRD_BPS, BPS);
if (eligibleRandomWallets == 0) amounts.firstPrize += FullMath.mulDiv(pot, RANDOM_BPS, BPS);
uint256 allocated = amounts.firstPrize + amounts.secondPrize + amounts.thirdPrize + amounts.randomPool;
amounts.firstPrize += pot - allocated;
}
function _emitRoundFinalized(
uint256 roundId,
Round storage round,
uint256 firstEntry,
uint256 secondEntry,
uint256 thirdEntry
) internal {
emit RoundFinalized(
roundId,
round.finalPotWeth,
firstEntry,
secondEntry,
thirdEntry,
round.finalizedAt
);
}
/// @notice Recovers an expired target block by irreversibly switching to the public fallback.
/// @dev The committed secret can no longer be revealed after this transition. This prevents
/// the committer from repeatedly expiring blocks and choosing among several known hashes.
function refreshRandomnessBlock() external {
uint256 roundId = currentRoundId;
Round storage round = _rounds[roundId];
if (round.state != RoundState.RandomPending) revert RoundNotReady();
if (block.number <= uint256(round.randomnessBlock) + 256) revert RandomnessNotReady();
bool wasFallbackActive = round.randomnessFallbackActive;
round.randomnessFallbackActive = true;
round.randomnessBlock = uint64(block.number + RANDOMNESS_BLOCK_DELAY);
if (!wasFallbackActive) emit RandomnessFallbackActivated(roundId, round.randomnessBlock);
emit RandomnessScheduled(roundId, round.randomnessBlock);
}
/// @notice Completes the draw using entropy committed before the round and a later block hash.
/// @dev This materially reduces unilateral sequencer influence but is not a dedicated VRF.
function settleRandomWinners(bytes32 secret) external nonReentrant {
uint256 roundId = currentRoundId;
Round storage round = _rounds[roundId];
if (round.state != RoundState.RandomPending) revert RoundNotReady();
if (round.randomnessFallbackActive) revert RandomnessNotReady();
if (keccak256(abi.encode(address(this), roundId, secret)) != round.randomnessCommitment) {
revert InvalidRandomnessReveal();
}
uint256 targetBlock = round.randomnessBlock;
if (block.number <= targetBlock) revert RandomnessNotReady();
bytes32 targetHash = blockhash(targetBlock);
if (targetHash == bytes32(0)) revert RandomnessExpired();
bytes32 seed = keccak256(
abi.encode(secret, targetHash, roundEntropy[roundId], roundId, round.finalPotWeth, round.entryCount, address(this))
);
_selectRandomWinners(roundId, round, uint256(seed), seed);
}
/// @notice Switches an unrevealed round into a public future-block fallback after 24 hours.
/// @dev Once activated, the committed secret can no longer be revealed. The operator therefore
/// cannot wait to inspect both outcomes and then choose the more favorable one.
function activateRandomnessFallback() external {
uint256 roundId = currentRoundId;
Round storage round = _rounds[roundId];
if (round.state != RoundState.RandomPending) revert RoundNotReady();
if (round.randomnessFallbackActive || block.timestamp < round.randomnessFallbackTime) {
revert RandomnessNotReady();
}
round.randomnessFallbackActive = true;
round.randomnessBlock = uint64(block.number + RANDOMNESS_BLOCK_DELAY);
emit RandomnessFallbackActivated(roundId, round.randomnessBlock);
emit RandomnessScheduled(roundId, round.randomnessBlock);
}
/// @notice Liveness fallback using a block that was unknown when fallback mode was activated.
/// @dev This remains weaker than VRF, but avoids a deterministic operator-selectable fallback.
function settleRandomWinnersFallback() external nonReentrant {
uint256 roundId = currentRoundId;
Round storage round = _rounds[roundId];
if (round.state != RoundState.RandomPending || !round.randomnessFallbackActive) revert RoundNotReady();
uint256 targetBlock = round.randomnessBlock;
if (block.number <= targetBlock) revert RandomnessNotReady();
bytes32 targetHash = blockhash(targetBlock);
if (targetHash == bytes32(0)) revert RandomnessExpired();
bytes32 seed = keccak256(
abi.encode(round.randomnessCommitment, targetHash, roundEntropy[roundId], roundId, round.finalPotWeth, round.entryCount, address(this))
);
emit RandomnessFallbackUsed(roundId, seed);
_selectRandomWinners(roundId, round, uint256(seed), seed);
}
function _selectRandomWinners(uint256 roundId, Round storage round, uint256 randomWord, bytes32 seed) internal {
uint256 count = round.entryCount;
RandomSelectionAmounts memory amounts = _randomSelectionAmounts(roundId, round, count);
if (amounts.winnerCount == 0) {
round.randomWinnerCount = 0;
emit RandomWinnersSelected(roundId, 0, seed);
_openPayoutCooldown(roundId, round);
return;
}
uint256[] memory eligiblePlayerIndexes =
_buildEligibleRandomPlayerIndexes(roundId, count, amounts.eligibleWallets);
_allocateRandomWinners(roundId, randomWord, eligiblePlayerIndexes, amounts);
round.randomWinnerCount = uint8(amounts.winnerCount);
emit RandomWinnersSelected(roundId, amounts.winnerCount, seed);
_openPayoutCooldown(roundId, round);
}
/// @dev Builds the draw arithmetic in a separate frame so Remix's legacy code generator
/// does not keep the complete selection state on one EVM stack.
function _randomSelectionAmounts(uint256 roundId, Round storage round, uint256 count)
internal
view
returns (RandomSelectionAmounts memory amounts)
{
amounts.eligibleWallets = _eligibleRandomWalletCount(roundId, round.uniquePlayers, count);
amounts.winnerCount = amounts.eligibleWallets < MAX_RANDOM_WINNERS
? amounts.eligibleWallets
: MAX_RANDOM_WINNERS;
if (amounts.winnerCount == 0) return amounts;
amounts.randomPool = FullMath.mulDiv(round.finalPotWeth, RANDOM_BPS, BPS);
amounts.share = amounts.randomPool / amounts.winnerCount;
}
/// @dev Produces a compact list of eligible unique-player indexes, excluding top-three wallets.
function _buildEligibleRandomPlayerIndexes(uint256 roundId, uint256 count, uint256 eligibleWallets)
internal
view
returns (uint256[] memory indexes)
{
indexes = new uint256[](eligibleWallets);
uint256 cursor;
uint256 playerCount = _uniquePlayers[roundId].length;
for (uint256 playerIndex; playerIndex < playerCount; ++playerIndex) {
address candidateWallet = _uniquePlayers[roundId][playerIndex];
if (_isTopThreeWallet(roundId, count, candidateWallet)) continue;
indexes[cursor] = playerIndex;
unchecked { ++cursor; }
}
if (cursor != eligibleWallets) revert InvalidAmount();
}
/// @dev Runs the bounded partial Fisher-Yates draw in its own stack frame.
function _allocateRandomWinners(
uint256 roundId,
uint256 randomWord,
uint256[] memory eligiblePlayerIndexes,
RandomSelectionAmounts memory amounts
) internal {
for (uint256 i; i < amounts.winnerCount; ++i) {
uint256 playerIndex = _drawRandomPlayerIndex(
eligiblePlayerIndexes,
i,
uint256(keccak256(abi.encode(randomWord, roundId, i)))
);
address randomWallet = _uniquePlayers[roundId][playerIndex];
_allocate(
roundId,
_firstEntryIndexByPlayer[roundId][randomWallet],
_randomWinnerAmount(amounts, i),
WinnerType.Random
);
}
}
/// @dev Selects one remaining unique-player index and swaps it into the current cursor.
function _drawRandomPlayerIndex(uint256[] memory indexes, uint256 cursor, uint256 entropy)
internal
pure
returns (uint256 playerIndex)
{
uint256 selectedIndex = cursor + (entropy % (indexes.length - cursor));
playerIndex = indexes[selectedIndex];
indexes[selectedIndex] = indexes[cursor];
indexes[cursor] = playerIndex;
}
/// @dev Assigns any integer-division remainder to the last random allocation.
function _randomWinnerAmount(RandomSelectionAmounts memory amounts, uint256 cursor)
internal
pure
returns (uint256)
{
if (cursor + 1 == amounts.winnerCount) {
return amounts.randomPool - (amounts.share * (amounts.winnerCount - 1));
}
return amounts.share;
}
function getRandomnessStatus()
external
view
returns (uint256 roundId, uint64 targetBlock, uint256 currentBlock, bool ready, bool expired, bool fallbackActive)
{
roundId = currentRoundId;
targetBlock = _rounds[roundId].randomnessBlock;
currentBlock = block.number;
ready = targetBlock != 0 && currentBlock > targetBlock;
expired = ready && currentBlock > uint256(targetBlock) + 256;
fallbackActive = _rounds[roundId].randomnessFallbackActive;
}
function getRoundRandomness(uint256 roundId)
external
view
returns (bytes32 commitment, uint64 targetBlock, uint64 fallbackTime, bool fallbackActive)
{
Round storage round = _rounds[roundId];
return (
round.randomnessCommitment,
round.randomnessBlock,
round.randomnessFallbackTime,
round.randomnessFallbackActive
);
}
/// @notice Pays every remaining winner in one transaction.
/// @dev Permissionless. The caller pays gas. The round is capped at 53 allocations.
function payAllWinners(uint256 roundId) external nonReentrant {
Round storage round = _rounds[roundId];
if (round.state != RoundState.Cooldown) revert RoundNotReady();
uint256 allocationCount = _winnerAllocations[roundId].length;
if (allocationCount > MAX_WINNERS_PER_ROUND) revert TooManyWinnerAllocations();
uint256 remaining = allocationCount - uint256(round.payoutCursor);
_processWinnerPayments(roundId, round, remaining);
emit AllWinnersPaid(roundId, remaining);
}
/// @notice Emergency fallback that pays up to `maxPayments` rewards.
/// @dev Permissionless. Used only when a full-payment transaction cannot be estimated or executed.
function payWinners(uint256 roundId, uint8 maxPayments) external nonReentrant {
if (maxPayments == 0 || maxPayments > MAX_PAYOUTS_PER_TX) revert InvalidBatchSize();
Round storage round = _rounds[roundId];
if (round.state != RoundState.Cooldown) revert RoundNotReady();
_processWinnerPayments(roundId, round, maxPayments);
}
function _processWinnerPayments(uint256 roundId, Round storage round, uint256 maxPayments) internal {
WinnerAllocation[] storage allocations = _winnerAllocations[roundId];
uint256 cursor = round.payoutCursor;
uint256 startCursor = cursor;
uint256 processed;
while (cursor < allocations.length && processed < maxPayments) {
WinnerAllocation storage allocation = allocations[cursor];
if (!allocation.paid) {
allocation.paid = true;
claimable[roundId][allocation.wallet] -= allocation.amount;
totalClaimableWeth -= allocation.amount;
weth.safeTransfer(allocation.wallet, allocation.amount);
emit PrizePaid(
roundId,
allocation.wallet,
allocation.amount,
allocation.winnerType,
allocation.entryIndex
);
}
unchecked {
++cursor;
++processed;
}
}
round.payoutCursor = uint32(cursor);
emit PayoutBatchProcessed(roundId, startCursor, cursor, processed);
if (cursor == allocations.length) {
round.state = RoundState.Settled;
emit RoundPaymentsCompleted(roundId, round.finalPotWeth, uint64(block.timestamp));
}
}
/// @notice Permissionless after the 10-minute cooldown and only after every reward has been paid.
function startNextRound() external nonReentrant {
Round storage previous = _rounds[currentRoundId];
if (previous.state != RoundState.Settled || block.timestamp < previous.cooldownEnd) revert RoundNotReady();
if (previous.payoutCursor != previous.winnerAllocationCount) revert PaymentsPending();
_startNextRound();
}
function getCurrentRound() external view returns (CurrentRoundView memory result) {
Round storage round = _rounds[currentRoundId];
result.roundId = currentRoundId;
result.state = uint8(round.state);
result.startTime = round.startTime;
result.endTime = round.endTime;
result.cooldownEnd = round.cooldownEnd;
result.minimumBurn = _effectiveMinimumBurn(round);
result.startingPotWeth = round.startingPotWeth;
result.totalTokensIn = round.totalTokensIn;
result.entryCount = round.entryCount;
result.uniquePlayers = round.uniquePlayers;
result.payoutCursor = round.payoutCursor;
result.winnerAllocationCount = round.winnerAllocationCount;
}
function getRoundSummary(uint256 roundId) external view returns (RoundSummaryView memory result) {
Round storage round = _rounds[roundId];
result.state = uint8(round.state);
result.startTime = round.startTime;
result.endTime = round.endTime;
result.finalizedAt = round.finalizedAt;
result.cooldownEnd = round.cooldownEnd;
result.minimumBurn = round.minimumBurn;
result.startingPotWeth = round.startingPotWeth;
result.finalPotWeth = round.finalPotWeth;
result.totalTokensIn = round.totalTokensIn;
result.entryCount = round.entryCount;
result.uniquePlayers = round.uniquePlayers;
result.randomWinnerCount = round.randomWinnerCount;
result.payoutCursor = round.payoutCursor;
result.winnerAllocationCount = round.winnerAllocationCount;
}
function getRoundWinnerAllocations(uint256 roundId)
external
view
returns (
address[] memory wallets,
uint256[] memory amounts,
uint8[] memory winnerTypes,
uint256[] memory entryIndexes,
bool[] memory paid
)
{
WinnerAllocation[] storage source = _winnerAllocations[roundId];
uint256 length = source.length;
wallets = new address[](length);
amounts = new uint256[](length);
winnerTypes = new uint8[](length);
entryIndexes = new uint256[](length);
paid = new bool[](length);
for (uint256 i; i < length; ++i) {
WinnerAllocation storage item = source[i];
wallets[i] = item.wallet;
amounts[i] = item.amount;
winnerTypes[i] = uint8(item.winnerType);
entryIndexes[i] = item.entryIndex;
paid[i] = item.paid;
}
}
function getEntry(uint256 roundId, uint256 entryIndex) external view returns (Entry memory) {
return _entries[roundId][entryIndex];
}
function pendingWinnerPayments(uint256 roundId) external view returns (uint256) {
Round storage round = _rounds[roundId];
return uint256(round.winnerAllocationCount) - uint256(round.payoutCursor);
}
/// @notice On-chain TWAP fallback used by the backend when market-data APIs are unavailable.
function quoteTokenToWeth(uint256 tokenAmount) external view returns (uint256) {
return _oracleQuote(tokenAmount);
}
function _effectiveMinimumBurn(Round storage round) internal view returns (uint256) {
bool validPending = pendingMinimumBurn != 0
&& pendingBurnActivationTime != 0
&& pendingBurnActivationTime < round.endTime;
if (validPending && block.timestamp >= pendingBurnActivationTime && block.timestamp < round.endTime) {
return pendingMinimumBurn;
}
return round.minimumBurn;
}
function _activatePendingBurnAmount(Round storage round) internal returns (bool activated) {
if (round.state != RoundState.Active || block.timestamp >= round.endTime) return false;
return _activatePendingBurnAmountAt(round, uint64(block.timestamp));
}
function _activatePendingBurnAmountAt(Round storage round, uint64 effectiveTime)
internal
returns (bool activated)
{
if (
pendingMinimumBurn == 0 || pendingBurnActivationTime == 0
|| pendingBurnActivationTime >= round.endTime || effectiveTime < pendingBurnActivationTime
) return false;
uint256 previous = round.minimumBurn;
uint256 next = pendingMinimumBurn;
round.minimumBurn = next;
nextMinimumBurn = next;
pendingMinimumBurn = 0;
pendingBurnActivationTime = 0;
emit BurnAmountActivated(currentRoundId, previous, next);
return true;
}
function _finalizePendingBurnAmount(Round storage round) internal {
// A price is inherited by the next round only when its one-minute notice
// completed before this round's immutable end timestamp.
_activatePendingBurnAmountAt(round, round.endTime);
}
function _cancelPendingBurnAmount(uint256 roundId) internal {
if (pendingMinimumBurn == 0) return;
uint256 cancelled = pendingMinimumBurn;
pendingMinimumBurn = 0;
pendingBurnActivationTime = 0;
emit BurnAmountScheduleCancelled(roundId, cancelled);
}
function _minimumWethOut(uint256 sellAmount) internal view returns (uint256) {
uint256 oracleQuote = _oracleQuote(sellAmount);
uint256 minimumOut = FullMath.mulDiv(oracleQuote, BPS - maxSwapSlippageBps, BPS);
if (minimumOut == 0) revert InvalidSwapQuote();
return minimumOut;
}
function _oracleQuoteForCurrentMinimum(uint256 minimumBurn) internal view returns (uint256) {
return _oracleQuote(FullMath.mulDiv(minimumBurn, SWAP_BPS, BPS));
}
/// @dev Fails closed unless the configured pool can provide the complete TWAP window.
/// No spot-price fallback is permitted for a value-moving entry.
function _oracleQuote(uint256 sellAmount) internal view returns (uint256) {
if (sellAmount == 0 || sellAmount > type(uint128).max) revert InvalidSwapQuote();
if (pool.liquidity() == 0) revert InvalidSwapQuote();
uint32[] memory secondsAgos = new uint32[](2);
secondsAgos[0] = twapWindow;
secondsAgos[1] = 0;
(int56[] memory tickCumulatives,) = pool.observe(secondsAgos);
if (tickCumulatives.length != 2) revert InvalidSwapQuote();
int56 delta = tickCumulatives[1] - tickCumulatives[0];
int24 quoteTick = int24(delta / int56(uint56(twapWindow)));
if (delta < 0 && (delta % int56(uint56(twapWindow)) != 0)) quoteTick--;
uint256 quote = OracleQuoteLibrary.getQuoteAtTick(
quoteTick, uint128(sellAmount), address(token), address(weth)
);
if (quote == 0) revert InvalidSwapQuote();
return quote;
}
function _allocate(uint256 roundId, uint256 entryIndex, uint256 amount, WinnerType winnerType) internal {
if (amount == 0 || entryIndex == type(uint256).max) return;
address winner = _entries[roundId][entryIndex].player;
if (winner == address(0)) return;
claimable[roundId][winner] += amount;
_winnerAllocations[roundId].push(
WinnerAllocation({
wallet: winner,
amount: amount,
winnerType: winnerType,
entryIndex: entryIndex,
paid: false
})
);
emit PrizeAllocated(roundId, winner, amount, winnerType, entryIndex);
}
function _openPayoutCooldown(uint256 roundId, Round storage round) internal {
uint256 allocationCount = _winnerAllocations[roundId].length;
if (allocationCount > MAX_WINNERS_PER_ROUND) revert TooManyWinnerAllocations();
round.winnerAllocationCount = uint32(allocationCount);
round.state = round.winnerAllocationCount == 0 ? RoundState.Settled : RoundState.Cooldown;
if (round.winnerAllocationCount == 0) {
emit RoundPaymentsCompleted(roundId, 0, uint64(block.timestamp));
}
}
function _startNextRound() internal {
_cancelPendingBurnAmount(currentRoundId);
lastBurnScheduleTime = 0;
if (nextRandomnessCommitment == bytes32(0)) revert RandomnessCommitmentMissing();
currentRoundId += 1;
Round storage round = _rounds[currentRoundId];
round.randomnessCommitment = nextRandomnessCommitment;
nextRandomnessCommitment = bytes32(0);
round.state = RoundState.Active;
round.startTime = uint64(block.timestamp);
round.endTime = uint64(block.timestamp + INITIAL_DURATION);
round.minimumBurn = nextMinimumBurn;
roundEntropy[currentRoundId] = keccak256(abi.encode(address(this), currentRoundId, blockhash(block.number - 1)));
uint256 balance = weth.balanceOf(address(this));
if (balance < totalClaimableWeth) revert InsolventPot();
round.startingPotWeth = balance - totalClaimableWeth;
nextRoundCarryoverWeth = 0;
emit RoundStarted(currentRoundId, round.startTime, round.endTime, round.minimumBurn, round.startingPotWeth);
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "initialOwner",
"type": "address",
"internalType": "address"
},
{
"name": "tokenAddress",
"type": "address",
"internalType": "address"
},
{
"name": "wethAddress",
"type": "address",
"internalType": "address"
},
{
"name": "swapRouterAddress",
"type": "address",
"internalType": "address"
},
{
"name": "poolAddress",
"type": "address",
"internalType": "address"
},
{
"name": "feeDistributorAddress",
"type": "address",
"internalType": "address"
},
{
"name": "initialMinimumBurn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "twapWindowSeconds",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "maximumSwapSlippageBps",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "nonpayable"
},
{
"name": "BurnAmountChanged",
"type": "error",
"inputs": [
{
"name": "expectedAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "currentAmount",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "BurnAmountMustBeWholeTokens",
"type": "error",
"inputs": []
},
{
"name": "BurnChangeTooLarge",
"type": "error",
"inputs": [
{
"name": "currentAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "requestedAmount",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "BurnUpdateTooSoon",
"type": "error",
"inputs": [
{
"name": "nextAllowedTime",
"type": "uint64",
"internalType": "uint64"
}
]
},
{
"name": "BurnUpdateWindowClosed",
"type": "error",
"inputs": []
},
{
"name": "GameAlreadyStarted",
"type": "error",
"inputs": []
},
{
"name": "GameNotStarted",
"type": "error",
"inputs": []
},
{
"name": "InsolventPot",
"type": "error",
"inputs": []
},
{
"name": "InvalidAddress",
"type": "error",
"inputs": []
},
{
"name": "InvalidAmount",
"type": "error",
"inputs": []
},
{
"name": "InvalidBatchSize",
"type": "error",
"inputs": []
},
{
"name": "InvalidPool",
"type": "error",
"inputs": []
},
{
"name": "InvalidRandomnessReveal",
"type": "error",
"inputs": []
},
{
"name": "InvalidSwapQuote",
"type": "error",
"inputs": []
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ParticipationPaused",
"type": "error",
"inputs": []
},
{
"name": "PaymentsPending",
"type": "error",
"inputs": []
},
{
"name": "RandomnessCommitmentMissing",
"type": "error",
"inputs": []
},
{
"name": "RandomnessExpired",
"type": "error",
"inputs": []
},
{
"name": "RandomnessNotReady",
"type": "error",
"inputs": []
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "RoundNotActive",
"type": "error",
"inputs": []
},
{
"name": "RoundNotReady",
"type": "error",
"inputs": []
},
{
"name": "RoundStillRunning",
"type": "error",
"inputs": []
},
{
"name": "SafeERC20FailedOperation",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "SwapOutputTooLow",
"type": "error",
"inputs": []
},
{
"name": "TooManyWinnerAllocations",
"type": "error",
"inputs": []
},
{
"name": "UnauthorizedBurnPriceUpdater",
"type": "error",
"inputs": []
},
{
"name": "UnauthorizedFeeDistributor",
"type": "error",
"inputs": []
},
{
"name": "UnauthorizedRandomnessCommitter",
"type": "error",
"inputs": []
},
{
"name": "AllWinnersPaid",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "payments",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BurnAmountActivated",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "previousAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "newAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BurnAmountScheduleCancelled",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "cancelledAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BurnAmountScheduled",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "currentAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "pendingAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "activationTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "BurnPriceUpdaterUpdated",
"type": "event",
"inputs": [
{
"name": "previousUpdater",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newUpdater",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "BurnRegistered",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "entryIndex",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "player",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokensIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "burnedTokens",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "soldTokens",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "wethAddedToPot",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "newEndTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "burnedAt",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "CreatorFeesDeposited",
"type": "event",
"inputs": [
{
"name": "creditedRoundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "distributor",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "carriedToNextRound",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "FeeDistributorUpdated",
"type": "event",
"inputs": [
{
"name": "previousDistributor",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newDistributor",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "GameStarted",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "startTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "endTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "NextRandomnessCommitted",
"type": "event",
"inputs": [
{
"name": "targetRoundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "commitment",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferStarted",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "ParticipationPauseUpdated",
"type": "event",
"inputs": [
{
"name": "paused",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "PayoutBatchProcessed",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "fromIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "toIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "payments",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "PrizeAllocated",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "winner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "winnerType",
"type": "uint8",
"indexed": false,
"internalType": "enum BurnWarsGameV27_4.WinnerType"
},
{
"name": "entryIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "PrizePaid",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "winner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "winnerType",
"type": "uint8",
"indexed": false,
"internalType": "enum BurnWarsGameV27_4.WinnerType"
},
{
"name": "entryIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "RandomWinnersSelected",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "winnerCount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "seed",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "RandomnessCommitterUpdated",
"type": "event",
"inputs": [
{
"name": "previousCommitter",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newCommitter",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RandomnessFallbackActivated",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "targetBlock",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "RandomnessFallbackUsed",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "seed",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "RandomnessScheduled",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "targetBlock",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "RoundFinalized",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "finalPotWeth",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "firstEntryIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "secondEntryIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "thirdEntryIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "finalizedAt",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "RoundPaymentsCompleted",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "totalPaid",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "completedAt",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "RoundStarted",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "startTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "endTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "minimumBurn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "startingPotWeth",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "BURN_AMOUNT_ACTIVATION_DELAY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "BURN_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "BURN_UPDATE_MIN_INTERVAL",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "COOLDOWN",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "DEAD",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "EXTENSION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "FIRST_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "INITIAL_DURATION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "MAX_CONFIGURABLE_SLIPPAGE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "MAX_PAYOUTS_PER_TX",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "MAX_RANDOM_WINNERS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "MAX_REMAINING",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "MAX_TWAP_WINDOW",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "MAX_WINNERS_PER_ROUND",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "ORACLE_CARDINALITY_TARGET",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "RANDOMNESS_BLOCK_DELAY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "RANDOMNESS_FALLBACK_DELAY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "RANDOM_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "SECOND_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "SWAP_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "THIRD_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "activateRandomnessFallback",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "applyPendingBurnAmount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "activated",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "availablePotBalance",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "burnAndEnter",
"type": "function",
"inputs": [
{
"name": "expectedBurnAmount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "burnPriceUpdater",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "claimable",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "contractVersion",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "pure"
},
{
"name": "currentRoundId",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "depositCreatorFees",
"type": "function",
"inputs": [
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "feeDistributor",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "finalizeRound",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "gameStarted",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "getBurnPricing",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "currentAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "pendingAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "activationTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "secondsUntilActivation",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "getCurrentRound",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "result",
"type": "tuple",
"components": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "state",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "startTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "endTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "cooldownEnd",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "minimumBurn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "startingPotWeth",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "totalTokensIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "entryCount",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "uniquePlayers",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "payoutCursor",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "winnerAllocationCount",
"type": "uint32",
"internalType": "uint32"
}
],
"internalType": "struct BurnWarsGameV27_4.CurrentRoundView"
}
],
"stateMutability": "view"
},
{
"name": "getEntry",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "entryIndex",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "player",
"type": "address",
"internalType": "address"
},
{
"name": "tokensIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tokensBurned",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tokensSold",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "wethAddedToPot",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "burnedAt",
"type": "uint64",
"internalType": "uint64"
}
],
"internalType": "struct BurnWarsGameV27_4.Entry"
}
],
"stateMutability": "view"
},
{
"name": "getPotAccounting",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "contractWethBalance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "reservedForWinners",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "activeRoundPot",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "nextRoundCarryover",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getPotStatus",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "contractWethBalance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "reservedForWinners",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "availablePot",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getRandomnessStatus",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "targetBlock",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "currentBlock",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "ready",
"type": "bool",
"internalType": "bool"
},
{
"name": "expired",
"type": "bool",
"internalType": "bool"
},
{
"name": "fallbackActive",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "getRoundRandomness",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "commitment",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "targetBlock",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "fallbackTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "fallbackActive",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "getRoundSummary",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "result",
"type": "tuple",
"components": [
{
"name": "state",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "startTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "endTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "finalizedAt",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "cooldownEnd",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "minimumBurn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "startingPotWeth",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "finalPotWeth",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "totalTokensIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "entryCount",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "uniquePlayers",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "randomWinnerCount",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "payoutCursor",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "winnerAllocationCount",
"type": "uint32",
"internalType": "uint32"
}
],
"internalType": "struct BurnWarsGameV27_4.RoundSummaryView"
}
],
"stateMutability": "view"
},
{
"name": "getRoundWinnerAllocations",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "wallets",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "amounts",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "winnerTypes",
"type": "uint8[]",
"internalType": "uint8[]"
},
{
"name": "entryIndexes",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "paid",
"type": "bool[]",
"internalType": "bool[]"
}
],
"stateMutability": "view"
},
{
"name": "lastBurnScheduleTime",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "maxSwapSlippageBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "nextMinimumBurn",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "nextRandomnessCommitment",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "nextRoundCarryoverWeth",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "participationPaused",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "payAllWinners",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "payWinners",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "maxPayments",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "pendingBurnActivationTime",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "pendingMinimumBurn",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "pendingOwner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingWinnerPayments",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "pool",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IUniswapV3Pool"
}
],
"stateMutability": "view"
},
{
"name": "poolFee",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint24",
"internalType": "uint24"
}
],
"stateMutability": "view"
},
{
"name": "prepareNextRoundRandomness",
"type": "function",
"inputs": [
{
"name": "commitment",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "quoteCurrentEntryWethOut",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "oracleQuote",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minimumOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "quoteTokenToWeth",
"type": "function",
"inputs": [
{
"name": "tokenAmount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "randomnessCommitter",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "refreshRandomnessBlock",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "view"
},
{
"name": "roundEntropy",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "scheduleBurnAmount",
"type": "function",
"inputs": [
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setBurnPriceUpdater",
"type": "function",
"inputs": [
{
"name": "newUpdater",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFeeDistributor",
"type": "function",
"inputs": [
{
"name": "newDistributor",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setParticipationPaused",
"type": "function",
"inputs": [
{
"name": "paused",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setRandomnessCommitter",
"type": "function",
"inputs": [
{
"name": "newCommitter",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "settleRandomWinners",
"type": "function",
"inputs": [
{
"name": "secret",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "settleRandomWinnersFallback",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "startGame",
"type": "function",
"inputs": [
{
"name": "firstRoundCommitment",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "startNextRound",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "swapRouter",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract ISwapRouter02"
}
],
"stateMutability": "view"
},
{
"name": "token",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IERC20"
}
],
"stateMutability": "view"
},
{
"name": "tokenDecimals",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "tokenUnit",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "totalClaimableWeth",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "twapWindow",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "weth",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IERC20"
}
],
"stateMutability": "view"
}
]0x6101a060405260015f5534801562000015575f80fd5b5060405162006b2638038062006b2683398101604081905262000038916200070b565b886001600160a01b0381166200006757604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040515f907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b0389161580620000d157506001600160a01b03891661dead145b80620000e457506001600160a01b038816155b80620000f757506001600160a01b038716155b806200010a57506001600160a01b038616155b806200011d57506001600160a01b038516155b806200013057506001600160a01b038416155b806200014657506001600160a01b03841661dead145b15620001655760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0388163b15806200018557506001600160a01b0387163b155b806200019957506001600160a01b0386163b155b80620001ad57506001600160a01b0385163b155b15620001cc5760405163e6c4247b60e01b815260040160405180910390fd5b821580620001e05750601e8263ffffffff16105b80620001f457506201518063ffffffff8316115b8062000202575061ffff8116155b806200021357506107d061ffff8216115b15620002325760405163162908e360e11b815260040160405180910390fd5b6001600160a01b03808916608081905288821660a05287821660c05286821660e052600380549287166001600160a01b0319938416811790915560048054841682178155600580549094169091179092556040805163313ce56760e01b815290515f9363313ce567928082019260209290918290030181865afa158015620002bc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620002e29190620007e3565b905060248160ff1611156200030a5760405163162908e360e11b815260040160405180910390fd5b5f6200031b60ff8316600a62000915565b905062000329818662000922565b151580620003985750896001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200036f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000395919062000942565b85115b15620003b75760405163160e7f3760e21b815260040160405180910390fd5b60ff9091166101605261018052600783905563ffffffff82166101205261ffff81166101405260408051630dfe168160e01b815290515f916001600160a01b03881691630dfe1681916004808201926020929091908290030181865afa15801562000424573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200044a91906200095a565b90505f866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200048a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620004b091906200095a565b90505f8a6001600160a01b0316836001600160a01b0316148015620004e65750896001600160a01b0316826001600160a01b0316145b80620005205750896001600160a01b0316836001600160a01b03161480156200052057508a6001600160a01b0316826001600160a01b0316145b905080620005405760405162820f3560e61b815260040160405180910390fd5b5050505f856001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000581573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620005a7919062000978565b90508062ffffff165f03620005ce5760405162820f3560e61b815260040160405180910390fd5b8062ffffff166101008162ffffff16815250505f866001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156200061f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200064591906200099c565b5050505050509050806001600160a01b03165f03620006765760405162820f3560e61b815260040160405180910390fd5b50604080516332148f6760e01b815260048101919091526001600160a01b038716906332148f67906024015f604051808303815f87803b158015620006b9575f80fd5b505af1925050508015620006cb575060015b505050505050505050505062000a3d565b6001600160a01b0381168114620006f1575f80fd5b50565b805161ffff8116811462000706575f80fd5b919050565b5f805f805f805f805f6101208a8c03121562000725575f80fd5b89516200073281620006dc565b60208b01519099506200074581620006dc565b60408b01519098506200075881620006dc565b60608b01519097506200076b81620006dc565b60808b01519096506200077e81620006dc565b60a08b01519095506200079181620006dc565b60c08b015160e08c0151919550935063ffffffff81168114620007b2575f80fd5b9150620007c36101008b01620006f4565b90509295985092959850929598565b805160ff8116811462000706575f80fd5b5f60208284031215620007f4575f80fd5b620007ff82620007d2565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b600181815b808511156200085a57815f19048211156200083e576200083e62000806565b808516156200084c57918102915b93841c93908002906200081f565b509250929050565b5f8262000872575060016200090f565b816200088057505f6200090f565b8160018114620008995760028114620008a457620008c4565b60019150506200090f565b60ff841115620008b857620008b862000806565b50506001821b6200090f565b5060208310610133831016604e8410600b8410161715620008e9575081810a6200090f565b620008f583836200081a565b805f19048211156200090b576200090b62000806565b0290505b92915050565b5f620007ff838362000862565b5f826200093d57634e487b7160e01b5f52601260045260245ffd5b500690565b5f6020828403121562000953575f80fd5b5051919050565b5f602082840312156200096b575f80fd5b8151620007ff81620006dc565b5f6020828403121562000989575f80fd5b815162ffffff81168114620007ff575f80fd5b5f805f805f805f60e0888a031215620009b3575f80fd5b8751620009c081620006dc565b8097505060208801518060020b8114620009d8575f80fd5b9550620009e860408901620006f4565b9450620009f860608901620006f4565b935062000a0860808901620006f4565b925062000a1860a08901620007d2565b915060c0880151801515811462000a2d575f80fd5b8091505092959891949750929550565b60805160a05160c05160e0516101005161012051610140516101605161018051615fb162000b755f395f8181610a94015261130201525f61055001525f818161093c015281816115f40152614f5a01525f8181610733015281816138c601528181613a3b0152613a7a01525f818161040b015261495301525f8181610493015281816137fe015261395301525f818161096d0152818161499d01528181614a2a0152614ac601525f818161057f01528181610d69015281816117f401528181611ec50152818161260f01528181613ae201528181613c6901528181613ed201528181614863015281816149260152614b0401525f8181610afa0152818161125e015281816130f90152818161317c015281816131bd015281816132be01528181613ac1015281816149000152614aa40152615fb15ff3fe608060405234801561000f575f80fd5b50600436106103af575f3560e01c8063030f386c146103b357806303fd2a45146103c85780630597725e146103e75780630837f88e146103fe578063089fe6aa146104065780630a37e4fb146104415780630b5ffd131461045d5780630d43e8ad14610473578063132a518c1461048657806316f0115b1461048e5780631bfb7699146104b55780631c40c7d8146104c85780631cfe7edf146104db5780631e820325146104f55780631eddd2eb146104fd578063249d39e9146105105780632718d34e146105195780632aac1a5a1461052257806335223a5a146105355780633b97e8561461054b5780633c3ccc44146105725780633fc8cef31461057a57806346e0c91e146105a157806346f13619146105aa5780634c92fb12146105b25780634cacbdf1146105c55780634f022c4d146105ce57806357f9ebf3146105e55780635882f4da146105ed5780635950458c1461060c5780635e123ce4146106165780635edadf141461063a5780636372fbc11461064357806363c2ed151461065657806365728bc61461066957806369b947e014610672578063715018a6146106b55780637705a363146106bd578063788c1338146106c557806378b5a297146106df57806378dd1de4146106f25780637916e4fa146106fa5780637988e7231461070d57806379ba5097146107155780637ad5367c1461071d5780637bc75e82146107255780638107e1331461072e578063885620bb1461076a5780638da5cb5b146107ed5780638f716d74146107f55780639345ba0214610808578063964c065b1461060c57806398ba676d1461081b5780639cbe5efd146108875780639dcfa49314610890578063a0a8e460146108a3578063a0c7f71c146108cb578063a2724a4d146108f5578063a32bf597146108fe578063a37a9fc014610913578063a4b7c5451461091c578063b4a7698e1461092f578063b7c3565d14610937578063b88a92b41461095e578063c31c9c0714610968578063c515cf151461098f578063c5f5293c14610998578063c868e02e146109ac578063cca5e0d9146109cc578063ccfc2e8d146109d5578063d5ffb242146109e8578063d7ea41a614610a10578063e2232eba14610a23578063e30c397814610a5a578063e53e3f4f14610a6b578063e5da886d14610a73578063e7b542f614610a86578063e93c980d14610a8f578063ea6a632614610ab6578063effaa1cb14610ada578063f2fde38b14610ae2578063fc0c546a14610af5578063ff874c051461098f575b5f80fd5b6103c66103c1366004615534565b610b1c565b005b6103d161dead81565b6040516103de919061554f565b60405180910390f35b6103f0600c5481565b6040519081526020016103de565b6103c6610be1565b61042d7f000000000000000000000000000000000000000000000000000000000000000081565b60405162ffffff90911681526020016103de565b61044a6107d081565b60405161ffff90911681526020016103de565b610466610e1081565b6040516103de9190615570565b6003546103d1906001600160a01b031681565b6103f0610d65565b6103d17f000000000000000000000000000000000000000000000000000000000000000081565b6103f06104c3366004615584565b610e39565b6005546103d1906001600160a01b031681565b6104e3603581565b60405160ff90911681526020016103de565b6103c6610e72565b6103c661050b366004615584565b61109f565b6103f061271081565b6103f061138881565b6103c6610530366004615584565b6111d8565b61053d611593565b6040516103de92919061559b565b6104e37f000000000000000000000000000000000000000000000000000000000000000081565b6103c661162c565b6103d17f000000000000000000000000000000000000000000000000000000000000000081565b6103f06103e881565b610466601e81565b6103c66105c0366004615584565b6116fa565b6103f060085481565b6105d66117ef565b6040516103de939291906155a9565b6104e3600a81565b6103f06105fb366004615584565b60146020525f908152604090205481565b6104666201518081565b60055461062a90600160a01b900460ff1681565b60405190151581526020016103de565b61046661012c81565b6004546103d1906001600160a01b031681565b6103f0610664366004615584565b6118c8565b6103f0600a5481565b61067a6118d8565b604080519687526001600160401b039095166020870152938501929092521515606084015215156080830152151560a082015260c0016103de565b6103c661196c565b61062a6119b4565b60095461046690600160401b90046001600160401b031681565b6103c66106ed3660046155cc565b611a2d565b610466600881565b6103c6610708366004615584565b611ab2565b61044a604081565b6103c6611c5c565b6103c6611ce3565b6103f060075481565b6107557f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016103de565b6107bb610778366004615584565b5f908152600d602052604090206008810154600682015460079092015490926001600160401b03600160881b90930483169282169160ff600160401b9091041690565b6040516103de94939291909384526001600160401b039283166020850152911660408301521515606082015260800190565b6103d1611e38565b6103c6610803366004615584565b611e47565b6103c66108163660046155e7565b611fe6565b61082e61082936600461561a565b612096565b6040516103de919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201516001600160401b03169181019190915260c00190565b6103f060065481565b6103c661089e366004615534565b61210f565b6040805180820182526006815265032372e342e360d41b602082015290516103de919061565c565b6103f06108d936600461568e565b601360209081525f928352604080842090915290825290205481565b61046661025881565b6109066121cb565b6040516103de91906156b1565b6103f0611b5881565b6103c661092a366004615584565b6122f0565b610466603c81565b61044a7f000000000000000000000000000000000000000000000000000000000000000081565b6107556201518081565b6103d17f000000000000000000000000000000000000000000000000000000000000000081565b6103f06107d081565b60055461062a90600160a81b900460ff1681565b6109bf6109ba366004615584565b6123f8565b6040516103de9190615784565b6103f0600b5481565b6103c66109e3366004615534565b61254d565b6109f0612609565b6040805194855260208501939093529183015260608201526080016103de565b6103c6610a1e366004615584565b6126e6565b610a2b61279e565b6040805194855260208501939093526001600160401b03918216928401929092521660608201526080016103de565b6002546001600160a01b03166103d1565b6104e3603281565b600954610466906001600160401b031681565b6103f0610bb881565b6103f07f000000000000000000000000000000000000000000000000000000000000000081565b610ac9610ac4366004615584565b612876565b6040516103de959493929190615902565b6103c6612b1b565b6103c6610af0366004615534565b612c4d565b6103d17f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b03163314610b52573360405163118cdaa760e01b8152600401610b49919061554f565b60405180910390fd5b6001600160a01b0381161580610b7257506001600160a01b03811661dead145b15610b905760405163e6c4247b60e01b815260040160405180910390fd5b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fd012192ad897398417bfd9744d72f34e12dc2a6383f050db122ce11e98905c5d905f90a35050565b60025f5403610c0357604051633ee5aeb560e01b815260040160405180910390fd5b60025f818155600654808252600d60205260409091209091815460ff166004811115610c3157610c31615995565b141580610c4a57506007810154600160401b900460ff16155b15610c675760405162facebb60e61b815260040160405180910390fd5b6006810154600160881b90046001600160401b0316438110610c9c57604051637b91e42d60e11b815260040160405180910390fd5b804080610cbc57604051634604c5f960e11b815260040160405180910390fd5b60088301545f858152601460209081526040808320546004880154600689015492519495610cfc95909488948c939263ffffffff909116913091016159a9565b604051602081830303815290604052805190602001209050847f718da713b81f655e0d5d9981d8269c2fcd2eb87ee792688e246ce209f9f1bc2d82604051610d4691815260200190565b60405180910390a2610d5a85858380612cf4565b505060015f55505050565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610db3919061554f565b602060405180830381865afa158015610dce573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df291906159e8565b90505f600c54600b54610e059190615a13565b905080821015610e28576040516315c45db960e11b815260040160405180910390fd5b610e328183615a26565b9250505090565b5f818152600d602052604081206006810154610e6b9063ffffffff600160401b8204811691600160601b900416615a26565b9392505050565b60025f5403610e9457604051633ee5aeb560e01b815260040160405180910390fd5b60025f55600554600160a01b900460ff16610ec257604051633a5f7b5760e01b815260040160405180910390fd5b6006545f818152600d602052604090206001815460ff166004811115610eea57610eea615995565b14610f075760405162facebb60e61b815260040160405180910390fd5b8054600160481b90046001600160401b0316421015610f3957604051630a1e85db60e11b815260040160405180910390fd5b610f4281612dd9565b610f4b82612df6565b80546001600160401b0342908116600160881b02600160881b600160c81b0319909216919091178255610f819061025890615a13565b6001820180546001600160401b0319166001600160401b0392909216919091179055600681015463ffffffff165f819003610fc857610fc08383612e4c565b505050611099565b5f610fd4848484612ec2565b9050805f03610ff057610fe78484612fc4565b50505050611099565b825460ff19166002178355611006600843615a13565b6006840180546001600160401b0392909216600160881b02600160881b600160c81b03199092169190911790556110406201518042615a13565b6007840180546001600160481b0319166001600160401b03928316179055600684015460405186925f80516020615f5c8339815191529261108c92600160881b90910490911690615570565b60405180910390a2505050505b60015f55565b60025f54036110c157604051633ee5aeb560e01b815260040160405180910390fd5b60025f55600554600160a01b900460ff166110ef57604051633a5f7b5760e01b815260040160405180910390fd5b600554600160a81b900460ff161561111a57604051635bc4057960e01b815260040160405180910390fd5b6006545f818152600d602052604090206001815460ff16600481111561114257611142615995565b14158061116057508054600160481b90046001600160401b03164210155b1561117e57604051633df07da560e01b815260040160405180910390fd5b6111878161308b565b50806002015483146111b357600281015460405163bd73822360e01b8152610b4991859160040161559b565b5f6111be84336130d8565b90505f6111cc848484613301565b9050610d5a84826135c3565b6004546001600160a01b0316331480159061120c57506111f6611e38565b6001600160a01b0316336001600160a01b031614155b1561122a57604051631b8d200760e01b815260040160405180910390fd5b600554600160a01b900460ff1661125457604051633a5f7b5760e01b815260040160405180910390fd5b8015806112df57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112dc91906159e8565b81115b156112fd5760405163162908e360e11b815260040160405180910390fd5b6113277f000000000000000000000000000000000000000000000000000000000000000082615a4d565b156113455760405163160e7f3760e21b815260040160405180910390fd5b6006545f908152600d602052604090206001815460ff16600481111561136d5761136d615995565b14158061138b57508054600160481b90046001600160401b03164210155b156113a957604051633df07da560e01b815260040160405180910390fd5b6113b28161308b565b50806002015482036113cd576113c9600654612df6565b5050565b81600854036113da575050565b60095442905f906113fe9061012c90600160401b90046001600160401b0316615a60565b600954909150600160401b90046001600160401b0316158015906114335750806001600160401b0316826001600160401b0316105b156114535780604051637259add760e11b8152600401610b499190615570565b5f61145f603c84615a60565b84549091506001600160401b03600160481b9091048116908216106114975760405163136b300d60e01b815260040160405180910390fd5b600280850154905f906114ab908390615a87565b90505f60026114bb846001615a13565b6114c59190615a9e565b9050818811806114d457508088105b156114f657828860405163e57fe7f760e01b8152600401610b4992919061559b565b6114ff8861367e565b506008889055600980546001600160401b03888116600160401b026001600160801b03199092169087161717905560065460028801546040517fb43357481cfbfea92bea0d2bb4b3b4ea5c45b399fa096c3f6758baea27656af491611581918c90899092835260208301919091526001600160401b0316604082015260600190565b60405180910390a25050505050505050565b6005545f908190600160a01b900460ff166115b057505f91829150565b6006545f908152600d602052604081206115c990613696565b90505f6115db82610bb8612710613724565b90506115e6816137ca565b93506116248461161c61ffff7f000000000000000000000000000000000000000000000000000000000000000016612710615a26565b612710613724565b925050509091565b60025f540361164e57604051633ee5aeb560e01b815260040160405180910390fd5b60025f9081556006548152600d602052604090206003815460ff16600481111561167a5761167a615995565b141580611693575060018101546001600160401b031642105b156116b05760405162facebb60e61b815260040160405180910390fd5b6006810154600160401b810463ffffffff908116600160601b90920416146116eb576040516370136f7360e01b815260040160405180910390fd5b6116f3613b32565b5060015f55565b6001546001600160a01b03163314611727573360405163118cdaa760e01b8152600401610b49919061554f565b600554600160a01b900460ff16156117525760405163ba26162b60e01b815260040160405180910390fd5b61175b816126e6565b61176660075461367e565b506005805460ff60a01b1916600160a01b179055611782613b32565b6006545f818152600d6020908152604091829020805483516001600160401b03610100830481168252600160481b9092049091169281019290925292917fdf90cf1ad255c56e947d160fdc96fe384c300c7d8d08c302aa418686a162d0c191015b60405180910390a25050565b5f805f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161183e919061554f565b602060405180830381865afa158015611859573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187d91906159e8565b9250600b5491505f600c54836118939190615a13565b9050808410156118b6576040516315c45db960e11b815260040160405180910390fd5b6118c08185615a26565b915050909192565b5f6118d2826137ca565b92915050565b600680545f818152600d60205260408120909201549091600160881b9091046001600160401b03169043908080841580159061191c5750846001600160401b031684115b925082801561193e575061193b6001600160401b038616610100615a13565b84115b9150600d5f8781526020019081526020015f2060070160089054906101000a900460ff169050909192939495565b6001546001600160a01b03163314611999573360405163118cdaa760e01b8152600401610b49919061554f565b5f604051631e4fbdf760e01b8152600401610b49919061554f565b6005545f90600160a01b900460ff166119cc57505f90565b6006545f908152600d602052604090206001815460ff1660048111156119f4576119f4615995565b141580611a1257508054600160481b90046001600160401b03164210155b15611a1e575f91505090565b611a278161308b565b91505090565b6001546001600160a01b03163314611a5a573360405163118cdaa760e01b8152600401610b49919061554f565b60058054821515600160a81b0260ff60a81b199091161790556040517f1cb73f7e76b5e9b5d7e8ec0883e2dc6c655c40d684bca1832dce24cb6502527e90611aa790831515815260200190565b60405180910390a150565b60025f5403611ad457604051633ee5aeb560e01b815260040160405180910390fd5b60025f818155600654808252600d60205260409091209091815460ff166004811115611b0257611b02615995565b14611b1f5760405162facebb60e61b815260040160405180910390fd5b6007810154600160401b900460ff1615611b4c57604051637b91e42d60e11b815260040160405180910390fd5b8060080154308385604051602001611b6693929190615ab1565b6040516020818303038152906040528051906020012014611b9a57604051636ab5da2b60e01b815260040160405180910390fd5b6006810154600160881b90046001600160401b0316438110611bcf57604051637b91e42d60e11b815260040160405180910390fd5b804080611bef57604051634604c5f960e11b815260040160405180910390fd5b5f84815260146020908152604080832054600487015460068801549251611c2a948b948894938c93909263ffffffff909216913091016159a9565b604051602081830303815290604052805190602001209050611c508585835f1c84612cf4565b505060015f5550505050565b6002546001600160a01b03163314611c89573360405163118cdaa760e01b8152600401610b49919061554f565b600180546001600160a01b0319808216339081179093556002805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a350565b6006545f818152600d602052604090206002815460ff166004811115611d0b57611d0b615995565b14611d285760405162facebb60e61b815260040160405180910390fd5b6006810154611d4990600160881b90046001600160401b0316610100615a13565b4311611d6857604051637b91e42d60e11b815260040160405180910390fd5b600781018054600160401b60ff60401b19821681179092550460ff16611d8f600843615a13565b8260060160116101000a8154816001600160401b0302191690836001600160401b0316021790555080611df857600682015460405184915f80516020615f3c83398151915291611def91600160881b90046001600160401b031690615570565b60405180910390a25b600682015460405184915f80516020615f5c83398151915291611e2b91600160881b90046001600160401b031690615570565b60405180910390a2505050565b6001546001600160a01b031690565b60025f5403611e6957604051633ee5aeb560e01b815260040160405180910390fd5b60025f556003546001600160a01b03163314611e9857604051637a11843360e01b815260040160405180910390fd5b805f03611eb85760405163162908e360e11b815260040160405180910390fd5b611eed6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084613d84565b6005546001905f90600160a01b900460ff16611f0a576001611f18565b600654611f18906001615a13565b600554909150600160a01b900460ff1615611f82576006545f908152600d602052604090206001815460ff166004811115611f5557611f55615995565b148015611f7257508054600160481b90046001600160401b031642105b15611f80575f925060065491505b505b8115611f9f5782600c5f828254611f999190615a13565b90915550505b604080518481528315156020820152339183917f64c0123778195ae68f9df99ac43bde277e108253249a83e9b57fc99bd3eae952910160405180910390a3505060015f5550565b60025f540361200857604051633ee5aeb560e01b815260040160405180910390fd5b60025f5560ff8116158061201f5750600a60ff8216115b1561203d57604051637862e95960e01b815260040160405180910390fd5b5f828152600d602052604090206004815460ff16600481111561206257612062615995565b1461207f5760405162facebb60e61b815260040160405180910390fd5b61208d83828460ff16613deb565b505060015f5550565b61209e6154db565b505f918252600e6020908152604080842092845291815291819020815160c08101835281546001600160a01b031681526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600501546001600160401b031660a082015290565b6001546001600160a01b0316331461213c573360405163118cdaa760e01b8152600401610b49919061554f565b6001600160a01b038116158061215c57506001600160a01b03811661dead145b1561217a5760405163e6c4247b60e01b815260040160405180910390fd5b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fdd8bcf61c48bec82fb1e075ae14a3e3785fefd64468c20112aa0e48bdbf4f89b905f90a35050565b60408051610180810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101919091526006545f818152600d60205260409020908252805460ff16600481111561225457612254615995565b60ff16602083015280546001600160401b03610100820481166040850152600160481b90910481166060840152600182015416608083015261229581613696565b60a0830152600381015460c0830152600581015460e08301526006015463ffffffff808216610100840152600160201b82048116610120840152600160401b82048116610140840152600160601b9091041661016082015290565b60025f540361231257604051633ee5aeb560e01b815260040160405180910390fd5b60025f908155818152600d602052604090206004815460ff16600481111561233c5761233c615995565b146123595760405162facebb60e61b815260040160405180910390fd5b5f828152601260205260409020546035811115612389576040516301eccb0960e51b815260040160405180910390fd5b60068201545f906123a790600160401b900463ffffffff1683615a26565b90506123b4848483613deb565b837f707eea9fa1d1d69eac18fe206c3b311a4e489f2abb27e9dd38fde4986b9ea05a826040516123e691815260200190565b60405180910390a2505060015f555050565b604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091525f828152600d60205260409020805460ff16600481111561248b5761248b615995565b60ff908116835281546001600160401b0361010080830482166020870152600160481b830482166040870152600160881b909204811660608601526001840154166080850152600283015460a0850152600383015460c0850152600483015460e085015260058301549084015260069091015463ffffffff808216610120850152600160201b82048116610140850152600160801b8204909216610160840152600160401b81048216610180840152600160601b9004166101a0820152919050565b6001546001600160a01b0316331461257a573360405163118cdaa760e01b8152600401610b49919061554f565b6001600160a01b038116158061259a57506001600160a01b03811661dead145b156125b85760405163e6c4247b60e01b815260040160405180910390fd5b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fbb470d12faa974cbae56bc3c345446451b4d504aa13806836f3df6d032fa9a91905f90a35050565b5f805f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612659919061554f565b602060405180830381865afa158015612674573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061269891906159e8565b600b54600c54919550935090505f6126b08285615a13565b9050808510156126d3576040516315c45db960e11b815260040160405180910390fd5b6126dd8186615a26565b92505090919293565b6005546001600160a01b0316331480159061271a5750612704611e38565b6001600160a01b0316336001600160a01b031614155b1561273857604051631cf076c760e11b815260040160405180910390fd5b8061275657604051631cef5d9f60e01b815260040160405180910390fd5b5f60065460016127669190615a13565b600a839055604051909150829082907f16779bc4ee4f6bcd092281f5e36e02d1a9360a94c4eeb04d57c6fbfcd1e5fa65905f90a35050565b6006545f908152600d602052604081206002810154600854600954919390926001600160401b03909216918184158015906127e157506001600160401b03841615155b8015612801575081546001600160401b03600160481b9091048116908516105b90508061281957505f93508392508291506128709050565b836001600160401b0316421015801561284257508154600160481b90046001600160401b031642105b1561284f5784955061286d565b836001600160401b031642101561286d5761286a4285615ad2565b92505b50505b90919293565b5f8181526012602052604090208054606091829182918291829190806001600160401b038111156128a9576128a9615af2565b6040519080825280602002602001820160405280156128d2578160200160208202803683370190505b509650806001600160401b038111156128ed576128ed615af2565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b509550806001600160401b0381111561293157612931615af2565b60405190808252806020026020018201604052801561295a578160200160208202803683370190505b509450806001600160401b0381111561297557612975615af2565b60405190808252806020026020018201604052801561299e578160200160208202803683370190505b509350806001600160401b038111156129b9576129b9615af2565b6040519080825280602002602001820160405280156129e2578160200160208202803683370190505b5092505f5b81811015612b0f575f838281548110612a0257612a02615b06565b5f918252602090912060059091020180548a519192506001600160a01b0316908a9084908110612a3457612a34615b06565b60200260200101906001600160a01b031690816001600160a01b0316815250508060010154888381518110612a6b57612a6b615b06565b6020908102919091010152600281015460ff166004811115612a8f57612a8f615995565b878381518110612aa157612aa1615b06565b602002602001019060ff16908160ff16815250508060030154868381518110612acc57612acc615b06565b60209081029190910101526004810154855160ff90911690869084908110612af657612af6615b06565b91151560209283029190910190910152506001016129e7565b50505091939590929450565b6006545f818152600d602052604090206002815460ff166004811115612b4357612b43615995565b14612b605760405162facebb60e61b815260040160405180910390fd5b6007810154600160401b900460ff1680612b86575060078101546001600160401b031642105b15612ba457604051637b91e42d60e11b815260040160405180910390fd5b60078101805460ff60401b1916600160401b179055612bc4600843615a13565b600682018054600160881b600160c81b031916600160881b6001600160401b039384168102919091179182905560405185935f80516020615f3c83398151915293612c129390041690615570565b60405180910390a2600681015460405183915f80516020615f5c833981519152916117e391600160881b90046001600160401b031690615570565b6001546001600160a01b03163314612c7a573360405163118cdaa760e01b8152600401610b49919061554f565b6001600160a01b038116612ca3575f604051631e4fbdf760e01b8152600401610b49919061554f565b600280546001600160a01b0319166001600160a01b03838116918217909255600154604051919216907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700905f90a350565b600683015463ffffffff165f612d0b86868461400f565b905080602001515f03612d615760068501805460ff60801b1916905560405186905f80516020615efc83398151915290612d48905f90879061559b565b60405180910390a2612d5a8686612fc4565b5050612dd3565b5f612d708784845f01516140a8565b9050612d7e878683856141ac565b602082015160068701805460ff60801b1916600160801b60ff84160217905560405188915f80516020615efc83398151915291612dbd9190889061559b565b60405180910390a2612dcf8787612fc4565b5050505b50505050565b80546113c9908290600160481b90046001600160401b031661426f565b6008545f03612e025750565b600880545f909155600980546001600160401b031916905560405181815282907fffb0019827f9e43d212f207be3a20cd3a7fc776b3fcf5ec5ae1030d71489ca2b906020016117e3565b5f600482018190558154600360ff19909116178083556040515f199285925f80516020615edc83398151915292612e9b9291869182918291600160881b9091046001600160401b031690615b1a565b60405180910390a2825f80516020615f1c8339815191525f42604051611e2b929190615b46565b5f612ecb610d65565b60048401819055600b80545f90612ee3908490615a13565b909155505f9050612ef5600184615a26565b90505f60018411612f07575f19612f12565b612f12600285615a26565b90505f60028511612f24575f19612f2f565b612f2f600386615a26565b6006870154909150612f50908890600160201b900463ffffffff1687614341565b93505f612f62876004015487876144bd565b9050612f748885835f0151600161463d565b6001861115612f8e57612f8e88848360200151600261463d565b6002861115612fa857612fa888838360400151600361463d565b612fb588888686866147e3565b60800151979650505050505050565b5f828152601260205260409020546035811115612ff4576040516301eccb0960e51b815260040160405180910390fd5b60068201805463ffffffff60601b1916600160601b63ffffffff84811682029290921792839055909104161561302b57600461302e565b60035b8254839060ff1916600183600481111561304a5761304a615995565b02179055506006820154600160601b900463ffffffff165f0361308657825f80516020615f1c8339815191525f42604051611e2b929190615b46565b505050565b5f6001825460ff1660048111156130a4576130a4615995565b1415806130c257508154600160481b90046001600160401b03164210155b156130ce57505f919050565b6118d2824261426f565b6130e06154db565b6040516370a0823160e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319061312e90309060040161554f565b602060405180830381865afa158015613149573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061316d91906159e8565b90506131a46001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016843087613d84565b6040516370a0823160e01b815281906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906131f290309060040161554f565b602060405180830381865afa15801561320d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061323191906159e8565b61323b9190615a26565b6020830181905284146132615760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0383168252602082015161328190611b58612710613724565b6040830181905260208301516132979190615a26565b60608301526001600160401b03421660a083015260408201516132e8906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061dead9061482d565b6132f58260600151614853565b60808301525092915050565b6006820180545f858152600e6020908152604080832063ffffffff948516808552908352818420875181546001600160a01b0319166001600160a01b0390911617815592870151600180850191909155918701516002840155606087015160038401556080870151600484015560a0870151600590930180546001600160401b0319166001600160401b03909416939093179092558454919490939092916133ab91859116615b5d565b92506101000a81548163ffffffff021916908363ffffffff1602179055508160200151836005015f8282546133e09190615a13565b90915550505f848152600f6020908152604080832085516001600160a01b0316845290915290205460ff166134cf575f848152600f6020908152604080832085516001600160a01b0390811685529083528184208054600160ff199091168117909155888552601184528285208751831686528452828520869055888552601084529184208651815480850183559186529390942090930180546001600160a01b03191692909316919091179091556006840180546004906134b0908490600160201b900463ffffffff16615b5d565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b5f848152601460209081526040909120548351918401519091908390436134f7600182615a26565b6040805160208101979097526001600160a01b03909516948601949094526060850192909252608084015260a08301524060c082015260e00160408051601f1981840301815291815281516020928301205f878152601490935290822055835461357390601e90600160481b90046001600160401b0316615a13565b90505f6135836201518042615a13565b90508082116135925781613594565b805b85546001600160401b0391909116600160481b02600160481b600160881b031990911617909455509392505050565b5f828152600e602090815260408083208484528252808320805460018201546002830154600384015460048501548a8952600d8852978690205460058601548751948552978401929092528286015260608201969096526001600160401b03600160481b909604861660808201529490931660a0850152905190926001600160a01b0390921691849186917fd7e5f73e0349f5769e5f38f545de71e86c6861848c2d86ab1d9cb1a7cde9dc71919081900360c00190a4505050565b5f6118d261369183610bb8612710613724565b6137ca565b5f806008545f141580156136b457506009546001600160401b031615155b80156136d6575082546009546001600160401b03600160481b90920482169116105b90508080156136f057506009546001600160401b03164210155b801561370c57508254600160481b90046001600160401b031642105b1561371b575050600854919050565b50506002015490565b5f80805f19858709858702925082811083820303915050805f03613758575f841161374d575f80fd5b508290049050610e6b565b808411613763575f80fd5b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b5f8115806137de57506001600160801b0382115b156137fc57604051630802985160e31b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015613858573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061387c9190615b7a565b6001600160801b03165f036138a457604051630802985160e31b815260040160405180910390fd5b6040805160028082526060820183525f926020830190803683370190505090507f0000000000000000000000000000000000000000000000000000000000000000815f815181106138f7576138f7615b06565b602002602001019063ffffffff16908163ffffffff16815250505f8160018151811061392557613925615b06565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063883bdbfd90613988908590600401615ba0565b5f60405180830381865afa1580156139a2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526139c99190810190615cb0565b50905080516002146139ee57604051630802985160e31b815260040160405180910390fd5b5f815f81518110613a0157613a01615b06565b602002602001015182600181518110613a1c57613a1c615b06565b6020026020010151613a2e9190615d73565b90505f613a6163ffffffff7f00000000000000000000000000000000000000000000000000000000000000001683615da0565b90505f8260060b128015613aa65750613aa063ffffffff7f00000000000000000000000000000000000000000000000000000000000000001683615ddc565b60060b15155b15613ab95780613ab581615dfd565b9150505b5f613b0682887f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000614bad565b9050805f03613b2857604051630802985160e31b815260040160405180910390fd5b9695505050505050565b613b3d600654612df6565b60098054600160401b600160801b0319169055600a54613b7057604051631cef5d9f60e01b815260040160405180910390fd5b600160065f828254613b829190615a13565b90915550506006545f908152600d60205260408120600a805460088301559190915580546001600160481b031916610100426001600160401b03811691909102919091176001178255613bd890610e1090615a13565b81546001600160401b0391909116600160481b02600160481b600160881b031990911617815560075460028201556006543090613c16600143615a26565b40604051602001613c2993929190615ab1565b60408051601f1981840301815282825280516020918201206006545f9081526014909252918120919091556370a0823160e01b8252906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190613c9e90309060040161554f565b602060405180830381865afa158015613cb9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cdd91906159e8565b9050600b54811015613d02576040516315c45db960e11b815260040160405180910390fd5b600b54613d0f9082615a26565b600383019081555f600c55600654835460028501549254604080516001600160401b03610100850481168252600160481b90940490931660208401528201939093526060810192909252907fc14c2b5ab44ec2aa5041966f8c8bf198662e94644d79f2c4ab59192ade6b1292906080016117e3565b6040516001600160a01b038481166024830152838116604483015260648201839052612dd39186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614cb3565b5f83815260126020526040812060068401549091600160401b90910463ffffffff169081905b835483108015613e2057508481105b15613f68575f848481548110613e3857613e38615b06565b5f9182526020909120600590910201600481015490915060ff16613f5b5760048101805460ff191660019081179091558101545f89815260136020908152604080832085546001600160a01b0316845290915281208054909190613e9d908490615a26565b90915550506001810154600b80545f90613eb8908490615a26565b909155505080546001820154613efc916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169291169061482d565b80546001820154600283015460038401546040516001600160a01b03909416938c937f5a4029e557daab85dffae7b9a57e7dd2435bad25e3b21974f48e49ef41ac44c193613f5293919260ff9091169190615e1e565b60405180910390a35b5060019283019201613e11565b60068601805463ffffffff60401b1916600160401b63ffffffff86160217905560405187907f681dcb35b2648ff840074936817a68d3007e718357abe76ee47298b8d48ff06c90613fbe908590879086906155a9565b60405180910390a283548303612dcf57855460ff19166003178655600486015460405188915f80516020615f1c83398151915291613ffe91904290615b46565b60405180910390a250505050505050565b61403660405180608001604052805f81526020015f81526020015f81526020015f81525090565b6006830154614054908590600160201b900463ffffffff1684614341565b808252603211614065576032614068565b80515b6020820181905215610e6b5761408783600401546107d0612710613724565b60408201819052602082015161409c91615a9e565b60608201529392505050565b6060816001600160401b038111156140c2576140c2615af2565b6040519080825280602002602001820160405280156140eb578160200160208202803683370190505b505f8581526010602052604081205491925090815b81811015614182575f87815260106020526040812080548390811061412757614127615b06565b5f918252602090912001546001600160a01b03169050614148888883614d59565b15614153575061417a565b8185858151811061416657614166615b06565b602002602001018181525050836001019350505b600101614100565b508382146141a35760405163162908e360e11b815260040160405180910390fd5b50509392505050565b5f5b8160200151811015614268575f6141f284838789866040516020016141d5939291906155a9565b604051602081830303815290604052805190602001205f1c614e4a565b5f878152601060205260408120805492935090918390811061421657614216615b06565b5f9182526020808320909101548983526011825260408084206001600160a01b039092168085529190925291205490915061425e9088906142578787614eea565b600461463d565b50506001016141ae565b5050505050565b5f6008545f148061428957506009546001600160401b0316155b806142ab575082546009546001600160401b03600160481b9092048216911610155b806142c457506009546001600160401b03908116908316105b156142d057505f6118d2565b600283018054600880549283905560078390555f9055600980546001600160401b03191690556006546040519192917ff0e4457ebc34a27eef8780e2d8d25fe749578b5b593e232c1650477730955f469061432e908590859061559b565b60405180910390a2506001949350505050565b5f838152600e6020526040812081908161435c600186615a26565b815260208101919091526040015f908120546001600160a01b0316915060018411614387575f6143ba565b5f868152600e60205260408120906143a0600287615a26565b815260208101919091526040015f20546001600160a01b03165b90505f600285116143cb575f6143fe565b5f878152600e60205260408120906143e4600388615a26565b815260208101919091526040015f20546001600160a01b03165b905060016001600160a01b0383161580159061442c5750836001600160a01b0316836001600160a01b031614155b1561443f5761443c600182615a13565b90505b6001600160a01b038216158015906144695750836001600160a01b0316826001600160a01b031614155b80156144875750826001600160a01b0316826001600160a01b031614155b1561449a57614497600182615a13565b90505b8087116144a7575f6144b1565b6144b18188615a26565b98975050505050505050565b6144ea6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6144f984611388612710613724565b815260018311614509575f614518565b614518846107d0612710613724565b60208201526002831161452b575f61453a565b61453a846103e8612710613724565b60408201526080810182905281614551575f614560565b614560846107d0612710613724565b606082015260028310156145905761457d846107d0612710613724565b8151829061458c908390615a13565b9052505b60038310156145bb576145a8846103e8612710613724565b815182906145b7908390615a13565b9052505b815f036145e4576145d1846107d0612710613724565b815182906145e0908390615a13565b9052505b5f816060015182604001518360200151845f01516146029190615a13565b61460c9190615a13565b6146169190615a13565b90506146228186615a26565b82518390614631908390615a13565b90525090949350505050565b81158061464a57505f1983145b612dd3575f848152600e602090815260408083208684529091529020546001600160a01b03168061467b5750612dd3565b5f8581526013602090815260408083206001600160a01b0385168452909152812080548592906146ac908490615a13565b90915550505f85815260126020908152604091829020825160a0810184526001600160a01b03851681529182018690529181018460048111156146f1576146f1615995565b815260208082018890525f604092830181905284546001808201875595825290829020845160059092020180546001600160a01b0319166001600160a01b03909216919091178155908301518185015590820151600282018054939492939192909160ff19169083600481111561476a5761476a615995565b0217905550606082015160038201556080909101516004909101805460ff19169115159190911790556040516001600160a01b0382169086907fd4b7789121552d8b23457dfda484be88230a8daf1f91c11b1f9147007ef9019f906147d490879087908a90615e1e565b60405180910390a35050505050565b6004840154845460405187925f80516020615edc8339815191529261481e92889188918891600160881b90046001600160401b031690615b1a565b60405180910390a25050505050565b61308683846001600160a01b031663a9059cbb8585604051602401613db9929190615e52565b5f8061485e83614f40565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016148ad919061554f565b602060405180830381865afa1580156148c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906148ec91906159e8565b6040805160e0810182526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081168083527f0000000000000000000000000000000000000000000000000000000000000000909116602083015262ffffff7f000000000000000000000000000000000000000000000000000000000000000016928201929092523060608201526080810187905260a081018590525f60c08201529192506149c2907f000000000000000000000000000000000000000000000000000000000000000087614fa4565b604080516304e45aaf60e01b815282516001600160a01b0390811660048301526020840151811660248301529183015162ffffff1660448201526060830151821660648201526080830151608482015260a083015160a482015260c0830151821660c48201527f0000000000000000000000000000000000000000000000000000000000000000909116906304e45aaf9060e4016020604051808303815f875af1158015614a72573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614a9691906159e8565b50614aeb6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000005f614fa4565b6040516370a0823160e01b815282906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190614b3990309060040161554f565b602060405180830381865afa158015614b54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614b7891906159e8565b614b829190615a26565b935082841015614ba5576040516303ddb00360e31b815260040160405180910390fd5b505050919050565b5f80614bb886615034565b90506001600160801b036001600160a01b03821611614c3d575f614be56001600160a01b03831680615a87565b9050836001600160a01b0316856001600160a01b031610614c1d57614c18600160c01b876001600160801b031683613724565b614c35565b614c3581876001600160801b0316600160c01b613724565b925050614caa565b5f614c566001600160a01b03831680600160401b613724565b9050836001600160a01b0316856001600160a01b031610614c8e57614c89600160801b876001600160801b031683613724565b614ca6565b614ca681876001600160801b0316600160801b613724565b9250505b50949350505050565b5f80836001600160a01b031683604051614ccd9190615e6b565b5f604051808303815f865af19150503d805f8114614d06576040519150601f19603f3d011682016040523d82523d5f602084013e614d0b565b606091505b5091509150811580614d395750805115801590614d39575080806020019051810190614d379190615e86565b155b15612dd35783604051635274afe760e01b8152600401610b49919061554f565b5f838152600e602052604081206001600160a01b0383169082614d7d600187615a26565b815260208101919091526040015f20546001600160a01b031603614da357506001610e6b565b600183118015614dec57505f848152600e602052604081206001600160a01b03841691614dd1600287615a26565b815260208101919091526040015f20546001600160a01b0316145b15614df957506001610e6b565b600283118015614e4257505f848152600e602052604081206001600160a01b03841691614e27600387615a26565b815260208101919091526040015f20546001600160a01b0316145b949350505050565b5f80838551614e599190615a26565b614e639084615a4d565b614e6d9085615a13565b9050848181518110614e8157614e81615b06565b60200260200101519150848481518110614e9d57614e9d615b06565b6020026020010151858281518110614eb757614eb7615b06565b60200260200101818152505081858581518110614ed657614ed6615b06565b602002602001018181525050509392505050565b60208201515f90614efc836001615a13565b03614f375760018360200151614f129190615a26565b8360600151614f219190615a87565b8360400151614f309190615a26565b90506118d2565b50506060015190565b5f80614f4b836137ca565b90505f614f828261161c61ffff7f000000000000000000000000000000000000000000000000000000000000000016612710615a26565b9050805f03610e6b57604051630802985160e31b815260040160405180910390fd5b5f836001600160a01b031663095ea7b38484604051602401614fc7929190615e52565b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050509050615000848261543a565b612dd35761502a84856001600160a01b031663095ea7b3865f604051602401613db9929190615e52565b612dd38482614cb3565b5f805f8360020b12615049578260020b615056565b8260020b61505690615ea1565b9050615065620d89e719615ebb565b60020b81111561509b5760405162461bcd60e51b81526020600482015260016024820152601560fa1b6044820152606401610b49565b5f816001165f036150b057600160801b6150c2565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b0316905060028216156150f75760806150f2826ffff97272373d413259a46990580e213a615a87565b901c90505b600482161561512157608061511c826ffff2e50f5f656932ef12357cf3c7fdcc615a87565b901c90505b600882161561514b576080615146826fffe5caca7e10e4e61c3624eaa0941cd0615a87565b901c90505b6010821615615175576080615170826fffcb9843d60f6159c9db58835c926644615a87565b901c90505b602082161561519f57608061519a826fff973b41fa98c081472e6896dfb254c0615a87565b901c90505b60408216156151c95760806151c4826fff2ea16466c96a3843ec78b326b52861615a87565b901c90505b60808216156151f35760806151ee826ffe5dee046a99a2a811c461f1969c3053615a87565b901c90505b61010082161561521e576080615219826ffcbe86c7900a88aedcffc83b479aa3a4615a87565b901c90505b610200821615615249576080615244826ff987a7253ac413176f2b074cf7815e54615a87565b901c90505b61040082161561527457608061526f826ff3392b0822b70005940c7a398e4b70f3615a87565b901c90505b61080082161561529f57608061529a826fe7159475a2c29b7443b29c7fa6e889d9615a87565b901c90505b6110008216156152ca5760806152c5826fd097f3bdfd2022b8845ad8f792aa5825615a87565b901c90505b6120008216156152f55760806152f0826fa9f746462d870fdf8a65dc1f90e061e5615a87565b901c90505b61400082161561532057608061531b826f70d869a156d2a1b890bb3df62baf32f7615a87565b901c90505b61800082161561534b576080615346826f31be135f97d08fd981231505542fcfa6615a87565b901c90505b62010000821615615377576080615372826f09aa508b5b7a84e1c677de54f3e99bc9615a87565b901c90505b620200008216156153a257608061539d826e5d6af8dedb81196699c329225ee604615a87565b901c90505b620400008216156153cc5760806153c7826d2216e584f5fa1ea926041bedfe98615a87565b901c90505b620800008216156153f45760806153ef826b048a170391f7dc42444e8fa2615a87565b901c90505b5f8460020b131561540d5761540a815f19615a9e565b90505b61541b600160201b82615a4d565b15615427576001615429565b5f5b614e429060ff16602083901c615a13565b5f805f846001600160a01b0316846040516154559190615e6b565b5f604051808303815f865af19150503d805f811461548e576040519150601f19603f3d011682016040523d82523d5f602084013e615493565b606091505b50915091508180156154bd5750805115806154bd5750808060200190518101906154bd9190615e86565b80156154d257505f856001600160a01b03163b115b95945050505050565b6040518060c001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f6001600160401b031681525090565b6001600160a01b0381168114615531575f80fd5b50565b5f60208284031215615544575f80fd5b8135610e6b8161551d565b6001600160a01b0391909116815260200190565b6001600160401b03169052565b6001600160401b0391909116815260200190565b5f60208284031215615594575f80fd5b5035919050565b918252602082015260400190565b9283526020830191909152604082015260600190565b8015158114615531575f80fd5b5f602082840312156155dc575f80fd5b8135610e6b816155bf565b5f80604083850312156155f8575f80fd5b82359150602083013560ff8116811461560f575f80fd5b809150509250929050565b5f806040838503121561562b575f80fd5b50508035926020909101359150565b5f5b8381101561565457818101518382015260200161563c565b50505f910152565b602081525f825180602084015261567a81604085016020870161563a565b601f01601f19169190910160400192915050565b5f806040838503121561569f575f80fd5b82359150602083013561560f8161551d565b815181526020808301516101808301916156cf9084018260ff169052565b5060408301516156e26040840182615563565b5060608301516156f56060840182615563565b5060808301516157086080840182615563565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015161573f8285018263ffffffff169052565b50506101208381015163ffffffff81168483015250506101408381015163ffffffff81168483015250506101608381015163ffffffff8116848301525b505092915050565b815160ff1681526101c0810160208301516157a26020840182615563565b5060408301516157b56040840182615563565b5060608301516157c86060840182615563565b5060808301516157db6080840182615563565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161581e8285018263ffffffff169052565b50506101408381015163ffffffff908116918401919091526101608085015160ff1690840152610180808501518216908401526101a080850151918216818501529061577c565b5f815180845260208085019450602084015f5b8381101561589457815187529582019590820190600101615878565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561589457815160ff16875295820195908201906001016158b2565b5f815180845260208085019450602084015f5b838110156158945781511515875295820195908201906001016158e4565b60a080825286519082018190525f9060209060c0840190828a01845b828110156159435781516001600160a01b03168452928401929084019060010161591e565b50505083810360208501526159588189615865565b915050828103604084015261596d818761589f565b905082810360608401526159818186615865565b905082810360808401526144b181856158d1565b634e487b7160e01b5f52602160045260245ffd5b968752602087019590955260408601939093526060850191909152608084015263ffffffff1660a08301526001600160a01b031660c082015260e00190565b5f602082840312156159f8575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156118d2576118d26159ff565b818103818111156118d2576118d26159ff565b634e487b7160e01b5f52601260045260245ffd5b5f82615a5b57615a5b615a39565b500690565b6001600160401b03818116838216019080821115615a8057615a806159ff565b5092915050565b80820281158282048414176118d2576118d26159ff565b5f82615aac57615aac615a39565b500490565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160401b03828116828216039080821115615a8057615a806159ff565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b9485526020850193909352604084019190915260608301526001600160401b0316608082015260a00190565b9182526001600160401b0316602082015260400190565b63ffffffff818116838216019080821115615a8057615a806159ff565b5f60208284031215615b8a575f80fd5b81516001600160801b0381168114610e6b575f80fd5b602080825282518282018190525f9190848201906040850190845b81811015615bdd57835163ffffffff1683529284019291840191600101615bbb565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715615c1157615c11615af2565b604052919050565b5f6001600160401b03821115615c3157615c31615af2565b5060051b60200190565b5f82601f830112615c4a575f80fd5b81516020615c5f615c5a83615c19565b615be9565b8083825260208201915060208460051b870101935086841115615c80575f80fd5b602086015b84811015615ca5578051615c988161551d565b8352918301918301615c85565b509695505050505050565b5f8060408385031215615cc1575f80fd5b82516001600160401b0380821115615cd7575f80fd5b818501915085601f830112615cea575f80fd5b81516020615cfa615c5a83615c19565b82815260059290921b84018101918181019089841115615d18575f80fd5b948201945b83861015615d445785518060060b8114615d35575f80fd5b82529482019490820190615d1d565b91880151919650909350505080821115615d5c575f80fd5b50615d6985828601615c3b565b9150509250929050565b600682810b9082900b03667fffffffffffff198112667fffffffffffff821317156118d2576118d26159ff565b5f8160060b8360060b80615db657615db6615a39565b667fffffffffffff1982145f1982141615615dd357615dd36159ff565b90059392505050565b5f8260060b80615dee57615dee615a39565b808360060b0791505092915050565b5f8160020b627fffff198103615e1557615e156159ff565b5f190192915050565b8381526060810160058410615e4157634e487b7160e01b5f52602160045260245ffd5b602082019390935260400152919050565b6001600160a01b03929092168252602082015260400190565b5f8251615e7c81846020870161563a565b9190910192915050565b5f60208284031215615e96575f80fd5b8151610e6b816155bf565b5f600160ff1b8201615eb557615eb56159ff565b505f0390565b5f8160020b627fffff198103615ed357615ed36159ff565b5f039291505056fe7042bd10dbe05c21f65180e15a3f81868fb6f326675466a2aaa232ff66b25e21d7a3011d24ef5a0e45b052d9edae4bdcf3d2cef189e92a32db3dfa755a9b618bc2013973c1b57bc4c3d7784ede2ac4ce6d3f374b3317f26bc2650f9b9cd00f363cea0c8e4eb828c0293c1cd7cf72d8c4eb394823c539581eb2e6b25a6c5feda10cdbb89fc7974f07e4662fa4b0d250d0fa12c9c39f50ba940ef49f8a157a5676a2646970667358221220b5e88f6870b1b6edf3e4a09b9f93c4619f3c932f7e752b85ecc6c69311db518464736f6c634300081800330000000000000000000000007e71ac662b038e101be4336d68aa917950d07875000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd810000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73000000000000000000000000caf681a66d020601342297493863e78c959e5cb20000000000000000000000005d32c699f4755c5b317489f32dec68e1f63246ed0000000000000000000000007e71ac662b038e101be4336d68aa917950d078750000000000000000000000000000000000000000000173c43e13592f4a480000000000000000000000000000000000000000000000000000000000000000012c0000000000000000000000000000000000000000000000000000000000000320
0x608060405234801561000f575f80fd5b50600436106103af575f3560e01c8063030f386c146103b357806303fd2a45146103c85780630597725e146103e75780630837f88e146103fe578063089fe6aa146104065780630a37e4fb146104415780630b5ffd131461045d5780630d43e8ad14610473578063132a518c1461048657806316f0115b1461048e5780631bfb7699146104b55780631c40c7d8146104c85780631cfe7edf146104db5780631e820325146104f55780631eddd2eb146104fd578063249d39e9146105105780632718d34e146105195780632aac1a5a1461052257806335223a5a146105355780633b97e8561461054b5780633c3ccc44146105725780633fc8cef31461057a57806346e0c91e146105a157806346f13619146105aa5780634c92fb12146105b25780634cacbdf1146105c55780634f022c4d146105ce57806357f9ebf3146105e55780635882f4da146105ed5780635950458c1461060c5780635e123ce4146106165780635edadf141461063a5780636372fbc11461064357806363c2ed151461065657806365728bc61461066957806369b947e014610672578063715018a6146106b55780637705a363146106bd578063788c1338146106c557806378b5a297146106df57806378dd1de4146106f25780637916e4fa146106fa5780637988e7231461070d57806379ba5097146107155780637ad5367c1461071d5780637bc75e82146107255780638107e1331461072e578063885620bb1461076a5780638da5cb5b146107ed5780638f716d74146107f55780639345ba0214610808578063964c065b1461060c57806398ba676d1461081b5780639cbe5efd146108875780639dcfa49314610890578063a0a8e460146108a3578063a0c7f71c146108cb578063a2724a4d146108f5578063a32bf597146108fe578063a37a9fc014610913578063a4b7c5451461091c578063b4a7698e1461092f578063b7c3565d14610937578063b88a92b41461095e578063c31c9c0714610968578063c515cf151461098f578063c5f5293c14610998578063c868e02e146109ac578063cca5e0d9146109cc578063ccfc2e8d146109d5578063d5ffb242146109e8578063d7ea41a614610a10578063e2232eba14610a23578063e30c397814610a5a578063e53e3f4f14610a6b578063e5da886d14610a73578063e7b542f614610a86578063e93c980d14610a8f578063ea6a632614610ab6578063effaa1cb14610ada578063f2fde38b14610ae2578063fc0c546a14610af5578063ff874c051461098f575b5f80fd5b6103c66103c1366004615534565b610b1c565b005b6103d161dead81565b6040516103de919061554f565b60405180910390f35b6103f0600c5481565b6040519081526020016103de565b6103c6610be1565b61042d7f000000000000000000000000000000000000000000000000000000000000271081565b60405162ffffff90911681526020016103de565b61044a6107d081565b60405161ffff90911681526020016103de565b610466610e1081565b6040516103de9190615570565b6003546103d1906001600160a01b031681565b6103f0610d65565b6103d17f0000000000000000000000005d32c699f4755c5b317489f32dec68e1f63246ed81565b6103f06104c3366004615584565b610e39565b6005546103d1906001600160a01b031681565b6104e3603581565b60405160ff90911681526020016103de565b6103c6610e72565b6103c661050b366004615584565b61109f565b6103f061271081565b6103f061138881565b6103c6610530366004615584565b6111d8565b61053d611593565b6040516103de92919061559b565b6104e37f000000000000000000000000000000000000000000000000000000000000001281565b6103c661162c565b6103d17f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7381565b6103f06103e881565b610466601e81565b6103c66105c0366004615584565b6116fa565b6103f060085481565b6105d66117ef565b6040516103de939291906155a9565b6104e3600a81565b6103f06105fb366004615584565b60146020525f908152604090205481565b6104666201518081565b60055461062a90600160a01b900460ff1681565b60405190151581526020016103de565b61046661012c81565b6004546103d1906001600160a01b031681565b6103f0610664366004615584565b6118c8565b6103f0600a5481565b61067a6118d8565b604080519687526001600160401b039095166020870152938501929092521515606084015215156080830152151560a082015260c0016103de565b6103c661196c565b61062a6119b4565b60095461046690600160401b90046001600160401b031681565b6103c66106ed3660046155cc565b611a2d565b610466600881565b6103c6610708366004615584565b611ab2565b61044a604081565b6103c6611c5c565b6103c6611ce3565b6103f060075481565b6107557f000000000000000000000000000000000000000000000000000000000000012c81565b60405163ffffffff90911681526020016103de565b6107bb610778366004615584565b5f908152600d602052604090206008810154600682015460079092015490926001600160401b03600160881b90930483169282169160ff600160401b9091041690565b6040516103de94939291909384526001600160401b039283166020850152911660408301521515606082015260800190565b6103d1611e38565b6103c6610803366004615584565b611e47565b6103c66108163660046155e7565b611fe6565b61082e61082936600461561a565b612096565b6040516103de919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201516001600160401b03169181019190915260c00190565b6103f060065481565b6103c661089e366004615534565b61210f565b6040805180820182526006815265032372e342e360d41b602082015290516103de919061565c565b6103f06108d936600461568e565b601360209081525f928352604080842090915290825290205481565b61046661025881565b6109066121cb565b6040516103de91906156b1565b6103f0611b5881565b6103c661092a366004615584565b6122f0565b610466603c81565b61044a7f000000000000000000000000000000000000000000000000000000000000032081565b6107556201518081565b6103d17f000000000000000000000000caf681a66d020601342297493863e78c959e5cb281565b6103f06107d081565b60055461062a90600160a81b900460ff1681565b6109bf6109ba366004615584565b6123f8565b6040516103de9190615784565b6103f0600b5481565b6103c66109e3366004615534565b61254d565b6109f0612609565b6040805194855260208501939093529183015260608201526080016103de565b6103c6610a1e366004615584565b6126e6565b610a2b61279e565b6040805194855260208501939093526001600160401b03918216928401929092521660608201526080016103de565b6002546001600160a01b03166103d1565b6104e3603281565b600954610466906001600160401b031681565b6103f0610bb881565b6103f07f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b610ac9610ac4366004615584565b612876565b6040516103de959493929190615902565b6103c6612b1b565b6103c6610af0366004615534565b612c4d565b6103d17f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd8181565b6001546001600160a01b03163314610b52573360405163118cdaa760e01b8152600401610b49919061554f565b60405180910390fd5b6001600160a01b0381161580610b7257506001600160a01b03811661dead145b15610b905760405163e6c4247b60e01b815260040160405180910390fd5b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fd012192ad897398417bfd9744d72f34e12dc2a6383f050db122ce11e98905c5d905f90a35050565b60025f5403610c0357604051633ee5aeb560e01b815260040160405180910390fd5b60025f818155600654808252600d60205260409091209091815460ff166004811115610c3157610c31615995565b141580610c4a57506007810154600160401b900460ff16155b15610c675760405162facebb60e61b815260040160405180910390fd5b6006810154600160881b90046001600160401b0316438110610c9c57604051637b91e42d60e11b815260040160405180910390fd5b804080610cbc57604051634604c5f960e11b815260040160405180910390fd5b60088301545f858152601460209081526040808320546004880154600689015492519495610cfc95909488948c939263ffffffff909116913091016159a9565b604051602081830303815290604052805190602001209050847f718da713b81f655e0d5d9981d8269c2fcd2eb87ee792688e246ce209f9f1bc2d82604051610d4691815260200190565b60405180910390a2610d5a85858380612cf4565b505060015f55505050565b5f807f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610db3919061554f565b602060405180830381865afa158015610dce573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df291906159e8565b90505f600c54600b54610e059190615a13565b905080821015610e28576040516315c45db960e11b815260040160405180910390fd5b610e328183615a26565b9250505090565b5f818152600d602052604081206006810154610e6b9063ffffffff600160401b8204811691600160601b900416615a26565b9392505050565b60025f5403610e9457604051633ee5aeb560e01b815260040160405180910390fd5b60025f55600554600160a01b900460ff16610ec257604051633a5f7b5760e01b815260040160405180910390fd5b6006545f818152600d602052604090206001815460ff166004811115610eea57610eea615995565b14610f075760405162facebb60e61b815260040160405180910390fd5b8054600160481b90046001600160401b0316421015610f3957604051630a1e85db60e11b815260040160405180910390fd5b610f4281612dd9565b610f4b82612df6565b80546001600160401b0342908116600160881b02600160881b600160c81b0319909216919091178255610f819061025890615a13565b6001820180546001600160401b0319166001600160401b0392909216919091179055600681015463ffffffff165f819003610fc857610fc08383612e4c565b505050611099565b5f610fd4848484612ec2565b9050805f03610ff057610fe78484612fc4565b50505050611099565b825460ff19166002178355611006600843615a13565b6006840180546001600160401b0392909216600160881b02600160881b600160c81b03199092169190911790556110406201518042615a13565b6007840180546001600160481b0319166001600160401b03928316179055600684015460405186925f80516020615f5c8339815191529261108c92600160881b90910490911690615570565b60405180910390a2505050505b60015f55565b60025f54036110c157604051633ee5aeb560e01b815260040160405180910390fd5b60025f55600554600160a01b900460ff166110ef57604051633a5f7b5760e01b815260040160405180910390fd5b600554600160a81b900460ff161561111a57604051635bc4057960e01b815260040160405180910390fd5b6006545f818152600d602052604090206001815460ff16600481111561114257611142615995565b14158061116057508054600160481b90046001600160401b03164210155b1561117e57604051633df07da560e01b815260040160405180910390fd5b6111878161308b565b50806002015483146111b357600281015460405163bd73822360e01b8152610b4991859160040161559b565b5f6111be84336130d8565b90505f6111cc848484613301565b9050610d5a84826135c3565b6004546001600160a01b0316331480159061120c57506111f6611e38565b6001600160a01b0316336001600160a01b031614155b1561122a57604051631b8d200760e01b815260040160405180910390fd5b600554600160a01b900460ff1661125457604051633a5f7b5760e01b815260040160405180910390fd5b8015806112df57507f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112dc91906159e8565b81115b156112fd5760405163162908e360e11b815260040160405180910390fd5b6113277f0000000000000000000000000000000000000000000000000de0b6b3a764000082615a4d565b156113455760405163160e7f3760e21b815260040160405180910390fd5b6006545f908152600d602052604090206001815460ff16600481111561136d5761136d615995565b14158061138b57508054600160481b90046001600160401b03164210155b156113a957604051633df07da560e01b815260040160405180910390fd5b6113b28161308b565b50806002015482036113cd576113c9600654612df6565b5050565b81600854036113da575050565b60095442905f906113fe9061012c90600160401b90046001600160401b0316615a60565b600954909150600160401b90046001600160401b0316158015906114335750806001600160401b0316826001600160401b0316105b156114535780604051637259add760e11b8152600401610b499190615570565b5f61145f603c84615a60565b84549091506001600160401b03600160481b9091048116908216106114975760405163136b300d60e01b815260040160405180910390fd5b600280850154905f906114ab908390615a87565b90505f60026114bb846001615a13565b6114c59190615a9e565b9050818811806114d457508088105b156114f657828860405163e57fe7f760e01b8152600401610b4992919061559b565b6114ff8861367e565b506008889055600980546001600160401b03888116600160401b026001600160801b03199092169087161717905560065460028801546040517fb43357481cfbfea92bea0d2bb4b3b4ea5c45b399fa096c3f6758baea27656af491611581918c90899092835260208301919091526001600160401b0316604082015260600190565b60405180910390a25050505050505050565b6005545f908190600160a01b900460ff166115b057505f91829150565b6006545f908152600d602052604081206115c990613696565b90505f6115db82610bb8612710613724565b90506115e6816137ca565b93506116248461161c61ffff7f000000000000000000000000000000000000000000000000000000000000032016612710615a26565b612710613724565b925050509091565b60025f540361164e57604051633ee5aeb560e01b815260040160405180910390fd5b60025f9081556006548152600d602052604090206003815460ff16600481111561167a5761167a615995565b141580611693575060018101546001600160401b031642105b156116b05760405162facebb60e61b815260040160405180910390fd5b6006810154600160401b810463ffffffff908116600160601b90920416146116eb576040516370136f7360e01b815260040160405180910390fd5b6116f3613b32565b5060015f55565b6001546001600160a01b03163314611727573360405163118cdaa760e01b8152600401610b49919061554f565b600554600160a01b900460ff16156117525760405163ba26162b60e01b815260040160405180910390fd5b61175b816126e6565b61176660075461367e565b506005805460ff60a01b1916600160a01b179055611782613b32565b6006545f818152600d6020908152604091829020805483516001600160401b03610100830481168252600160481b9092049091169281019290925292917fdf90cf1ad255c56e947d160fdc96fe384c300c7d8d08c302aa418686a162d0c191015b60405180910390a25050565b5f805f7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161183e919061554f565b602060405180830381865afa158015611859573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187d91906159e8565b9250600b5491505f600c54836118939190615a13565b9050808410156118b6576040516315c45db960e11b815260040160405180910390fd5b6118c08185615a26565b915050909192565b5f6118d2826137ca565b92915050565b600680545f818152600d60205260408120909201549091600160881b9091046001600160401b03169043908080841580159061191c5750846001600160401b031684115b925082801561193e575061193b6001600160401b038616610100615a13565b84115b9150600d5f8781526020019081526020015f2060070160089054906101000a900460ff169050909192939495565b6001546001600160a01b03163314611999573360405163118cdaa760e01b8152600401610b49919061554f565b5f604051631e4fbdf760e01b8152600401610b49919061554f565b6005545f90600160a01b900460ff166119cc57505f90565b6006545f908152600d602052604090206001815460ff1660048111156119f4576119f4615995565b141580611a1257508054600160481b90046001600160401b03164210155b15611a1e575f91505090565b611a278161308b565b91505090565b6001546001600160a01b03163314611a5a573360405163118cdaa760e01b8152600401610b49919061554f565b60058054821515600160a81b0260ff60a81b199091161790556040517f1cb73f7e76b5e9b5d7e8ec0883e2dc6c655c40d684bca1832dce24cb6502527e90611aa790831515815260200190565b60405180910390a150565b60025f5403611ad457604051633ee5aeb560e01b815260040160405180910390fd5b60025f818155600654808252600d60205260409091209091815460ff166004811115611b0257611b02615995565b14611b1f5760405162facebb60e61b815260040160405180910390fd5b6007810154600160401b900460ff1615611b4c57604051637b91e42d60e11b815260040160405180910390fd5b8060080154308385604051602001611b6693929190615ab1565b6040516020818303038152906040528051906020012014611b9a57604051636ab5da2b60e01b815260040160405180910390fd5b6006810154600160881b90046001600160401b0316438110611bcf57604051637b91e42d60e11b815260040160405180910390fd5b804080611bef57604051634604c5f960e11b815260040160405180910390fd5b5f84815260146020908152604080832054600487015460068801549251611c2a948b948894938c93909263ffffffff909216913091016159a9565b604051602081830303815290604052805190602001209050611c508585835f1c84612cf4565b505060015f5550505050565b6002546001600160a01b03163314611c89573360405163118cdaa760e01b8152600401610b49919061554f565b600180546001600160a01b0319808216339081179093556002805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a350565b6006545f818152600d602052604090206002815460ff166004811115611d0b57611d0b615995565b14611d285760405162facebb60e61b815260040160405180910390fd5b6006810154611d4990600160881b90046001600160401b0316610100615a13565b4311611d6857604051637b91e42d60e11b815260040160405180910390fd5b600781018054600160401b60ff60401b19821681179092550460ff16611d8f600843615a13565b8260060160116101000a8154816001600160401b0302191690836001600160401b0316021790555080611df857600682015460405184915f80516020615f3c83398151915291611def91600160881b90046001600160401b031690615570565b60405180910390a25b600682015460405184915f80516020615f5c83398151915291611e2b91600160881b90046001600160401b031690615570565b60405180910390a2505050565b6001546001600160a01b031690565b60025f5403611e6957604051633ee5aeb560e01b815260040160405180910390fd5b60025f556003546001600160a01b03163314611e9857604051637a11843360e01b815260040160405180910390fd5b805f03611eb85760405163162908e360e11b815260040160405180910390fd5b611eed6001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7316333084613d84565b6005546001905f90600160a01b900460ff16611f0a576001611f18565b600654611f18906001615a13565b600554909150600160a01b900460ff1615611f82576006545f908152600d602052604090206001815460ff166004811115611f5557611f55615995565b148015611f7257508054600160481b90046001600160401b031642105b15611f80575f925060065491505b505b8115611f9f5782600c5f828254611f999190615a13565b90915550505b604080518481528315156020820152339183917f64c0123778195ae68f9df99ac43bde277e108253249a83e9b57fc99bd3eae952910160405180910390a3505060015f5550565b60025f540361200857604051633ee5aeb560e01b815260040160405180910390fd5b60025f5560ff8116158061201f5750600a60ff8216115b1561203d57604051637862e95960e01b815260040160405180910390fd5b5f828152600d602052604090206004815460ff16600481111561206257612062615995565b1461207f5760405162facebb60e61b815260040160405180910390fd5b61208d83828460ff16613deb565b505060015f5550565b61209e6154db565b505f918252600e6020908152604080842092845291815291819020815160c08101835281546001600160a01b031681526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600501546001600160401b031660a082015290565b6001546001600160a01b0316331461213c573360405163118cdaa760e01b8152600401610b49919061554f565b6001600160a01b038116158061215c57506001600160a01b03811661dead145b1561217a5760405163e6c4247b60e01b815260040160405180910390fd5b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fdd8bcf61c48bec82fb1e075ae14a3e3785fefd64468c20112aa0e48bdbf4f89b905f90a35050565b60408051610180810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101919091526006545f818152600d60205260409020908252805460ff16600481111561225457612254615995565b60ff16602083015280546001600160401b03610100820481166040850152600160481b90910481166060840152600182015416608083015261229581613696565b60a0830152600381015460c0830152600581015460e08301526006015463ffffffff808216610100840152600160201b82048116610120840152600160401b82048116610140840152600160601b9091041661016082015290565b60025f540361231257604051633ee5aeb560e01b815260040160405180910390fd5b60025f908155818152600d602052604090206004815460ff16600481111561233c5761233c615995565b146123595760405162facebb60e61b815260040160405180910390fd5b5f828152601260205260409020546035811115612389576040516301eccb0960e51b815260040160405180910390fd5b60068201545f906123a790600160401b900463ffffffff1683615a26565b90506123b4848483613deb565b837f707eea9fa1d1d69eac18fe206c3b311a4e489f2abb27e9dd38fde4986b9ea05a826040516123e691815260200190565b60405180910390a2505060015f555050565b604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091525f828152600d60205260409020805460ff16600481111561248b5761248b615995565b60ff908116835281546001600160401b0361010080830482166020870152600160481b830482166040870152600160881b909204811660608601526001840154166080850152600283015460a0850152600383015460c0850152600483015460e085015260058301549084015260069091015463ffffffff808216610120850152600160201b82048116610140850152600160801b8204909216610160840152600160401b81048216610180840152600160601b9004166101a0820152919050565b6001546001600160a01b0316331461257a573360405163118cdaa760e01b8152600401610b49919061554f565b6001600160a01b038116158061259a57506001600160a01b03811661dead145b156125b85760405163e6c4247b60e01b815260040160405180910390fd5b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fbb470d12faa974cbae56bc3c345446451b4d504aa13806836f3df6d032fa9a91905f90a35050565b5f805f807f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612659919061554f565b602060405180830381865afa158015612674573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061269891906159e8565b600b54600c54919550935090505f6126b08285615a13565b9050808510156126d3576040516315c45db960e11b815260040160405180910390fd5b6126dd8186615a26565b92505090919293565b6005546001600160a01b0316331480159061271a5750612704611e38565b6001600160a01b0316336001600160a01b031614155b1561273857604051631cf076c760e11b815260040160405180910390fd5b8061275657604051631cef5d9f60e01b815260040160405180910390fd5b5f60065460016127669190615a13565b600a839055604051909150829082907f16779bc4ee4f6bcd092281f5e36e02d1a9360a94c4eeb04d57c6fbfcd1e5fa65905f90a35050565b6006545f908152600d602052604081206002810154600854600954919390926001600160401b03909216918184158015906127e157506001600160401b03841615155b8015612801575081546001600160401b03600160481b9091048116908516105b90508061281957505f93508392508291506128709050565b836001600160401b0316421015801561284257508154600160481b90046001600160401b031642105b1561284f5784955061286d565b836001600160401b031642101561286d5761286a4285615ad2565b92505b50505b90919293565b5f8181526012602052604090208054606091829182918291829190806001600160401b038111156128a9576128a9615af2565b6040519080825280602002602001820160405280156128d2578160200160208202803683370190505b509650806001600160401b038111156128ed576128ed615af2565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b509550806001600160401b0381111561293157612931615af2565b60405190808252806020026020018201604052801561295a578160200160208202803683370190505b509450806001600160401b0381111561297557612975615af2565b60405190808252806020026020018201604052801561299e578160200160208202803683370190505b509350806001600160401b038111156129b9576129b9615af2565b6040519080825280602002602001820160405280156129e2578160200160208202803683370190505b5092505f5b81811015612b0f575f838281548110612a0257612a02615b06565b5f918252602090912060059091020180548a519192506001600160a01b0316908a9084908110612a3457612a34615b06565b60200260200101906001600160a01b031690816001600160a01b0316815250508060010154888381518110612a6b57612a6b615b06565b6020908102919091010152600281015460ff166004811115612a8f57612a8f615995565b878381518110612aa157612aa1615b06565b602002602001019060ff16908160ff16815250508060030154868381518110612acc57612acc615b06565b60209081029190910101526004810154855160ff90911690869084908110612af657612af6615b06565b91151560209283029190910190910152506001016129e7565b50505091939590929450565b6006545f818152600d602052604090206002815460ff166004811115612b4357612b43615995565b14612b605760405162facebb60e61b815260040160405180910390fd5b6007810154600160401b900460ff1680612b86575060078101546001600160401b031642105b15612ba457604051637b91e42d60e11b815260040160405180910390fd5b60078101805460ff60401b1916600160401b179055612bc4600843615a13565b600682018054600160881b600160c81b031916600160881b6001600160401b039384168102919091179182905560405185935f80516020615f3c83398151915293612c129390041690615570565b60405180910390a2600681015460405183915f80516020615f5c833981519152916117e391600160881b90046001600160401b031690615570565b6001546001600160a01b03163314612c7a573360405163118cdaa760e01b8152600401610b49919061554f565b6001600160a01b038116612ca3575f604051631e4fbdf760e01b8152600401610b49919061554f565b600280546001600160a01b0319166001600160a01b03838116918217909255600154604051919216907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700905f90a350565b600683015463ffffffff165f612d0b86868461400f565b905080602001515f03612d615760068501805460ff60801b1916905560405186905f80516020615efc83398151915290612d48905f90879061559b565b60405180910390a2612d5a8686612fc4565b5050612dd3565b5f612d708784845f01516140a8565b9050612d7e878683856141ac565b602082015160068701805460ff60801b1916600160801b60ff84160217905560405188915f80516020615efc83398151915291612dbd9190889061559b565b60405180910390a2612dcf8787612fc4565b5050505b50505050565b80546113c9908290600160481b90046001600160401b031661426f565b6008545f03612e025750565b600880545f909155600980546001600160401b031916905560405181815282907fffb0019827f9e43d212f207be3a20cd3a7fc776b3fcf5ec5ae1030d71489ca2b906020016117e3565b5f600482018190558154600360ff19909116178083556040515f199285925f80516020615edc83398151915292612e9b9291869182918291600160881b9091046001600160401b031690615b1a565b60405180910390a2825f80516020615f1c8339815191525f42604051611e2b929190615b46565b5f612ecb610d65565b60048401819055600b80545f90612ee3908490615a13565b909155505f9050612ef5600184615a26565b90505f60018411612f07575f19612f12565b612f12600285615a26565b90505f60028511612f24575f19612f2f565b612f2f600386615a26565b6006870154909150612f50908890600160201b900463ffffffff1687614341565b93505f612f62876004015487876144bd565b9050612f748885835f0151600161463d565b6001861115612f8e57612f8e88848360200151600261463d565b6002861115612fa857612fa888838360400151600361463d565b612fb588888686866147e3565b60800151979650505050505050565b5f828152601260205260409020546035811115612ff4576040516301eccb0960e51b815260040160405180910390fd5b60068201805463ffffffff60601b1916600160601b63ffffffff84811682029290921792839055909104161561302b57600461302e565b60035b8254839060ff1916600183600481111561304a5761304a615995565b02179055506006820154600160601b900463ffffffff165f0361308657825f80516020615f1c8339815191525f42604051611e2b929190615b46565b505050565b5f6001825460ff1660048111156130a4576130a4615995565b1415806130c257508154600160481b90046001600160401b03164210155b156130ce57505f919050565b6118d2824261426f565b6130e06154db565b6040516370a0823160e01b81525f906001600160a01b037f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd8116906370a082319061312e90309060040161554f565b602060405180830381865afa158015613149573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061316d91906159e8565b90506131a46001600160a01b037f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd8116843087613d84565b6040516370a0823160e01b815281906001600160a01b037f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd8116906370a08231906131f290309060040161554f565b602060405180830381865afa15801561320d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061323191906159e8565b61323b9190615a26565b6020830181905284146132615760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0383168252602082015161328190611b58612710613724565b6040830181905260208301516132979190615a26565b60608301526001600160401b03421660a083015260408201516132e8906001600160a01b037f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd81169061dead9061482d565b6132f58260600151614853565b60808301525092915050565b6006820180545f858152600e6020908152604080832063ffffffff948516808552908352818420875181546001600160a01b0319166001600160a01b0390911617815592870151600180850191909155918701516002840155606087015160038401556080870151600484015560a0870151600590930180546001600160401b0319166001600160401b03909416939093179092558454919490939092916133ab91859116615b5d565b92506101000a81548163ffffffff021916908363ffffffff1602179055508160200151836005015f8282546133e09190615a13565b90915550505f848152600f6020908152604080832085516001600160a01b0316845290915290205460ff166134cf575f848152600f6020908152604080832085516001600160a01b0390811685529083528184208054600160ff199091168117909155888552601184528285208751831686528452828520869055888552601084529184208651815480850183559186529390942090930180546001600160a01b03191692909316919091179091556006840180546004906134b0908490600160201b900463ffffffff16615b5d565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b5f848152601460209081526040909120548351918401519091908390436134f7600182615a26565b6040805160208101979097526001600160a01b03909516948601949094526060850192909252608084015260a08301524060c082015260e00160408051601f1981840301815291815281516020928301205f878152601490935290822055835461357390601e90600160481b90046001600160401b0316615a13565b90505f6135836201518042615a13565b90508082116135925781613594565b805b85546001600160401b0391909116600160481b02600160481b600160881b031990911617909455509392505050565b5f828152600e602090815260408083208484528252808320805460018201546002830154600384015460048501548a8952600d8852978690205460058601548751948552978401929092528286015260608201969096526001600160401b03600160481b909604861660808201529490931660a0850152905190926001600160a01b0390921691849186917fd7e5f73e0349f5769e5f38f545de71e86c6861848c2d86ab1d9cb1a7cde9dc71919081900360c00190a4505050565b5f6118d261369183610bb8612710613724565b6137ca565b5f806008545f141580156136b457506009546001600160401b031615155b80156136d6575082546009546001600160401b03600160481b90920482169116105b90508080156136f057506009546001600160401b03164210155b801561370c57508254600160481b90046001600160401b031642105b1561371b575050600854919050565b50506002015490565b5f80805f19858709858702925082811083820303915050805f03613758575f841161374d575f80fd5b508290049050610e6b565b808411613763575f80fd5b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b5f8115806137de57506001600160801b0382115b156137fc57604051630802985160e31b815260040160405180910390fd5b7f0000000000000000000000005d32c699f4755c5b317489f32dec68e1f63246ed6001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015613858573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061387c9190615b7a565b6001600160801b03165f036138a457604051630802985160e31b815260040160405180910390fd5b6040805160028082526060820183525f926020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000012c815f815181106138f7576138f7615b06565b602002602001019063ffffffff16908163ffffffff16815250505f8160018151811061392557613925615b06565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81525f906001600160a01b037f0000000000000000000000005d32c699f4755c5b317489f32dec68e1f63246ed169063883bdbfd90613988908590600401615ba0565b5f60405180830381865afa1580156139a2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526139c99190810190615cb0565b50905080516002146139ee57604051630802985160e31b815260040160405180910390fd5b5f815f81518110613a0157613a01615b06565b602002602001015182600181518110613a1c57613a1c615b06565b6020026020010151613a2e9190615d73565b90505f613a6163ffffffff7f000000000000000000000000000000000000000000000000000000000000012c1683615da0565b90505f8260060b128015613aa65750613aa063ffffffff7f000000000000000000000000000000000000000000000000000000000000012c1683615ddc565b60060b15155b15613ab95780613ab581615dfd565b9150505b5f613b0682887f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd817f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73614bad565b9050805f03613b2857604051630802985160e31b815260040160405180910390fd5b9695505050505050565b613b3d600654612df6565b60098054600160401b600160801b0319169055600a54613b7057604051631cef5d9f60e01b815260040160405180910390fd5b600160065f828254613b829190615a13565b90915550506006545f908152600d60205260408120600a805460088301559190915580546001600160481b031916610100426001600160401b03811691909102919091176001178255613bd890610e1090615a13565b81546001600160401b0391909116600160481b02600160481b600160881b031990911617815560075460028201556006543090613c16600143615a26565b40604051602001613c2993929190615ab1565b60408051601f1981840301815282825280516020918201206006545f9081526014909252918120919091556370a0823160e01b8252906001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7316906370a0823190613c9e90309060040161554f565b602060405180830381865afa158015613cb9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cdd91906159e8565b9050600b54811015613d02576040516315c45db960e11b815260040160405180910390fd5b600b54613d0f9082615a26565b600383019081555f600c55600654835460028501549254604080516001600160401b03610100850481168252600160481b90940490931660208401528201939093526060810192909252907fc14c2b5ab44ec2aa5041966f8c8bf198662e94644d79f2c4ab59192ade6b1292906080016117e3565b6040516001600160a01b038481166024830152838116604483015260648201839052612dd39186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614cb3565b5f83815260126020526040812060068401549091600160401b90910463ffffffff169081905b835483108015613e2057508481105b15613f68575f848481548110613e3857613e38615b06565b5f9182526020909120600590910201600481015490915060ff16613f5b5760048101805460ff191660019081179091558101545f89815260136020908152604080832085546001600160a01b0316845290915281208054909190613e9d908490615a26565b90915550506001810154600b80545f90613eb8908490615a26565b909155505080546001820154613efc916001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7381169291169061482d565b80546001820154600283015460038401546040516001600160a01b03909416938c937f5a4029e557daab85dffae7b9a57e7dd2435bad25e3b21974f48e49ef41ac44c193613f5293919260ff9091169190615e1e565b60405180910390a35b5060019283019201613e11565b60068601805463ffffffff60401b1916600160401b63ffffffff86160217905560405187907f681dcb35b2648ff840074936817a68d3007e718357abe76ee47298b8d48ff06c90613fbe908590879086906155a9565b60405180910390a283548303612dcf57855460ff19166003178655600486015460405188915f80516020615f1c83398151915291613ffe91904290615b46565b60405180910390a250505050505050565b61403660405180608001604052805f81526020015f81526020015f81526020015f81525090565b6006830154614054908590600160201b900463ffffffff1684614341565b808252603211614065576032614068565b80515b6020820181905215610e6b5761408783600401546107d0612710613724565b60408201819052602082015161409c91615a9e565b60608201529392505050565b6060816001600160401b038111156140c2576140c2615af2565b6040519080825280602002602001820160405280156140eb578160200160208202803683370190505b505f8581526010602052604081205491925090815b81811015614182575f87815260106020526040812080548390811061412757614127615b06565b5f918252602090912001546001600160a01b03169050614148888883614d59565b15614153575061417a565b8185858151811061416657614166615b06565b602002602001018181525050836001019350505b600101614100565b508382146141a35760405163162908e360e11b815260040160405180910390fd5b50509392505050565b5f5b8160200151811015614268575f6141f284838789866040516020016141d5939291906155a9565b604051602081830303815290604052805190602001205f1c614e4a565b5f878152601060205260408120805492935090918390811061421657614216615b06565b5f9182526020808320909101548983526011825260408084206001600160a01b039092168085529190925291205490915061425e9088906142578787614eea565b600461463d565b50506001016141ae565b5050505050565b5f6008545f148061428957506009546001600160401b0316155b806142ab575082546009546001600160401b03600160481b9092048216911610155b806142c457506009546001600160401b03908116908316105b156142d057505f6118d2565b600283018054600880549283905560078390555f9055600980546001600160401b03191690556006546040519192917ff0e4457ebc34a27eef8780e2d8d25fe749578b5b593e232c1650477730955f469061432e908590859061559b565b60405180910390a2506001949350505050565b5f838152600e6020526040812081908161435c600186615a26565b815260208101919091526040015f908120546001600160a01b0316915060018411614387575f6143ba565b5f868152600e60205260408120906143a0600287615a26565b815260208101919091526040015f20546001600160a01b03165b90505f600285116143cb575f6143fe565b5f878152600e60205260408120906143e4600388615a26565b815260208101919091526040015f20546001600160a01b03165b905060016001600160a01b0383161580159061442c5750836001600160a01b0316836001600160a01b031614155b1561443f5761443c600182615a13565b90505b6001600160a01b038216158015906144695750836001600160a01b0316826001600160a01b031614155b80156144875750826001600160a01b0316826001600160a01b031614155b1561449a57614497600182615a13565b90505b8087116144a7575f6144b1565b6144b18188615a26565b98975050505050505050565b6144ea6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6144f984611388612710613724565b815260018311614509575f614518565b614518846107d0612710613724565b60208201526002831161452b575f61453a565b61453a846103e8612710613724565b60408201526080810182905281614551575f614560565b614560846107d0612710613724565b606082015260028310156145905761457d846107d0612710613724565b8151829061458c908390615a13565b9052505b60038310156145bb576145a8846103e8612710613724565b815182906145b7908390615a13565b9052505b815f036145e4576145d1846107d0612710613724565b815182906145e0908390615a13565b9052505b5f816060015182604001518360200151845f01516146029190615a13565b61460c9190615a13565b6146169190615a13565b90506146228186615a26565b82518390614631908390615a13565b90525090949350505050565b81158061464a57505f1983145b612dd3575f848152600e602090815260408083208684529091529020546001600160a01b03168061467b5750612dd3565b5f8581526013602090815260408083206001600160a01b0385168452909152812080548592906146ac908490615a13565b90915550505f85815260126020908152604091829020825160a0810184526001600160a01b03851681529182018690529181018460048111156146f1576146f1615995565b815260208082018890525f604092830181905284546001808201875595825290829020845160059092020180546001600160a01b0319166001600160a01b03909216919091178155908301518185015590820151600282018054939492939192909160ff19169083600481111561476a5761476a615995565b0217905550606082015160038201556080909101516004909101805460ff19169115159190911790556040516001600160a01b0382169086907fd4b7789121552d8b23457dfda484be88230a8daf1f91c11b1f9147007ef9019f906147d490879087908a90615e1e565b60405180910390a35050505050565b6004840154845460405187925f80516020615edc8339815191529261481e92889188918891600160881b90046001600160401b031690615b1a565b60405180910390a25050505050565b61308683846001600160a01b031663a9059cbb8585604051602401613db9929190615e52565b5f8061485e83614f40565b90505f7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016148ad919061554f565b602060405180830381865afa1580156148c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906148ec91906159e8565b6040805160e0810182526001600160a01b037f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd8181168083527f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73909116602083015262ffffff7f000000000000000000000000000000000000000000000000000000000000271016928201929092523060608201526080810187905260a081018590525f60c08201529192506149c2907f000000000000000000000000caf681a66d020601342297493863e78c959e5cb287614fa4565b604080516304e45aaf60e01b815282516001600160a01b0390811660048301526020840151811660248301529183015162ffffff1660448201526060830151821660648201526080830151608482015260a083015160a482015260c0830151821660c48201527f000000000000000000000000caf681a66d020601342297493863e78c959e5cb2909116906304e45aaf9060e4016020604051808303815f875af1158015614a72573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614a9691906159e8565b50614aeb6001600160a01b037f000000000000000000000000e11dbfca75228e09c96b3a0381affd4f3663fd81167f000000000000000000000000caf681a66d020601342297493863e78c959e5cb25f614fa4565b6040516370a0823160e01b815282906001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7316906370a0823190614b3990309060040161554f565b602060405180830381865afa158015614b54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614b7891906159e8565b614b829190615a26565b935082841015614ba5576040516303ddb00360e31b815260040160405180910390fd5b505050919050565b5f80614bb886615034565b90506001600160801b036001600160a01b03821611614c3d575f614be56001600160a01b03831680615a87565b9050836001600160a01b0316856001600160a01b031610614c1d57614c18600160c01b876001600160801b031683613724565b614c35565b614c3581876001600160801b0316600160c01b613724565b925050614caa565b5f614c566001600160a01b03831680600160401b613724565b9050836001600160a01b0316856001600160a01b031610614c8e57614c89600160801b876001600160801b031683613724565b614ca6565b614ca681876001600160801b0316600160801b613724565b9250505b50949350505050565b5f80836001600160a01b031683604051614ccd9190615e6b565b5f604051808303815f865af19150503d805f8114614d06576040519150601f19603f3d011682016040523d82523d5f602084013e614d0b565b606091505b5091509150811580614d395750805115801590614d39575080806020019051810190614d379190615e86565b155b15612dd35783604051635274afe760e01b8152600401610b49919061554f565b5f838152600e602052604081206001600160a01b0383169082614d7d600187615a26565b815260208101919091526040015f20546001600160a01b031603614da357506001610e6b565b600183118015614dec57505f848152600e602052604081206001600160a01b03841691614dd1600287615a26565b815260208101919091526040015f20546001600160a01b0316145b15614df957506001610e6b565b600283118015614e4257505f848152600e602052604081206001600160a01b03841691614e27600387615a26565b815260208101919091526040015f20546001600160a01b0316145b949350505050565b5f80838551614e599190615a26565b614e639084615a4d565b614e6d9085615a13565b9050848181518110614e8157614e81615b06565b60200260200101519150848481518110614e9d57614e9d615b06565b6020026020010151858281518110614eb757614eb7615b06565b60200260200101818152505081858581518110614ed657614ed6615b06565b602002602001018181525050509392505050565b60208201515f90614efc836001615a13565b03614f375760018360200151614f129190615a26565b8360600151614f219190615a87565b8360400151614f309190615a26565b90506118d2565b50506060015190565b5f80614f4b836137ca565b90505f614f828261161c61ffff7f000000000000000000000000000000000000000000000000000000000000032016612710615a26565b9050805f03610e6b57604051630802985160e31b815260040160405180910390fd5b5f836001600160a01b031663095ea7b38484604051602401614fc7929190615e52565b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050509050615000848261543a565b612dd35761502a84856001600160a01b031663095ea7b3865f604051602401613db9929190615e52565b612dd38482614cb3565b5f805f8360020b12615049578260020b615056565b8260020b61505690615ea1565b9050615065620d89e719615ebb565b60020b81111561509b5760405162461bcd60e51b81526020600482015260016024820152601560fa1b6044820152606401610b49565b5f816001165f036150b057600160801b6150c2565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b0316905060028216156150f75760806150f2826ffff97272373d413259a46990580e213a615a87565b901c90505b600482161561512157608061511c826ffff2e50f5f656932ef12357cf3c7fdcc615a87565b901c90505b600882161561514b576080615146826fffe5caca7e10e4e61c3624eaa0941cd0615a87565b901c90505b6010821615615175576080615170826fffcb9843d60f6159c9db58835c926644615a87565b901c90505b602082161561519f57608061519a826fff973b41fa98c081472e6896dfb254c0615a87565b901c90505b60408216156151c95760806151c4826fff2ea16466c96a3843ec78b326b52861615a87565b901c90505b60808216156151f35760806151ee826ffe5dee046a99a2a811c461f1969c3053615a87565b901c90505b61010082161561521e576080615219826ffcbe86c7900a88aedcffc83b479aa3a4615a87565b901c90505b610200821615615249576080615244826ff987a7253ac413176f2b074cf7815e54615a87565b901c90505b61040082161561527457608061526f826ff3392b0822b70005940c7a398e4b70f3615a87565b901c90505b61080082161561529f57608061529a826fe7159475a2c29b7443b29c7fa6e889d9615a87565b901c90505b6110008216156152ca5760806152c5826fd097f3bdfd2022b8845ad8f792aa5825615a87565b901c90505b6120008216156152f55760806152f0826fa9f746462d870fdf8a65dc1f90e061e5615a87565b901c90505b61400082161561532057608061531b826f70d869a156d2a1b890bb3df62baf32f7615a87565b901c90505b61800082161561534b576080615346826f31be135f97d08fd981231505542fcfa6615a87565b901c90505b62010000821615615377576080615372826f09aa508b5b7a84e1c677de54f3e99bc9615a87565b901c90505b620200008216156153a257608061539d826e5d6af8dedb81196699c329225ee604615a87565b901c90505b620400008216156153cc5760806153c7826d2216e584f5fa1ea926041bedfe98615a87565b901c90505b620800008216156153f45760806153ef826b048a170391f7dc42444e8fa2615a87565b901c90505b5f8460020b131561540d5761540a815f19615a9e565b90505b61541b600160201b82615a4d565b15615427576001615429565b5f5b614e429060ff16602083901c615a13565b5f805f846001600160a01b0316846040516154559190615e6b565b5f604051808303815f865af19150503d805f811461548e576040519150601f19603f3d011682016040523d82523d5f602084013e615493565b606091505b50915091508180156154bd5750805115806154bd5750808060200190518101906154bd9190615e86565b80156154d257505f856001600160a01b03163b115b95945050505050565b6040518060c001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f6001600160401b031681525090565b6001600160a01b0381168114615531575f80fd5b50565b5f60208284031215615544575f80fd5b8135610e6b8161551d565b6001600160a01b0391909116815260200190565b6001600160401b03169052565b6001600160401b0391909116815260200190565b5f60208284031215615594575f80fd5b5035919050565b918252602082015260400190565b9283526020830191909152604082015260600190565b8015158114615531575f80fd5b5f602082840312156155dc575f80fd5b8135610e6b816155bf565b5f80604083850312156155f8575f80fd5b82359150602083013560ff8116811461560f575f80fd5b809150509250929050565b5f806040838503121561562b575f80fd5b50508035926020909101359150565b5f5b8381101561565457818101518382015260200161563c565b50505f910152565b602081525f825180602084015261567a81604085016020870161563a565b601f01601f19169190910160400192915050565b5f806040838503121561569f575f80fd5b82359150602083013561560f8161551d565b815181526020808301516101808301916156cf9084018260ff169052565b5060408301516156e26040840182615563565b5060608301516156f56060840182615563565b5060808301516157086080840182615563565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015161573f8285018263ffffffff169052565b50506101208381015163ffffffff81168483015250506101408381015163ffffffff81168483015250506101608381015163ffffffff8116848301525b505092915050565b815160ff1681526101c0810160208301516157a26020840182615563565b5060408301516157b56040840182615563565b5060608301516157c86060840182615563565b5060808301516157db6080840182615563565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161581e8285018263ffffffff169052565b50506101408381015163ffffffff908116918401919091526101608085015160ff1690840152610180808501518216908401526101a080850151918216818501529061577c565b5f815180845260208085019450602084015f5b8381101561589457815187529582019590820190600101615878565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561589457815160ff16875295820195908201906001016158b2565b5f815180845260208085019450602084015f5b838110156158945781511515875295820195908201906001016158e4565b60a080825286519082018190525f9060209060c0840190828a01845b828110156159435781516001600160a01b03168452928401929084019060010161591e565b50505083810360208501526159588189615865565b915050828103604084015261596d818761589f565b905082810360608401526159818186615865565b905082810360808401526144b181856158d1565b634e487b7160e01b5f52602160045260245ffd5b968752602087019590955260408601939093526060850191909152608084015263ffffffff1660a08301526001600160a01b031660c082015260e00190565b5f602082840312156159f8575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156118d2576118d26159ff565b818103818111156118d2576118d26159ff565b634e487b7160e01b5f52601260045260245ffd5b5f82615a5b57615a5b615a39565b500690565b6001600160401b03818116838216019080821115615a8057615a806159ff565b5092915050565b80820281158282048414176118d2576118d26159ff565b5f82615aac57615aac615a39565b500490565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160401b03828116828216039080821115615a8057615a806159ff565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b9485526020850193909352604084019190915260608301526001600160401b0316608082015260a00190565b9182526001600160401b0316602082015260400190565b63ffffffff818116838216019080821115615a8057615a806159ff565b5f60208284031215615b8a575f80fd5b81516001600160801b0381168114610e6b575f80fd5b602080825282518282018190525f9190848201906040850190845b81811015615bdd57835163ffffffff1683529284019291840191600101615bbb565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715615c1157615c11615af2565b604052919050565b5f6001600160401b03821115615c3157615c31615af2565b5060051b60200190565b5f82601f830112615c4a575f80fd5b81516020615c5f615c5a83615c19565b615be9565b8083825260208201915060208460051b870101935086841115615c80575f80fd5b602086015b84811015615ca5578051615c988161551d565b8352918301918301615c85565b509695505050505050565b5f8060408385031215615cc1575f80fd5b82516001600160401b0380821115615cd7575f80fd5b818501915085601f830112615cea575f80fd5b81516020615cfa615c5a83615c19565b82815260059290921b84018101918181019089841115615d18575f80fd5b948201945b83861015615d445785518060060b8114615d35575f80fd5b82529482019490820190615d1d565b91880151919650909350505080821115615d5c575f80fd5b50615d6985828601615c3b565b9150509250929050565b600682810b9082900b03667fffffffffffff198112667fffffffffffff821317156118d2576118d26159ff565b5f8160060b8360060b80615db657615db6615a39565b667fffffffffffff1982145f1982141615615dd357615dd36159ff565b90059392505050565b5f8260060b80615dee57615dee615a39565b808360060b0791505092915050565b5f8160020b627fffff198103615e1557615e156159ff565b5f190192915050565b8381526060810160058410615e4157634e487b7160e01b5f52602160045260245ffd5b602082019390935260400152919050565b6001600160a01b03929092168252602082015260400190565b5f8251615e7c81846020870161563a565b9190910192915050565b5f60208284031215615e96575f80fd5b8151610e6b816155bf565b5f600160ff1b8201615eb557615eb56159ff565b505f0390565b5f8160020b627fffff198103615ed357615ed36159ff565b5f039291505056fe7042bd10dbe05c21f65180e15a3f81868fb6f326675466a2aaa232ff66b25e21d7a3011d24ef5a0e45b052d9edae4bdcf3d2cef189e92a32db3dfa755a9b618bc2013973c1b57bc4c3d7784ede2ac4ce6d3f374b3317f26bc2650f9b9cd00f363cea0c8e4eb828c0293c1cd7cf72d8c4eb394823c539581eb2e6b25a6c5feda10cdbb89fc7974f07e4662fa4b0d250d0fa12c9c39f50ba940ef49f8a157a5676a2646970667358221220b5e88f6870b1b6edf3e4a09b9f93c4619f3c932f7e752b85ecc6c69311db518464736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
WETH (WETH) | WETH | 0.000000 | $1,900.26 | $0 |
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x03e27173…1c0966 | Transfer | 21,866,271 | 20 days agoTue, 28 Jul 2026 20:06:53 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x47635849…f2a69f | Transfer | 21,857,291 | 20 days agoTue, 28 Jul 2026 19:51:51 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x330b880d…26e15d | Transfer | 21,848,332 | 20 days agoTue, 28 Jul 2026 19:36:52 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x8d62ad33…9331c3 | Transfer | 21,839,362 | 20 days agoTue, 28 Jul 2026 19:21:52 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xe346f46b…d73059 | Transfer | 21,830,393 | 20 days agoTue, 28 Jul 2026 19:06:52 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x8c497b69…fcb94d | Transfer | 21,821,423 | 20 days agoTue, 28 Jul 2026 18:51:51 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x73e38473…448cd5 | Transfer | 21,812,446 | 20 days agoTue, 28 Jul 2026 18:36:52 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x7cd3315c…c16122 | Transfer | 21,803,475 | 20 days agoTue, 28 Jul 2026 18:21:51 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xdece8f87…f6cda1 | Transfer | 21,794,502 | 20 days agoTue, 28 Jul 2026 18:06:51 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x58bfa311…de2068 | Transfer | 21,785,519 | 20 days agoTue, 28 Jul 2026 17:51:51 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x1d57c998…e99347 | Transfer | 21,776,543 | 20 days agoTue, 28 Jul 2026 17:36:51 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xa325676d…4f4003 | Transfer | 21,767,568 | 20 days agoTue, 28 Jul 2026 17:21:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xc2178409…7aeb16 | Transfer | 21,758,578 | 20 days agoTue, 28 Jul 2026 17:06:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x3530c294…578a83 | Transfer | 21,749,607 | 20 days agoTue, 28 Jul 2026 16:51:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xd9e5644c…995f37 | Transfer | 21,740,631 | 20 days agoTue, 28 Jul 2026 16:36:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x97853f71…071c15 | Transfer | 21,731,646 | 20 days agoTue, 28 Jul 2026 16:21:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xb19329e2…8aec0c | Transfer | 21,722,672 | 20 days agoTue, 28 Jul 2026 16:06:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0xb73dd811…dfb8fc | Transfer | 21,713,699 | 20 days agoTue, 28 Jul 2026 15:51:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x86c5354d…825b4d | Transfer | 21,704,707 | 20 days agoTue, 28 Jul 2026 15:36:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x3510c05f…458a3b | Transfer | 21,695,731 | 20 days agoTue, 28 Jul 2026 15:21:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x87167d50…c3916c | Transfer | 21,686,763 | 20 days agoTue, 28 Jul 2026 15:06:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x4b638943…1c56ad | Transfer | 21,686,066 | 20 days agoTue, 28 Jul 2026 15:05:41 UTC | 0x9d43…f8d6 | OUT | 0xd65e…f25d | 0.000804 WETH | WETH (WETH) | |
| 0xb289d533…8d1060 | Transfer | 21,677,777 | 20 days agoTue, 28 Jul 2026 14:51:49 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x6a7b0647…1c3f0f | Transfer | 21,668,796 | 20 days agoTue, 28 Jul 2026 14:36:49 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000000 WETH | WETH (WETH) | |
| 0x6cc8b7ce…a8f0ac | Transfer | 21,659,821 | 20 days agoTue, 28 Jul 2026 14:21:50 UTC | 0x7e71…7875 | IN | 0x9d43…f8d6 | 0.000009 WETH | WETH (WETH) |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xcfe72c…e23311 | prepareNextRoundRandomness | 21,902,406 | 20 days agoTue, 28 Jul 2026 21:07:15 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000144 | |
| 0x12a3bf…34195a | finalizeRound | 21,896,411 | 20 days agoTue, 28 Jul 2026 20:57:15 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000187 | |
| 0xb4c35b…1c602a | applyPendingBurnAmount | 21,875,212 | 20 days agoTue, 28 Jul 2026 20:21:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000131 | |
| 0xce4454…fb8800 | scheduleBurnAmount | 21,872,221 | 20 days agoTue, 28 Jul 2026 20:16:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000252 | |
| 0xe9c57e…cf663f | applyPendingBurnAmount | 21,869,220 | 20 days agoTue, 28 Jul 2026 20:11:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000132 | |
| 0x03e271…1c0966 | depositCreatorFees | 21,866,271 | 20 days agoTue, 28 Jul 2026 20:06:53 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000175 | |
| 0x4a2cc2…524a3d | scheduleBurnAmount | 21,866,242 | 20 days agoTue, 28 Jul 2026 20:06:50 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000253 | |
| 0x8715de…777ad3 | applyPendingBurnAmount | 21,866,226 | 20 days agoTue, 28 Jul 2026 20:06:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000131 | |
| 0xe61543…0cdba4 | scheduleBurnAmount | 21,863,249 | 20 days agoTue, 28 Jul 2026 20:01:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000299 | |
| 0x83b25e…3316b3 | startNextRound | 21,860,522 | 20 days agoTue, 28 Jul 2026 19:57:15 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000478 | |
| 0xf7f7f9…3772bf | prepareNextRoundRandomness | 21,860,516 | 20 days agoTue, 28 Jul 2026 19:57:15 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000143 | |
| 0x476358…f2a69f | depositCreatorFees | 21,857,291 | 20 days agoTue, 28 Jul 2026 19:51:51 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000237 | |
| 0xb60407…5fc35a | finalizeRound | 21,854,532 | 20 days agoTue, 28 Jul 2026 19:47:14 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000190 | |
| 0x24064b…96f5b7 | applyPendingBurnAmount | 21,854,275 | 20 days agoTue, 28 Jul 2026 19:46:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000131 | |
| 0x16a8f5…e46fb6 | scheduleBurnAmount | 21,851,301 | 20 days agoTue, 28 Jul 2026 19:41:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000255 | |
| 0xdd8864…f282b4 | applyPendingBurnAmount | 21,851,290 | 20 days agoTue, 28 Jul 2026 19:41:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000132 | |
| 0x330b88…26e15d | depositCreatorFees | 21,848,332 | 20 days agoTue, 28 Jul 2026 19:36:52 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000175 | |
| 0xc29b9e…98c950 | scheduleBurnAmount | 21,848,306 | 20 days agoTue, 28 Jul 2026 19:36:49 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000253 | |
| 0xddba4c…3ffd4c | applyPendingBurnAmount | 21,848,295 | 20 days agoTue, 28 Jul 2026 19:36:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000132 | |
| 0xc49c60…e30764 | scheduleBurnAmount | 21,845,306 | 20 days agoTue, 28 Jul 2026 19:31:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000254 | |
| 0x8398cd…e92a21 | applyPendingBurnAmount | 21,842,311 | 20 days agoTue, 28 Jul 2026 19:26:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000132 | |
| 0x8d62ad…9331c3 | depositCreatorFees | 21,839,362 | 20 days agoTue, 28 Jul 2026 19:21:52 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000177 | |
| 0x73e86c…badb13 | scheduleBurnAmount | 21,839,349 | 20 days agoTue, 28 Jul 2026 19:21:51 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000253 | |
| 0x4440bd…ef57ce | applyPendingBurnAmount | 21,839,321 | 20 days agoTue, 28 Jul 2026 19:21:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000133 | |
| 0x69196f…d2db3a | scheduleBurnAmount | 21,836,343 | 20 days agoTue, 28 Jul 2026 19:16:48 UTC | 0x7e71…7875 | IN | BurnWarsGameV27_4 | $0.000 ETH | 0.00000254 |
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0xcfe72c…e23311 | 20 days agoTue, 28 Jul 2026 21:07:15 UTC | 0x16779b…fa65 | [0] 0x000000000000…00000007 [1] 0xa1aad9bb98d9…3f8daaf2 |
| 0x12a3bf…34195a | 20 days agoTue, 28 Jul 2026 20:57:15 UTC | 0xc20139…0f36 | [0] 0x000000000000…00000006 data: 0x000000000000000000…6a6917ab |
| 0x12a3bf…34195a | 20 days agoTue, 28 Jul 2026 20:57:15 UTC | 0x7042bd…5e21 | [0] 0x000000000000…00000006 data: 0x000000000000000000…6a6917ab |
| 0xb4c35b…1c602a | 20 days agoTue, 28 Jul 2026 20:21:49 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000006 data: 0x000000000000000000…b4640000 |
| 0xce4454…fb8800 | 20 days agoTue, 28 Jul 2026 20:16:49 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000006 data: 0x000000000000000000…6a690e6d |
| 0xe9c57e…cf663f | 20 days agoTue, 28 Jul 2026 20:11:49 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000006 data: 0x000000000000000000…470c0000 |
| 0x03e271…1c0966 | 20 days agoTue, 28 Jul 2026 20:06:53 UTC | 0x64c012…e952 | [0] 0x000000000000…00000006 [1] 0x000000000000…50d07875 data: 0x000000000000000000…00000000 |
| 0x4a2cc2…524a3d | 20 days agoTue, 28 Jul 2026 20:06:50 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000006 data: 0x000000000000000000…6a690c16 |
| 0x8715de…777ad3 | 20 days agoTue, 28 Jul 2026 20:06:48 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000006 data: 0x000000000000000000…e30c0000 |
| 0xe61543…0cdba4 | 20 days agoTue, 28 Jul 2026 20:01:49 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000006 data: 0x000000000000000000…6a690ae9 |
| 0x83b25e…3316b3 | 20 days agoTue, 28 Jul 2026 19:57:15 UTC | 0xc14c2b…1292 | [0] 0x000000000000…00000006 data: 0x000000000000000000…44af1d79 |
| 0xf7f7f9…3772bf | 20 days agoTue, 28 Jul 2026 19:57:15 UTC | 0x16779b…fa65 | [0] 0x000000000000…00000006 [1] 0x995699e36019…c5f66cdc |
| 0x476358…f2a69f | 20 days agoTue, 28 Jul 2026 19:51:51 UTC | 0x64c012…e952 | [0] 0x000000000000…00000006 [1] 0x000000000000…50d07875 data: 0x000000000000000000…00000001 |
| 0xb60407…5fc35a | 20 days agoTue, 28 Jul 2026 19:47:14 UTC | 0xc20139…0f36 | [0] 0x000000000000…00000005 data: 0x000000000000000000…6a690742 |
| 0xb60407…5fc35a | 20 days agoTue, 28 Jul 2026 19:47:14 UTC | 0x7042bd…5e21 | [0] 0x000000000000…00000005 data: 0x000000000000000000…6a690742 |
| 0x24064b…96f5b7 | 20 days agoTue, 28 Jul 2026 19:46:49 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000005 data: 0x000000000000000000…aabc0000 |
| 0x16a8f5…e46fb6 | 20 days agoTue, 28 Jul 2026 19:41:49 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000005 data: 0x000000000000000000…6a690639 |
| 0xdd8864…f282b4 | 20 days agoTue, 28 Jul 2026 19:41:48 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000005 data: 0x000000000000000000…eab80000 |
| 0x330b88…26e15d | 20 days agoTue, 28 Jul 2026 19:36:52 UTC | 0x64c012…e952 | [0] 0x000000000000…00000005 [1] 0x000000000000…50d07875 data: 0x000000000000000000…00000000 |
| 0xc29b9e…98c950 | 20 days agoTue, 28 Jul 2026 19:36:49 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000005 data: 0x000000000000000000…6a69050d |
| 0xddba4c…3ffd4c | 20 days agoTue, 28 Jul 2026 19:36:48 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000005 data: 0x000000000000000000…857c0000 |
| 0xc49c60…e30764 | 20 days agoTue, 28 Jul 2026 19:31:48 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000005 data: 0x000000000000000000…6a6903e0 |
| 0x8398cd…e92a21 | 20 days agoTue, 28 Jul 2026 19:26:48 UTC | 0xf0e445…5f46 | [0] 0x000000000000…00000005 data: 0x000000000000000000…d2e00000 |
| 0x8d62ad…9331c3 | 20 days agoTue, 28 Jul 2026 19:21:52 UTC | 0x64c012…e952 | [0] 0x000000000000…00000005 [1] 0x000000000000…50d07875 data: 0x000000000000000000…00000000 |
| 0x73e86c…badb13 | 20 days agoTue, 28 Jul 2026 19:21:51 UTC | 0xb43357…6af4 | [0] 0x000000000000…00000005 data: 0x000000000000000000…6a69018b |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||