// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {LotteryTreasury} from "./LotteryTreasury.sol";
import {IRandomnessAdapter} from "./interfaces/IRandomnessAdapter.sol";
contract LotteryEngine is AccessControl, Pausable, ReentrancyGuard {
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
uint64 public constant ROUND_DURATION = 15 minutes;
uint16 public constant BPS = 10_000;
uint8 public constant MAX_WINNERS = 32;
enum Status {
NONE,
OPEN,
MANIFEST_COMMITTED,
RANDOMNESS_REQUESTED,
RANDOMNESS_FULFILLED,
WINNERS_FINALIZED,
PAYING,
COMPLETE,
POSTPONED
}
struct Round {
uint64 opensAt;
uint64 closesAt;
uint64 snapshotBlock;
uint64 manifestCommittedAt;
uint256 minimumBalance;
uint256 tokensPerEntry;
uint256 totalEntries;
uint256 prizePool;
bytes32 eligibilityRoot;
bytes32 manifestHash;
bytes32 exclusionSetHash;
bytes32 randomnessRequestId;
address randomnessAdapter;
uint32 eligibleWalletCount;
uint8 winnerCount;
Status status;
}
struct Winner {
address wallet;
uint256 snapshotBalance;
uint256 firstTicket;
uint256 exclusiveLastTicket;
uint256 selectedTicket;
uint256 prize;
bool paid;
}
LotteryTreasury public immutable treasury;
address public immutable projectToken;
uint256 public immutable minimumBalance;
uint256 public immutable tokensPerEntry;
uint256 public immutable minimumPrizePool;
uint64 public immutable manifestReviewPeriod;
IRandomnessAdapter public randomnessAdapter;
uint8 public configuredWinnerCount;
uint16[] private _configuredPrizeBps;
uint256 public nextRoundId = 1;
mapping(uint256 => Round) public rounds;
mapping(uint256 => bool) public fundingFrozen;
mapping(uint256 => mapping(uint8 => Winner)) public winners;
mapping(uint256 => uint16[]) public roundPrizeBps;
event RoundOpened(
uint256 indexed roundId,
uint64 opensAt,
uint64 closesAt,
uint256 prizePool,
uint256 minimumBalance,
uint256 tokensPerEntry,
uint8 winnerCount,
uint16[] prizeBps,
address indexed randomnessAdapter
);
event ManifestCommitted(
uint256 indexed roundId,
uint64 snapshotBlock,
bytes32 eligibilityRoot,
bytes32 manifestHash,
bytes32 exclusionSetHash,
uint32 eligibleWalletCount,
uint256 totalEntries
);
event RoundPostponed(uint256 indexed roundId, uint32 eligibleWalletCount, uint256 rolledOver);
event RandomnessRequested(uint256 indexed roundId, bytes32 indexed requestId, address indexed adapter);
event RandomnessRecorded(uint256 indexed roundId, bytes32 randomness);
event WinnerFinalized(
uint256 indexed roundId, uint8 indexed position, address indexed wallet, uint256 ticket, uint256 prize
);
event PrizeSettled(uint256 indexed roundId, uint8 indexed position, address indexed wallet, uint256 prize);
event RoundCompleted(uint256 indexed roundId);
event RandomnessAdapterChanged(address indexed previousAdapter, address indexed nextAdapter);
event FuturePrizeConfigChanged(uint8 winnerCount, uint16[] prizeBps);
error InvalidAddress();
error InvalidAmount();
error InvalidRound();
error InvalidState();
error InvalidManifest();
error InvalidWinner();
error ReviewPeriodActive();
error RandomnessUnavailable();
constructor(
address admin,
address operator,
address pauser,
address treasury_,
address projectToken_,
address randomnessAdapter_,
uint256 minimumBalance_,
uint256 minimumPrizePool_,
uint64 manifestReviewPeriod_
) {
if (
admin == address(0) || operator == address(0) || pauser == address(0) || treasury_ == address(0)
|| projectToken_ == address(0) || randomnessAdapter_ == address(0)
|| randomnessAdapter_.code.length == 0
) revert InvalidAddress();
if (minimumBalance_ == 0 || manifestReviewPeriod_ == 0) revert InvalidAmount();
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(OPERATOR_ROLE, operator);
_grantRole(PAUSER_ROLE, pauser);
treasury = LotteryTreasury(treasury_);
projectToken = projectToken_;
randomnessAdapter = IRandomnessAdapter(randomnessAdapter_);
minimumBalance = minimumBalance_;
tokensPerEntry = minimumBalance_;
minimumPrizePool = minimumPrizePool_;
manifestReviewPeriod = manifestReviewPeriod_;
uint16[] memory initialPrizeBps = new uint16[](3);
initialPrizeBps[0] = 5_000;
initialPrizeBps[1] = 3_000;
initialPrizeBps[2] = 2_000;
_setFuturePrizeConfig(3, initialPrizeBps);
}
function openRound() external onlyRole(OPERATOR_ROLE) whenNotPaused returns (uint256 roundId, uint256 prizePool) {
uint64 opensAt;
if (nextRoundId == 1) {
opensAt = uint64(block.timestamp);
} else {
uint256 closingRoundId = nextRoundId - 1;
Round storage closingRound = rounds[closingRoundId];
if (closingRound.status != Status.OPEN || block.timestamp < closingRound.closesAt) revert InvalidState();
opensAt = closingRound.closesAt;
uint256 available = treasury.unallocatedWeth();
fundingFrozen[closingRoundId] = true;
if (available < minimumPrizePool) {
closingRound.status = Status.POSTPONED;
emit RoundPostponed(closingRoundId, 0, 0);
} else {
prizePool = treasury.reserveForRound(closingRoundId);
closingRound.prizePool = prizePool;
}
}
roundId = nextRoundId++;
uint8 winnerCount = configuredWinnerCount;
for (uint8 i; i < winnerCount; ++i) {
roundPrizeBps[roundId].push(_configuredPrizeBps[i]);
}
rounds[roundId] = Round({
opensAt: opensAt,
closesAt: opensAt + ROUND_DURATION,
snapshotBlock: 0,
manifestCommittedAt: 0,
minimumBalance: minimumBalance,
tokensPerEntry: tokensPerEntry,
totalEntries: 0,
prizePool: 0,
eligibilityRoot: bytes32(0),
manifestHash: bytes32(0),
exclusionSetHash: bytes32(0),
randomnessRequestId: bytes32(0),
randomnessAdapter: address(randomnessAdapter),
eligibleWalletCount: 0,
winnerCount: winnerCount,
status: Status.OPEN
});
emit RoundOpened(
roundId,
opensAt,
opensAt + ROUND_DURATION,
0,
minimumBalance,
tokensPerEntry,
winnerCount,
_configuredPrizeBps,
address(randomnessAdapter)
);
}
function commitManifest(
uint256 roundId,
uint64 snapshotBlock,
bytes32 eligibilityRoot,
bytes32 manifestHash,
bytes32 exclusionSetHash,
uint32 eligibleWalletCount,
uint256 totalEntries
) external onlyRole(OPERATOR_ROLE) whenNotPaused {
Round storage round = rounds[roundId];
if (round.status != Status.OPEN || block.timestamp < round.closesAt) revert InvalidState();
if (!fundingFrozen[roundId]) revert InvalidState();
if (
snapshotBlock == 0 || snapshotBlock > block.number || eligibilityRoot == bytes32(0)
|| manifestHash == bytes32(0) || exclusionSetHash == bytes32(0) || totalEntries < eligibleWalletCount
) revert InvalidManifest();
round.snapshotBlock = snapshotBlock;
round.eligibilityRoot = eligibilityRoot;
round.manifestHash = manifestHash;
round.exclusionSetHash = exclusionSetHash;
round.eligibleWalletCount = eligibleWalletCount;
round.totalEntries = totalEntries;
round.manifestCommittedAt = uint64(block.timestamp);
emit ManifestCommitted(
roundId, snapshotBlock, eligibilityRoot, manifestHash, exclusionSetHash, eligibleWalletCount, totalEntries
);
if (eligibleWalletCount < round.winnerCount) {
round.status = Status.POSTPONED;
uint256 rolled = treasury.releaseRound(roundId);
emit RoundPostponed(roundId, eligibleWalletCount, rolled);
return;
}
round.status = Status.MANIFEST_COMMITTED;
}
function requestRandomness(uint256 roundId) external whenNotPaused returns (bytes32 requestId) {
Round storage round = rounds[roundId];
if (round.status != Status.MANIFEST_COMMITTED) revert InvalidState();
uint64 notBefore = round.manifestCommittedAt + manifestReviewPeriod;
if (block.timestamp < notBefore) revert ReviewPeriodActive();
round.status = Status.RANDOMNESS_REQUESTED;
IRandomnessAdapter adapter = IRandomnessAdapter(round.randomnessAdapter);
requestId = adapter.requestRandomness(roundId, notBefore);
if (requestId == bytes32(0)) revert RandomnessUnavailable();
round.randomnessRequestId = requestId;
emit RandomnessRequested(roundId, requestId, address(adapter));
}
function recordRandomness(uint256 roundId) external whenNotPaused returns (bytes32 value) {
Round storage round = rounds[roundId];
if (round.status != Status.RANDOMNESS_REQUESTED) revert InvalidState();
(bool fulfilled, bytes32 randomness_) = IRandomnessAdapter(round.randomnessAdapter).randomness(roundId);
if (!fulfilled || randomness_ == bytes32(0)) revert RandomnessUnavailable();
round.status = Status.RANDOMNESS_FULFILLED;
value = randomness_;
emit RandomnessRecorded(roundId, value);
}
function finalizeWinner(
uint256 roundId,
uint8 position,
address wallet,
uint256 snapshotBalance,
uint256 firstTicket,
uint256 exclusiveLastTicket,
bytes32[] calldata proof
) external whenNotPaused {
Round storage round = rounds[roundId];
if (round.status != Status.RANDOMNESS_FULFILLED) revert InvalidState();
if (position >= round.winnerCount || position != _finalizedCount(roundId) || wallet == address(0)) {
revert InvalidWinner();
}
uint256 entries = snapshotBalance / round.tokensPerEntry;
if (
snapshotBalance < round.minimumBalance || entries == 0 || exclusiveLastTicket <= firstTicket
|| exclusiveLastTicket - firstTicket != entries || exclusiveLastTicket > round.totalEntries
) revert InvalidWinner();
bytes32 leaf = eligibilityLeaf(
roundId, round.snapshotBlock, wallet, snapshotBalance, entries, firstTicket, exclusiveLastTicket
);
if (!MerkleProof.verifyCalldata(proof, round.eligibilityRoot, leaf)) revert InvalidWinner();
(, bytes32 randomValue) = IRandomnessAdapter(round.randomnessAdapter).randomness(roundId);
uint256 ticket = _ticketForPosition(roundId, position, randomValue, round.totalEntries);
if (ticket < firstTicket || ticket >= exclusiveLastTicket) revert InvalidWinner();
for (uint8 i; i < position; ++i) {
if (winners[roundId][i].wallet == wallet) revert InvalidWinner();
}
uint256 prize;
if (position == round.winnerCount - 1) {
uint256 priorPrizes;
for (uint8 i; i < position; ++i) {
priorPrizes += winners[roundId][i].prize;
}
prize = round.prizePool - priorPrizes;
} else {
prize = round.prizePool * roundPrizeBps[roundId][position] / BPS;
}
winners[roundId][position] = Winner({
wallet: wallet,
snapshotBalance: snapshotBalance,
firstTicket: firstTicket,
exclusiveLastTicket: exclusiveLastTicket,
selectedTicket: ticket,
prize: prize,
paid: false
});
emit WinnerFinalized(roundId, position, wallet, ticket, prize);
if (position == round.winnerCount - 1) round.status = Status.WINNERS_FINALIZED;
}
function settlePrize(uint256 roundId, uint8 position) external whenNotPaused nonReentrant {
Round storage round = rounds[roundId];
if (round.status != Status.WINNERS_FINALIZED && round.status != Status.PAYING) revert InvalidState();
if (position >= round.winnerCount) revert InvalidWinner();
Winner storage winner = winners[roundId][position];
if (winner.wallet == address(0) || winner.paid) revert InvalidWinner();
winner.paid = true;
round.status = Status.PAYING;
treasury.payPrize(roundId, position, winner.wallet, winner.prize);
emit PrizeSettled(roundId, position, winner.wallet, winner.prize);
if (_paidCount(roundId) == round.winnerCount) {
round.status = Status.COMPLETE;
emit RoundCompleted(roundId);
}
}
function eligibilityLeaf(
uint256 roundId,
uint64 snapshotBlock,
address wallet,
uint256 snapshotBalance,
uint256 entries,
uint256 firstTicket,
uint256 exclusiveLastTicket
) public view returns (bytes32) {
return keccak256(
bytes.concat(
keccak256(
abi.encode(
block.chainid,
address(this),
projectToken,
roundId,
snapshotBlock,
wallet,
snapshotBalance,
entries,
firstTicket,
exclusiveLastTicket
)
)
)
);
}
function previewTicket(uint256 roundId, uint8 position) external view returns (uint256) {
Round storage round = rounds[roundId];
(, bytes32 randomValue) = IRandomnessAdapter(round.randomnessAdapter).randomness(roundId);
return _ticketForPosition(roundId, position, randomValue, round.totalEntries);
}
function setRandomnessAdapter(address nextAdapter) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (nextAdapter == address(0) || nextAdapter.code.length == 0) revert InvalidAddress();
emit RandomnessAdapterChanged(address(randomnessAdapter), nextAdapter);
randomnessAdapter = IRandomnessAdapter(nextAdapter);
}
function configuredPrizeBps() external view returns (uint16[] memory) {
return _configuredPrizeBps;
}
function setFuturePrizeConfig(uint8 winnerCount, uint16[] calldata prizeBps) external onlyRole(DEFAULT_ADMIN_ROLE) {
_setFuturePrizeConfig(winnerCount, prizeBps);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) {
_unpause();
}
function _ticketForPosition(uint256 roundId, uint8 position, bytes32 randomValue, uint256 totalEntries)
internal
view
returns (uint256 ticket)
{
if (randomValue == bytes32(0) || totalEntries == 0) revert RandomnessUnavailable();
uint256 attempt;
while (true) {
ticket = _unbiasedIndex(keccak256(abi.encode(randomValue, roundId, position, attempt)), totalEntries);
bool duplicateRange;
for (uint8 i; i < position; ++i) {
Winner storage prior = winners[roundId][i];
if (ticket >= prior.firstTicket && ticket < prior.exclusiveLastTicket) {
duplicateRange = true;
break;
}
}
if (!duplicateRange) return ticket;
unchecked {
++attempt;
}
}
}
function _unbiasedIndex(bytes32 seed, uint256 upperBound) internal pure returns (uint256) {
uint256 threshold;
unchecked {
threshold = (0 - upperBound) % upperBound;
}
uint256 value = uint256(seed);
uint256 nonce;
while (value < threshold) {
value = uint256(keccak256(abi.encode(seed, ++nonce)));
}
return value % upperBound;
}
function _finalizedCount(uint256 roundId) internal view returns (uint8 count) {
while (count < rounds[roundId].winnerCount && winners[roundId][count].wallet != address(0)) ++count;
}
function _paidCount(uint256 roundId) internal view returns (uint8 count) {
for (uint8 i; i < rounds[roundId].winnerCount; ++i) {
if (winners[roundId][i].paid) ++count;
}
}
function _setFuturePrizeConfig(uint8 winnerCount, uint16[] memory prizeBps) internal {
if (winnerCount == 0 || winnerCount > MAX_WINNERS || prizeBps.length != winnerCount) {
revert InvalidAmount();
}
uint256 total;
delete _configuredPrizeBps;
for (uint8 i; i < winnerCount; ++i) {
if (prizeBps[i] == 0) revert InvalidAmount();
total += prizeBps[i];
_configuredPrizeBps.push(prizeBps[i]);
}
if (total != BPS) revert InvalidAmount();
configuredWinnerCount = winnerCount;
emit FuturePrizeConfigChanged(winnerCount, prizeBps);
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "admin",
"type": "address",
"internalType": "address"
},
{
"name": "operator",
"type": "address",
"internalType": "address"
},
{
"name": "pauser",
"type": "address",
"internalType": "address"
},
{
"name": "treasury_",
"type": "address",
"internalType": "address"
},
{
"name": "projectToken_",
"type": "address",
"internalType": "address"
},
{
"name": "randomnessAdapter_",
"type": "address",
"internalType": "address"
},
{
"name": "minimumBalance_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minimumPrizePool_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "manifestReviewPeriod_",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AccessControlBadConfirmation",
"type": "error",
"inputs": []
},
{
"name": "AccessControlUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "neededRole",
"type": "bytes32",
"internalType": "bytes32"
}
]
},
{
"name": "EnforcedPause",
"type": "error",
"inputs": []
},
{
"name": "ExpectedPause",
"type": "error",
"inputs": []
},
{
"name": "InvalidAddress",
"type": "error",
"inputs": []
},
{
"name": "InvalidAmount",
"type": "error",
"inputs": []
},
{
"name": "InvalidManifest",
"type": "error",
"inputs": []
},
{
"name": "InvalidRound",
"type": "error",
"inputs": []
},
{
"name": "InvalidState",
"type": "error",
"inputs": []
},
{
"name": "InvalidWinner",
"type": "error",
"inputs": []
},
{
"name": "RandomnessUnavailable",
"type": "error",
"inputs": []
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "ReviewPeriodActive",
"type": "error",
"inputs": []
},
{
"name": "FuturePrizeConfigChanged",
"type": "event",
"inputs": [
{
"name": "winnerCount",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "prizeBps",
"type": "uint16[]",
"indexed": false,
"internalType": "uint16[]"
}
],
"anonymous": false
},
{
"name": "ManifestCommitted",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "snapshotBlock",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "eligibilityRoot",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
},
{
"name": "manifestHash",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
},
{
"name": "exclusionSetHash",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
},
{
"name": "eligibleWalletCount",
"type": "uint32",
"indexed": false,
"internalType": "uint32"
},
{
"name": "totalEntries",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Paused",
"type": "event",
"inputs": [
{
"name": "account",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "PrizeSettled",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "position",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "wallet",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "prize",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "RandomnessAdapterChanged",
"type": "event",
"inputs": [
{
"name": "previousAdapter",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "nextAdapter",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RandomnessRecorded",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "randomness",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "RandomnessRequested",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "requestId",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "adapter",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RoleAdminChanged",
"type": "event",
"inputs": [
{
"name": "role",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "previousAdminRole",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "newAdminRole",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "RoleGranted",
"type": "event",
"inputs": [
{
"name": "role",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RoleRevoked",
"type": "event",
"inputs": [
{
"name": "role",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RoundCompleted",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "RoundOpened",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "opensAt",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "closesAt",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "prizePool",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "minimumBalance",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "tokensPerEntry",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "winnerCount",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "prizeBps",
"type": "uint16[]",
"indexed": false,
"internalType": "uint16[]"
},
{
"name": "randomnessAdapter",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RoundPostponed",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "eligibleWalletCount",
"type": "uint32",
"indexed": false,
"internalType": "uint32"
},
{
"name": "rolledOver",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Unpaused",
"type": "event",
"inputs": [
{
"name": "account",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "WinnerFinalized",
"type": "event",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "position",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "wallet",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "ticket",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "prize",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "DEFAULT_ADMIN_ROLE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "MAX_WINNERS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "OPERATOR_ROLE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "PAUSER_ROLE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "ROUND_DURATION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "commitManifest",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "snapshotBlock",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "eligibilityRoot",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "manifestHash",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "exclusionSetHash",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "eligibleWalletCount",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "totalEntries",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "configuredPrizeBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16[]",
"internalType": "uint16[]"
}
],
"stateMutability": "view"
},
{
"name": "configuredWinnerCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "eligibilityLeaf",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "snapshotBlock",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "wallet",
"type": "address",
"internalType": "address"
},
{
"name": "snapshotBalance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "entries",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "firstTicket",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "exclusiveLastTicket",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "finalizeWinner",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "position",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "wallet",
"type": "address",
"internalType": "address"
},
{
"name": "snapshotBalance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "firstTicket",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "exclusiveLastTicket",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "proof",
"type": "bytes32[]",
"internalType": "bytes32[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "fundingFrozen",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "getRoleAdmin",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "grantRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "hasRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "manifestReviewPeriod",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "minimumBalance",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "minimumPrizePool",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "nextRoundId",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "openRound",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "prizePool",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "pause",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "paused",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "previewTicket",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "position",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "projectToken",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "randomnessAdapter",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IRandomnessAdapter"
}
],
"stateMutability": "view"
},
{
"name": "recordRandomness",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "value",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "nonpayable"
},
{
"name": "renounceRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "callerConfirmation",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "requestRandomness",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "requestId",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "nonpayable"
},
{
"name": "revokeRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "roundPrizeBps",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "rounds",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "opensAt",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "closesAt",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "snapshotBlock",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "manifestCommittedAt",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "minimumBalance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tokensPerEntry",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "totalEntries",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "prizePool",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "eligibilityRoot",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "manifestHash",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "exclusionSetHash",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "randomnessRequestId",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "randomnessAdapter",
"type": "address",
"internalType": "address"
},
{
"name": "eligibleWalletCount",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "winnerCount",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "status",
"type": "uint8",
"internalType": "enum LotteryEngine.Status"
}
],
"stateMutability": "view"
},
{
"name": "setFuturePrizeConfig",
"type": "function",
"inputs": [
{
"name": "winnerCount",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "prizeBps",
"type": "uint16[]",
"internalType": "uint16[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setRandomnessAdapter",
"type": "function",
"inputs": [
{
"name": "nextAdapter",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "settlePrize",
"type": "function",
"inputs": [
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "position",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "supportsInterface",
"type": "function",
"inputs": [
{
"name": "interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "tokensPerEntry",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "treasury",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract LotteryTreasury"
}
],
"stateMutability": "view"
},
{
"name": "unpause",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "winners",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "wallet",
"type": "address",
"internalType": "address"
},
{
"name": "snapshotBalance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "firstTicket",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "exclusiveLastTicket",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "selectedTicket",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "prize",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "paid",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
}
]0x6101406040523461042a57613d25610120813803918261001e8161042e565b93849283398101031261042a5761003481610453565b9061004160208201610453565b61004d60408301610453565b9061005a60608401610453565b61006660808501610453565b9061007360a08601610453565b9260c08601519461010060e08801519701519760018060401b038916808a0361042a57600160028190556005556001600160a01b038216158015610419575b8015610408575b80156103f7575b80156103e6575b80156103d5575b80156103cc575b6103bd5787159081156103b4575b5061027757610104926100f86100fe9261047b565b506104f1565b50610584565b5060018060a01b031660805260a05260018060a01b031660018060a01b031960035416176003558060c05260e0526101005261012052610144608061042e565b600381526020810190606036833780511561023b57611388825280516001101561023b57610bb8604082015280516002101561023b576107d060608201526003815103610277575f6004545f60045580610389575b505f5b60ff81169160038310156102865761ffff6101b78486610467565b5116156102775761ffff6101cb8486610467565b51168101809111610263576101e461ffff919385610467565b5116600454916801000000000000000083101561024f57600183018060045583101561023b5760ff9260019260045f5260205f208260041c019161ffff60f084549260041b1692831b921b1916179055011661019c565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b63162908e360e11b5f5260045ffd5b83612710869203610277576003805460ff60a01b1916600360a01b17815560408051918252602082018190529151918101829052606081019290915f5b81811061036f577f23152f873e4628b1e41643f494257c951daf2cbe6044d3051aac966350dcb53584860385a160405161368d90816106188239608051818181610be501528181610fcd01528181611cc701526130c8015260a0518181816124390152612d0e015260c0518181816102ee0152611381015260e0518181816101e20152610310015261010051818181610c5c015261281b015261012051818181611718015261190b0152f35b825161ffff168552602094850194909201916001016102c3565b60045f52600f60205f20910160041c8101905b8181106103a95750610199565b5f815560010161039c565b9050155f6100e3565b63e6c4247b60e01b5f5260045ffd5b50863b156100d5565b506001600160a01b038716156100ce565b506001600160a01b038616156100c7565b506001600160a01b038516156100c0565b506001600160a01b038316156100b9565b506001600160a01b038416156100b2565b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761024f57604052565b51906001600160a01b038216820361042a57565b805182101561023b5760209160051b010190565b6001600160a01b0381165f9081525f80516020613d05833981519152602052604090205460ff166104ec576001600160a01b03165f8181525f80516020613d0583398151915260205260408120805460ff191660011790553391905f80516020613ca58339815191528180a4600190565b505f90565b6001600160a01b0381165f9081525f80516020613ce5833981519152602052604090205460ff166104ec576001600160a01b03165f8181525f80516020613ce583398151915260205260408120805460ff191660011790553391907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929905f80516020613ca58339815191529080a4600190565b6001600160a01b0381165f9081525f80516020613cc5833981519152602052604090205460ff166104ec576001600160a01b03165f8181525f80516020613cc583398151915260205260408120805460ff191660011790553391907f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a905f80516020613ca58339815191529080a460019056fe6080806040526004361015610012575f80fd5b5f905f3560e01c90816301ffc9a714612ad157508063027b15211461283e5780631a3a3b1c14612804578063248a9ca3146127da578063249d39e9146127be57806329a62a76146127a45780632b801e14146127755780632f2ff15d14612738578063307515ac146126f957806336568abe1461268f578063394f1af61461265c5780633f4ba83a146125dd5780634002eda6146125c057806349afb803146125255780634ab3847f1461245d5780634b60ce771461240d5780634edde891146122bc57806353e410ff14611d0d5780635c975abb14611ceb57806361d027b314611c9b57806365fdc5e31461194b5780636641ea081461192f5780636ce09904146118eb5780637363ae1f146116c3578063785b1b43146116a057806382fcc4e6146116485780638456cb59146115725780638c65c81f1461145f57806391d14854146114095780639ac0b209146113be578063a217fddf146113a4578063b9d1d49b1461136a578063c6ca683d14611287578063ceb4740114610eb2578063d547741f14610e6b578063e562dfd91461027e578063e63ab1e914610243578063f5b541a6146102085763f9276640146101cb575f80fd5b3461020557806003193601126102055760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b80fd5b503461020557806003193601126102055760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b503461020557806003193601126102055760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b5034610205578060031936011261020557610297613281565b61029f613608565b80600554600181145f14610b61575067ffffffffffffffff4216905b600554916102c8836131ec565b60055560ff60035460a01c1690845b8260ff821610610a7557506102eb81612df9565b947f0000000000000000000000000000000000000000000000000000000000000000927f00000000000000000000000000000000000000000000000000000000000000009273ffffffffffffffffffffffffffffffffffffffff6003541660405190610200820182811067ffffffffffffffff821117610a485760405267ffffffffffffffff8084169a8b84521660208301528460408301528460608301528660808301528560a08301528460c08301528460e083015284610100830152846101208301528461014083015284610160830152610180820152836101a0820152826101c082015260016101e082015287845260066020526101e060096040862067ffffffffffffffff8451168154907fffffffffffffffffffffffffffffffff000000000000000000000000000000006fffffffffffffffff0000000000000000602088015160401b1692161717815561049767ffffffffffffffff60408601511682907fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff77ffffffffffffffff0000000000000000000000000000000083549260801b169116179055565b6060840151815477ffffffffffffffffffffffffffffffffffffffffffffffff1660c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000161781556080840151600182015560a0840151600282015560c0840151600382015560e084015160048201556101008401516005820155610120840151600682015561014084015160078201556101608401516008820155019173ffffffffffffffffffffffffffffffffffffffff8061018083015116167fffffffffffffffffffffffff00000000000000000000000000000000000000008454161783556105d763ffffffff6101a08301511684907fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff000000000000000000000000000000000000000083549260a01b169116179055565b6101c08101517fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff78ff00000000000000000000000000000000000000000000000085549260c01b16911617835501516009811015610a1b5781547fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff1660c89190911b79ff000000000000000000000000000000000000000000000000001617905561068190612df9565b9273ffffffffffffffffffffffffffffffffffffffff600354169467ffffffffffffffff6040519560e087019a87521660208601528360408601526060850152608084015260a083015260e060c0830152600454809652610100820195600482527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b81600f84011061093957926040977f594200c0636103be001d8d67da99a9a569f925e9d52b35ae191394a362b80d1393829389965491818110610924575b81811061090c575b8181106108f5575b8181106108dd575b8181106108c6575b8181106108ae575b818110610896575b81811061087e575b818110610866575b81811061084e575b818110610836575b81811061081e575b818110610806575b8181106107ee575b8181106107d6575b106107c8575b500390a382519182526020820152f35b60f01c81526020015f6107b8565b92602060019161ffff8560e01c1681520193016107b2565b92602060019161ffff8560d01c1681520193016107aa565b92602060019161ffff8560c01c1681520193016107a2565b92602060019161ffff8560b01c16815201930161079a565b92602060019161ffff8560a01c168152019301610792565b92602060019161ffff8560901c16815201930161078a565b92602060019161ffff8560801c168152019301610782565b92602060019161ffff8560701c16815201930161077a565b92602060019161ffff8560601c168152019301610772565b92602060019161ffff8560501c16815201930161076a565b92602060019161ffff858f1c168152019301610762565b92602060019161ffff8560301c16815201930161075a565b92602060019161ffff85831c168152019301610752565b92602060019161ffff8560101c16815201930161074a565b92602060019161ffff85168152019301610742565b9660016102006010928a5461ffff8116825261ffff81861c16602083015261ffff8160201c16604083015261ffff8160301c16606083015261ffff8160401c16608083015261ffff8160501c1660a083015261ffff8160601c1660c083015261ffff8160701c1660e083015261ffff8160801c1661010083015261ffff8160901c1661012083015261ffff8160a01c1661014083015261ffff8160b01c1661016083015261ffff8160c01c1661018083015261ffff8160d01c166101a083015261ffff8160e01c166101c083015260f01c6101e0820152019801920191610704565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b848652600960205260408620600454821015610b3457600480885282811c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b015482549184901b60f0161c61ffff169168010000000000000000821015610b075791610aeb826001948560ff9795018155612c44565b61ffff829392549160031b92831b921b191617905501166102d7565b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211610e3e57818352600660205260408320916009830160ff815460c81c166009811015610e1157600114801590610dfa575b610dd25767ffffffffffffffff845460401c16938573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166040517fac3b47ec000000000000000000000000000000000000000000000000000000008152602081600481855afa908115610dc7578391610d92575b50858352600760205260408320805460ff191660011790557f00000000000000000000000000000000000000000000000000000000000000001115610cfa575050507908000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790557fc4ba049834f47449d5b7abda8f9e818834d047a4fe480f083f66c4596099dc6660408051868152866020820152a26102bb565b919450926020925060249060405194859384927fd53b128600000000000000000000000000000000000000000000000000000000845260048401525af1908115610d87578491610d51575b506004819201556102bb565b90506020813d602011610d7f575b81610d6c60209383612c92565b81010312610d7b57515f610d45565b5f80fd5b3d9150610d5f565b6040513d86823e3d90fd5b9250506020823d602011610dbf575b81610dae60209383612c92565b81010312610d7b578791515f610c42565b3d9150610da1565b6040513d85823e3d90fd5b6004857fbaf3f0f7000000000000000000000000000000000000000000000000000000008152fd5b5067ffffffffffffffff845460401c164210610bb9565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b503461020557604060031936011261020557610eae600435610e8b612bb0565b90610ea9610ea4825f525f602052600160405f20015490565b613309565b613437565b5080f35b5034610d7b576040600319360112610d7b57600435610ecf612b6f565b91610ed8613608565b600280541461125f5760028055815f526006602052600960405f20019283549060ff8260c81c1660098110156112325760058114159081611226575b506111fe5760ff8091169160c01c168110156111c857825f52600860205260405f20815f5260205260405f209073ffffffffffffffffffffffffffffffffffffffff8254161580156111f0575b6111c85760068201600160ff198254161790557906000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff86541617855573ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8354169260058101938454833b15610d7b5760845f928360405196879485937f0bc6dec20000000000000000000000000000000000000000000000000000000085528d60048601528a6024860152604485015260648401525af19182156111bd5786926111a4575b50602073ffffffffffffffffffffffffffffffffffffffff7f9a1b93d55dff7a21676289a79ef040a5969fada1ab4529d96caea5b4058f18229254169454604051908152a48091815b818352600660205260ff600960408520015460c01c1660ff8216101561111a5781835260086020526040832060ff82165f5260205260ff600660405f20015416611103575b60010160ff166110b3565b92600161111160ff9261363c565b949150506110f8565b50838360ff80835460c01c16911614611137575b82600160025580f35b7907000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790557f0de73690a4c6b6fe902021c5ae286d7c66033d85adcc569a99a208e64864c2e78280a2818061112e565b5f9195506111b29250612c92565b5f928490602061106a565b6040513d5f823e3d90fd5b7f93a5f3c7000000000000000000000000000000000000000000000000000000005f5260045ffd5b5060ff600683015416610f61565b7fbaf3f0f7000000000000000000000000000000000000000000000000000000005f5260045ffd5b6006915014155f610f14565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f3ee5aeb5000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610d7b576020600319360112610d7b5760043573ffffffffffffffffffffffffffffffffffffffff811690818103610d7b576112c2613219565b8115908115611360575b50611338577fffffffffffffffffffffffff00000000000000000000000000000000000000006003548273ffffffffffffffffffffffffffffffffffffffff82167f6e03a35c0e0f70596c2fbc9a0ade97d9bf1db7cf0d6ec1a61debfcfad300a3505f80a31617600355005b7fe6c4247b000000000000000000000000000000000000000000000000000000005f5260045ffd5b90503b15826112cc565b34610d7b575f600319360112610d7b5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610d7b575f600319360112610d7b5760206040515f8152f35b34610d7b576040600319360112610d7b576024356004355f52600960205260405f20908154811015610d7b576113f961ffff91602093612c44565b90549060031b1c16604051908152f35b34610d7b576040600319360112610d7b57611422612bb0565b6004355f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060ff60405f2054166040519015158152f35b34610d7b576020600319360112610d7b576004355f52600660205260405f20805460ff6001830154926002810154906003810154600482015460058301546006840154916007850154936009600887015496015496888860c81c169a6040519a67ffffffffffffffff81168c5267ffffffffffffffff8160401c1660208d015267ffffffffffffffff8160801c1660408d015260c01c60608c015260808b015260a08a015260c089015260e088015261010087015261012086015261014085015261016084015273ffffffffffffffffffffffffffffffffffffffff811661018084015263ffffffff8160a01c166101a084015260c01c166101c0820152600982101561123257610200916101e0820152f35b34610d7b575f600319360112610d7b57335f9081527ff7c9542c591017a21c74b6f3fab6263c7952fc0aaf9db4c22a2a04ddc7f8674f602052604090205460ff16156115f8576115c0613608565b600160ff19815416176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b7fe2517d3f000000000000000000000000000000000000000000000000000000005f52336004527f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a60245260445ffd5b34610d7b5760e0600319360112610d7b57611661612bf6565b60a4359063ffffffff82168203610d7b5761169e9161167e613281565b611686613608565b60c43591608435906064359060443590600435612e1a565b005b34610d7b575f600319360112610d7b57602060ff60035460a01c16604051908152f35b34610d7b576020600319360112610d7b576004356116df613608565b805f52600660205260405f20906009820160ff815460c81c166009811015611232576002036111fe57825460c01c67ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000160167ffffffffffffffff81116118be5767ffffffffffffffff16908142106118965773ffffffffffffffffffffffffffffffffffffffff907903000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161781555416604051917ffb828e0900000000000000000000000000000000000000000000000000000000835283600484015260248301526020826044815f855af19182156111bd575f92611862575b50811561183a57816008602095015581604051937fa7ded6e5b345370b8080d61a2d03eefb7fa26aaaca189bd8aabe75f6344441385f80a48152f35b7fd58eba11000000000000000000000000000000000000000000000000000000005f5260045ffd5b9091506020813d60201161188e575b8161187e60209383612c92565b81010312610d7b575190846117fe565b3d9150611871565b7f56adf9ee000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b34610d7b575f600319360112610d7b57602060405167ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610d7b575f600319360112610d7b5760206040516103848152f35b34610d7b575f600319360112610d7b57604051806020600454928381520160045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b925f935b81600f860110611bb95791611a43948492611a2f945491818110611ba4575b818110611b8c575b818110611b75575b818110611b5d575b818110611b45575b818110611b2d575b818110611b15575b818110611afd575b818110611ae5575b818110611acd575b818110611ab5575b818110611a9d575b818110611a85575b818110611a6d575b818110611a55575b10611a47575b500382612c92565b604051918291602083526020830190612c0d565b0390f35b60f01c815260200185611a27565b92602060019161ffff8560e01c168152019301611a21565b92602060019161ffff8560d01c168152019301611a19565b92602060019161ffff8560c01c168152019301611a11565b92602060019161ffff8560b01c168152019301611a09565b92602060019161ffff8560a01c168152019301611a01565b92602060019161ffff8560901c1681520193016119f9565b92602060019161ffff8560801c1681520193016119f1565b92602060019161ffff8560701c1681520193016119e9565b92602060019161ffff8560601c1681520193016119e1565b92602060019161ffff8560501c1681520193016119d9565b92602060019161ffff8560401c1681520193016119d1565b92602060019161ffff8560301c1681520193016119c9565b92602060019161ffff85831c1681520193016119c1565b92602060019161ffff8560101c1681520193016119b9565b92602060019161ffff851681520193016119b1565b916001610200601092855461ffff8116825261ffff81861c16602083015261ffff8160201c16604083015261ffff8160301c16606083015261ffff8160401c16608083015261ffff8160501c1660a083015261ffff8160601c1660c083015261ffff8160701c1660e083015261ffff8160801c1661010083015261ffff8160901c1661012083015261ffff8160a01c1661014083015261ffff8160b01c1661016083015261ffff8160c01c1661018083015261ffff8160d01c166101a083015261ffff8160e01c166101c083015260f01c6101e0820152019301940193611992565b34610d7b575f600319360112610d7b57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610d7b575f600319360112610d7b57602060ff600154166040519015158152f35b34610d7b5760e0600319360112610d7b57600435611d29612b6f565b90611d32612bd3565b91606435916084359160a4359460c43567ffffffffffffffff8111610d7b57611d5f903690600401612b7f565b959093611d6a613608565b805f52600660205260405f2095600987019889549760ff8960c81c166009811015611232576004036111fe5760ff8960c01c169060ff881697828910801590612229575b801561220b575b6111c857600282015480156121de5787046001830154881080156121d6575b80156121cc575b80156121b9575b80156121ac575b6111c8579a611e0c85878f9e8b8d67ffffffffffffffff895460801c168d612cd3565b6005840154905f9d8e5b1015611e54578d60051b8d0135908181105f14611e43575f52602052600160405f205b9d019c8e8e611e16565b905f52602052600160405f20611e39565b8f9c50036111c857604073ffffffffffffffffffffffffffffffffffffffff9160248251809481937f1b1d5b270000000000000000000000000000000000000000000000000000000083528c6004840152165afa80156111bd57611ec7915f9161217b575b5060038401549083896134e1565b928584108015612171575b6111c85773ffffffffffffffffffffffffffffffffffffffff5f9916985b8a60ff8216106121305750611f0660ff91612dbb565b1689036120ef57505f905f5b8960ff8216106120bc5750906004611f2b920154612dae565b6040519560e0870187811067ffffffffffffffff82111761208f5789977fd131b124175534f8c8bfdd7d94d6db7698ca2a7ae4c03545a802de2f5ac65ce59660409660069388528b83526020830194855287830191825260608301908152608083019087825260a084019287845260c08501965f88528c5f5260086020528d8b5f20905f5260205273ffffffffffffffffffffffffffffffffffffffff808c5f20975116167fffffffffffffffffffffffff0000000000000000000000000000000000000000875416178655516001860155516002850155516003840155516004830155516005820155019051151560ff60ff19835416911617905582519182526020820152a460ff61204381845460c01c16612dbb565b161461204b57005b80547fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff16790500000000000000000000000000000000000000000000000000179055005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b9160016120e760ff92895f52600860205260405f208487165f52602052600560405f20015490612dec565b930116611f12565b9061210d600461ffff92015492875f52600960205260405f20612c44565b90549060031b1c16908181029181830414901517156118be576127109004611f2b565b875f52600860205260405f2060ff82165f526020528973ffffffffffffffffffffffffffffffffffffffff60405f205416146111c85760010160ff16611ef0565b5084841015611ed2565b61219d915060403d6040116121a5575b6121958183612c92565b810190612d8e565b90508c611eb9565b503d61218b565b5060038301548511611de9565b50806121c58787612dae565b1415611de2565b5085851115611ddb565b508015611dd4565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5073ffffffffffffffffffffffffffffffffffffffff881615611db5565b509a999897969594939291905f5b855f52600660205260ff600960405f20015460c01c1660ff82161080612284575b1561226b576122669061363c565b612237565b60ff909c9192939495969798999a9b9c16891415611dae565b50855f52600860205260405f2060ff82165f5260205273ffffffffffffffffffffffffffffffffffffffff60405f2054161515612258565b34610d7b576020600319360112610d7b576004356122d8613608565b805f526006602052600960405f20019081549060ff8260c81c166009811015611232576003036111fe57604073ffffffffffffffffffffffffffffffffffffffff9260248251809581937f1b1d5b27000000000000000000000000000000000000000000000000000000008352866004840152165afa9182156111bd575f905f936123e9575b501580156123e1575b61183a576020927904000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790557f5bbc1faa290e6f965e63afbc2da8c6088fa598d6447a0f57885f88f6c8707ecc83604051848152a2604051908152f35b508115612367565b905061240591925060403d6040116121a5576121958183612c92565b91908461235e565b34610d7b575f600319360112610d7b57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610d7b576040600319360112610d7b57600435602461247b612b6f565b91805f52600660205260405f2092604073ffffffffffffffffffffffffffffffffffffffff6009860154168151948580927f1b1d5b270000000000000000000000000000000000000000000000000000000082528660048301525afa9081156111bd576020946124f7945f936124ff575b5060030154926134e1565b604051908152f35b600391935061251c9060403d6040116121a5576121958183612c92565b905092906124ec565b34610d7b576040600319360112610d7b5761253e612b6f565b6004355f52600860205260ff60405f2091165f5260205260e060405f2073ffffffffffffffffffffffffffffffffffffffff815416906001810154906002810154600382015460048301549160ff600660058601549501541694604051968752602087015260408601526060850152608084015260a0830152151560c0820152f35b34610d7b575f600319360112610d7b576020600554604051908152f35b34610d7b575f600319360112610d7b576125f5613219565b60015460ff8116156126345760ff19166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b7f8dfc202b000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610d7b575f600319360112610d7b57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b34610d7b576040600319360112610d7b576126a8612bb0565b3373ffffffffffffffffffffffffffffffffffffffff8216036126d15761169e90600435613437565b7f6697b232000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610d7b5760e0600319360112610d7b5760206124f7612717612bf6565b61271f612bd3565b9060c4359160a435916084359160643591600435612cd3565b34610d7b576040600319360112610d7b5761169e600435612757612bb0565b90612770610ea4825f525f602052600160405f20015490565b613383565b34610d7b576020600319360112610d7b576004355f526007602052602060ff60405f2054166040519015158152f35b34610d7b575f600319360112610d7b576020604051818152f35b34610d7b575f600319360112610d7b5760206040516127108152f35b34610d7b576020600319360112610d7b5760206124f76004355f525f602052600160405f20015490565b34610d7b575f600319360112610d7b5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610d7b576040600319360112610d7b5760043560ff8116808203610d7b5760243567ffffffffffffffff8111610d7b5761287d903690600401612b7f565b9190612887613219565b67ffffffffffffffff831161208f578260051b90604051936128ac6020840186612c92565b84526020840191810190368211610d7b57915b818310612ab65750505080158015612aac575b8015612aa1575b61297e575f906004545f60045580612a3a575b505f5b60ff811692828410156129a65761ffff612909858761336f565b51161561297e5761293461292d61ffff9283612925888a61336f565b511690612dec565b948661336f565b511690600454906801000000000000000082101561208f5760ff926129628360018095016004556004612c44565b61ffff829392549160031b92831b921b191617905501166128ef565b7f2c5211c6000000000000000000000000000000000000000000000000000000005f5260045ffd5b848361271088930361297e577f23152f873e4628b1e41643f494257c951daf2cbe6044d3051aac966350dcb535927fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000006003549260a01b16911617600355612a356040519283928352604060208401526040830190612c0d565b0390a1005b600f9060045f520160041c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b017f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b818110612a9657506128ec565b5f8155600101612a89565b5080825114156128d9565b50602081116128d2565b823561ffff81168103610d7b578152602092830192016128bf565b34610d7b576020600319360112610d7b57600435907fffffffff000000000000000000000000000000000000000000000000000000008216809203610d7b57817f7965db0b0000000000000000000000000000000000000000000000000000000060209314908115612b45575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483612b3e565b6024359060ff82168203610d7b57565b9181601f84011215610d7b5782359167ffffffffffffffff8311610d7b576020808501948460051b010111610d7b57565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203610d7b57565b6044359073ffffffffffffffffffffffffffffffffffffffff82168203610d7b57565b6024359067ffffffffffffffff82168203610d7b57565b90602080835192838152019201905f5b818110612c2a5750505090565b825161ffff16845260209384019390920191600101612c1d565b9190918054831015612c65575f52601e60205f208360041c019260011b1690565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761208f57604052565b95939173ffffffffffffffffffffffffffffffffffffffff909593919567ffffffffffffffff604051976020890199468b523060408b0152847f00000000000000000000000000000000000000000000000000000000000000001660608b015260808a01521660a08801521660c086015260e08501526101008401526101208301526101408201526101408152612d6c61016082612c92565b5190206040516020810191825260208152612d88604082612c92565b51902090565b9190826040910312610d7b5781518015158103610d7b5760209092015190565b919082039182116118be57565b60ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9116019060ff82116118be57565b919082018092116118be57565b67ffffffffffffffff6103849116019067ffffffffffffffff82116118be57565b949593855f52600660205260405f20600981019760ff895460c81c166009811015611232576001148015906131d5575b6111fe57875f52600760205260ff60405f205416156111fe5767ffffffffffffffff841692831580156131cc575b80156131c4575b80156131bc575b80156131b4575b80156131a5575b61317d5788967f84af10d1629ced0c0308081340d732b986389816d9c4fa86e7a05530e72b05cc96612fc385612f75868f612f1a60c09c63ffffffff9b907fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff77ffffffffffffffff0000000000000000000000000000000083549260801b169116179055565b856005850155866006850155876007850155907fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff000000000000000000000000000000000000000083549260a01b169116179055565b600381018c9055805477ffffffffffffffffffffffffffffffffffffffffffffffff164260c01b7fffffffffffffffff00000000000000000000000000000000000000000000000016179055565b604051958652602086015260408501526060840152169485608083015260a0820152a260ff835460c01c16811061303a5750507902000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff825416179055565b90917908000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790556040517f53900a2f0000000000000000000000000000000000000000000000000000000081528260048201526020816024815f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af19081156111bd575f9161312b575b507fc4ba049834f47449d5b7abda8f9e818834d047a4fe480f083f66c4596099dc669160409182519182526020820152a2565b90506020813d602011613175575b8161314660209383612c92565b81010312610d7b57517fc4ba049834f47449d5b7abda8f9e818834d047a4fe480f083f66c4596099dc666130f8565b3d9150613139565b7fe18d5d12000000000000000000000000000000000000000000000000000000005f5260045ffd5b5063ffffffff82168810612e94565b508015612e8d565b508615612e86565b508515612e7f565b50438411612e78565b5067ffffffffffffffff825460401c164210612e4a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118be5760010190565b335f9081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff161561325157565b7fe2517d3f000000000000000000000000000000000000000000000000000000005f52336004525f60245260445ffd5b335f9081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f602052604090205460ff16156132b957565b7fe2517d3f000000000000000000000000000000000000000000000000000000005f52336004527f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92960245260445ffd5b805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff33165f5260205260ff60405f205416156133405750565b7fe2517d3f000000000000000000000000000000000000000000000000000000005f523360045260245260445ffd5b8051821015612c655760209160051b010190565b805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260ff60405f205416155f1461343157805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260405f20600160ff1982541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4600190565b50505f90565b805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260ff60405f2054165f1461343157805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260405f2060ff19815416905573ffffffffffffffffffffffffffffffffffffffff339216907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b5f80a4600190565b90919283158015613600575b61183a575f5b6040516020810186815284604083015260ff8616918260608201528360808201526080815261352360a082612c92565b5190208361353381805f0361364d565b82905f5b8183106135c557505061354a925061364d565b905f905f5b8160ff821610613573575b50501561356a57506001016134f3565b94505050505090565b865f52600860205260405f2060ff82165f5260205260405f20600281015485101590816135b7575b506135ab5760010160ff1661354f565b50505060015f8061355a565b60039150015484105f61359b565b9092506135d291506131ec565b916040516020810190828252846040820152604081526135f3606082612c92565b5190209092869290613537565b5080156134ed565b60ff6001541661361457565b7fd93c0665000000000000000000000000000000000000000000000000000000005f5260045ffd5b60ff1660ff81146118be5760010190565b81156121de57069056fea26469706673582212202bc5911991870ee862aeaa11c0460cfa4ac4009a5c3af6713448045a8e5fbd0264736f6c634300081a00332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0df7c9542c591017a21c74b6f3fab6263c7952fc0aaf9db4c22a2a04ddc7f8674fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5000000000000000000000000fcab387420c2493ff7737e072c712028c3b91553000000000000000000000000fcab387420c2493ff7737e072c712028c3b9155300000000000000000000000044c2d01b4d6e1e0718582cb1d1da72864ad36264000000000000000000000000e0c08825c59563d2c9f367c0de7e2388bbd83cf0000000000000000000000000e5b521f8474a22d84cb4d162966b3e4f559aaf700000000000000000000000008680c48ad89228c4ee485c597816b0da01c5aecf000000000000000000000000000000000000000000002a5a058fc295ed0000000000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000003c
0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816301ffc9a714612ad157508063027b15211461283e5780631a3a3b1c14612804578063248a9ca3146127da578063249d39e9146127be57806329a62a76146127a45780632b801e14146127755780632f2ff15d14612738578063307515ac146126f957806336568abe1461268f578063394f1af61461265c5780633f4ba83a146125dd5780634002eda6146125c057806349afb803146125255780634ab3847f1461245d5780634b60ce771461240d5780634edde891146122bc57806353e410ff14611d0d5780635c975abb14611ceb57806361d027b314611c9b57806365fdc5e31461194b5780636641ea081461192f5780636ce09904146118eb5780637363ae1f146116c3578063785b1b43146116a057806382fcc4e6146116485780638456cb59146115725780638c65c81f1461145f57806391d14854146114095780639ac0b209146113be578063a217fddf146113a4578063b9d1d49b1461136a578063c6ca683d14611287578063ceb4740114610eb2578063d547741f14610e6b578063e562dfd91461027e578063e63ab1e914610243578063f5b541a6146102085763f9276640146101cb575f80fd5b3461020557806003193601126102055760206040517f000000000000000000000000000000000000000000002a5a058fc295ed0000008152f35b80fd5b503461020557806003193601126102055760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b503461020557806003193601126102055760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b5034610205578060031936011261020557610297613281565b61029f613608565b80600554600181145f14610b61575067ffffffffffffffff4216905b600554916102c8836131ec565b60055560ff60035460a01c1690845b8260ff821610610a7557506102eb81612df9565b947f000000000000000000000000000000000000000000002a5a058fc295ed000000927f000000000000000000000000000000000000000000002a5a058fc295ed0000009273ffffffffffffffffffffffffffffffffffffffff6003541660405190610200820182811067ffffffffffffffff821117610a485760405267ffffffffffffffff8084169a8b84521660208301528460408301528460608301528660808301528560a08301528460c08301528460e083015284610100830152846101208301528461014083015284610160830152610180820152836101a0820152826101c082015260016101e082015287845260066020526101e060096040862067ffffffffffffffff8451168154907fffffffffffffffffffffffffffffffff000000000000000000000000000000006fffffffffffffffff0000000000000000602088015160401b1692161717815561049767ffffffffffffffff60408601511682907fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff77ffffffffffffffff0000000000000000000000000000000083549260801b169116179055565b6060840151815477ffffffffffffffffffffffffffffffffffffffffffffffff1660c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000161781556080840151600182015560a0840151600282015560c0840151600382015560e084015160048201556101008401516005820155610120840151600682015561014084015160078201556101608401516008820155019173ffffffffffffffffffffffffffffffffffffffff8061018083015116167fffffffffffffffffffffffff00000000000000000000000000000000000000008454161783556105d763ffffffff6101a08301511684907fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff000000000000000000000000000000000000000083549260a01b169116179055565b6101c08101517fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff78ff00000000000000000000000000000000000000000000000085549260c01b16911617835501516009811015610a1b5781547fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff1660c89190911b79ff000000000000000000000000000000000000000000000000001617905561068190612df9565b9273ffffffffffffffffffffffffffffffffffffffff600354169467ffffffffffffffff6040519560e087019a87521660208601528360408601526060850152608084015260a083015260e060c0830152600454809652610100820195600482527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b81600f84011061093957926040977f594200c0636103be001d8d67da99a9a569f925e9d52b35ae191394a362b80d1393829389965491818110610924575b81811061090c575b8181106108f5575b8181106108dd575b8181106108c6575b8181106108ae575b818110610896575b81811061087e575b818110610866575b81811061084e575b818110610836575b81811061081e575b818110610806575b8181106107ee575b8181106107d6575b106107c8575b500390a382519182526020820152f35b60f01c81526020015f6107b8565b92602060019161ffff8560e01c1681520193016107b2565b92602060019161ffff8560d01c1681520193016107aa565b92602060019161ffff8560c01c1681520193016107a2565b92602060019161ffff8560b01c16815201930161079a565b92602060019161ffff8560a01c168152019301610792565b92602060019161ffff8560901c16815201930161078a565b92602060019161ffff8560801c168152019301610782565b92602060019161ffff8560701c16815201930161077a565b92602060019161ffff8560601c168152019301610772565b92602060019161ffff8560501c16815201930161076a565b92602060019161ffff858f1c168152019301610762565b92602060019161ffff8560301c16815201930161075a565b92602060019161ffff85831c168152019301610752565b92602060019161ffff8560101c16815201930161074a565b92602060019161ffff85168152019301610742565b9660016102006010928a5461ffff8116825261ffff81861c16602083015261ffff8160201c16604083015261ffff8160301c16606083015261ffff8160401c16608083015261ffff8160501c1660a083015261ffff8160601c1660c083015261ffff8160701c1660e083015261ffff8160801c1661010083015261ffff8160901c1661012083015261ffff8160a01c1661014083015261ffff8160b01c1661016083015261ffff8160c01c1661018083015261ffff8160d01c166101a083015261ffff8160e01c166101c083015260f01c6101e0820152019801920191610704565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b848652600960205260408620600454821015610b3457600480885282811c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b015482549184901b60f0161c61ffff169168010000000000000000821015610b075791610aeb826001948560ff9795018155612c44565b61ffff829392549160031b92831b921b191617905501166102d7565b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211610e3e57818352600660205260408320916009830160ff815460c81c166009811015610e1157600114801590610dfa575b610dd25767ffffffffffffffff845460401c16938573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e0c08825c59563d2c9f367c0de7e2388bbd83cf0166040517fac3b47ec000000000000000000000000000000000000000000000000000000008152602081600481855afa908115610dc7578391610d92575b50858352600760205260408320805460ff191660011790557f0000000000000000000000000000000000000000000000000001c6bf526340001115610cfa575050507908000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790557fc4ba049834f47449d5b7abda8f9e818834d047a4fe480f083f66c4596099dc6660408051868152866020820152a26102bb565b919450926020925060249060405194859384927fd53b128600000000000000000000000000000000000000000000000000000000845260048401525af1908115610d87578491610d51575b506004819201556102bb565b90506020813d602011610d7f575b81610d6c60209383612c92565b81010312610d7b57515f610d45565b5f80fd5b3d9150610d5f565b6040513d86823e3d90fd5b9250506020823d602011610dbf575b81610dae60209383612c92565b81010312610d7b578791515f610c42565b3d9150610da1565b6040513d85823e3d90fd5b6004857fbaf3f0f7000000000000000000000000000000000000000000000000000000008152fd5b5067ffffffffffffffff845460401c164210610bb9565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b503461020557604060031936011261020557610eae600435610e8b612bb0565b90610ea9610ea4825f525f602052600160405f20015490565b613309565b613437565b5080f35b5034610d7b576040600319360112610d7b57600435610ecf612b6f565b91610ed8613608565b600280541461125f5760028055815f526006602052600960405f20019283549060ff8260c81c1660098110156112325760058114159081611226575b506111fe5760ff8091169160c01c168110156111c857825f52600860205260405f20815f5260205260405f209073ffffffffffffffffffffffffffffffffffffffff8254161580156111f0575b6111c85760068201600160ff198254161790557906000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff86541617855573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e0c08825c59563d2c9f367c0de7e2388bbd83cf01673ffffffffffffffffffffffffffffffffffffffff8354169260058101938454833b15610d7b5760845f928360405196879485937f0bc6dec20000000000000000000000000000000000000000000000000000000085528d60048601528a6024860152604485015260648401525af19182156111bd5786926111a4575b50602073ffffffffffffffffffffffffffffffffffffffff7f9a1b93d55dff7a21676289a79ef040a5969fada1ab4529d96caea5b4058f18229254169454604051908152a48091815b818352600660205260ff600960408520015460c01c1660ff8216101561111a5781835260086020526040832060ff82165f5260205260ff600660405f20015416611103575b60010160ff166110b3565b92600161111160ff9261363c565b949150506110f8565b50838360ff80835460c01c16911614611137575b82600160025580f35b7907000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790557f0de73690a4c6b6fe902021c5ae286d7c66033d85adcc569a99a208e64864c2e78280a2818061112e565b5f9195506111b29250612c92565b5f928490602061106a565b6040513d5f823e3d90fd5b7f93a5f3c7000000000000000000000000000000000000000000000000000000005f5260045ffd5b5060ff600683015416610f61565b7fbaf3f0f7000000000000000000000000000000000000000000000000000000005f5260045ffd5b6006915014155f610f14565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f3ee5aeb5000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610d7b576020600319360112610d7b5760043573ffffffffffffffffffffffffffffffffffffffff811690818103610d7b576112c2613219565b8115908115611360575b50611338577fffffffffffffffffffffffff00000000000000000000000000000000000000006003548273ffffffffffffffffffffffffffffffffffffffff82167f6e03a35c0e0f70596c2fbc9a0ade97d9bf1db7cf0d6ec1a61debfcfad300a3505f80a31617600355005b7fe6c4247b000000000000000000000000000000000000000000000000000000005f5260045ffd5b90503b15826112cc565b34610d7b575f600319360112610d7b5760206040517f000000000000000000000000000000000000000000002a5a058fc295ed0000008152f35b34610d7b575f600319360112610d7b5760206040515f8152f35b34610d7b576040600319360112610d7b576024356004355f52600960205260405f20908154811015610d7b576113f961ffff91602093612c44565b90549060031b1c16604051908152f35b34610d7b576040600319360112610d7b57611422612bb0565b6004355f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060ff60405f2054166040519015158152f35b34610d7b576020600319360112610d7b576004355f52600660205260405f20805460ff6001830154926002810154906003810154600482015460058301546006840154916007850154936009600887015496015496888860c81c169a6040519a67ffffffffffffffff81168c5267ffffffffffffffff8160401c1660208d015267ffffffffffffffff8160801c1660408d015260c01c60608c015260808b015260a08a015260c089015260e088015261010087015261012086015261014085015261016084015273ffffffffffffffffffffffffffffffffffffffff811661018084015263ffffffff8160a01c166101a084015260c01c166101c0820152600982101561123257610200916101e0820152f35b34610d7b575f600319360112610d7b57335f9081527ff7c9542c591017a21c74b6f3fab6263c7952fc0aaf9db4c22a2a04ddc7f8674f602052604090205460ff16156115f8576115c0613608565b600160ff19815416176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b7fe2517d3f000000000000000000000000000000000000000000000000000000005f52336004527f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a60245260445ffd5b34610d7b5760e0600319360112610d7b57611661612bf6565b60a4359063ffffffff82168203610d7b5761169e9161167e613281565b611686613608565b60c43591608435906064359060443590600435612e1a565b005b34610d7b575f600319360112610d7b57602060ff60035460a01c16604051908152f35b34610d7b576020600319360112610d7b576004356116df613608565b805f52600660205260405f20906009820160ff815460c81c166009811015611232576002036111fe57825460c01c67ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000003c160167ffffffffffffffff81116118be5767ffffffffffffffff16908142106118965773ffffffffffffffffffffffffffffffffffffffff907903000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161781555416604051917ffb828e0900000000000000000000000000000000000000000000000000000000835283600484015260248301526020826044815f855af19182156111bd575f92611862575b50811561183a57816008602095015581604051937fa7ded6e5b345370b8080d61a2d03eefb7fa26aaaca189bd8aabe75f6344441385f80a48152f35b7fd58eba11000000000000000000000000000000000000000000000000000000005f5260045ffd5b9091506020813d60201161188e575b8161187e60209383612c92565b81010312610d7b575190846117fe565b3d9150611871565b7f56adf9ee000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b34610d7b575f600319360112610d7b57602060405167ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000003c168152f35b34610d7b575f600319360112610d7b5760206040516103848152f35b34610d7b575f600319360112610d7b57604051806020600454928381520160045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b925f935b81600f860110611bb95791611a43948492611a2f945491818110611ba4575b818110611b8c575b818110611b75575b818110611b5d575b818110611b45575b818110611b2d575b818110611b15575b818110611afd575b818110611ae5575b818110611acd575b818110611ab5575b818110611a9d575b818110611a85575b818110611a6d575b818110611a55575b10611a47575b500382612c92565b604051918291602083526020830190612c0d565b0390f35b60f01c815260200185611a27565b92602060019161ffff8560e01c168152019301611a21565b92602060019161ffff8560d01c168152019301611a19565b92602060019161ffff8560c01c168152019301611a11565b92602060019161ffff8560b01c168152019301611a09565b92602060019161ffff8560a01c168152019301611a01565b92602060019161ffff8560901c1681520193016119f9565b92602060019161ffff8560801c1681520193016119f1565b92602060019161ffff8560701c1681520193016119e9565b92602060019161ffff8560601c1681520193016119e1565b92602060019161ffff8560501c1681520193016119d9565b92602060019161ffff8560401c1681520193016119d1565b92602060019161ffff8560301c1681520193016119c9565b92602060019161ffff85831c1681520193016119c1565b92602060019161ffff8560101c1681520193016119b9565b92602060019161ffff851681520193016119b1565b916001610200601092855461ffff8116825261ffff81861c16602083015261ffff8160201c16604083015261ffff8160301c16606083015261ffff8160401c16608083015261ffff8160501c1660a083015261ffff8160601c1660c083015261ffff8160701c1660e083015261ffff8160801c1661010083015261ffff8160901c1661012083015261ffff8160a01c1661014083015261ffff8160b01c1661016083015261ffff8160c01c1661018083015261ffff8160d01c166101a083015261ffff8160e01c166101c083015260f01c6101e0820152019301940193611992565b34610d7b575f600319360112610d7b57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e0c08825c59563d2c9f367c0de7e2388bbd83cf0168152f35b34610d7b575f600319360112610d7b57602060ff600154166040519015158152f35b34610d7b5760e0600319360112610d7b57600435611d29612b6f565b90611d32612bd3565b91606435916084359160a4359460c43567ffffffffffffffff8111610d7b57611d5f903690600401612b7f565b959093611d6a613608565b805f52600660205260405f2095600987019889549760ff8960c81c166009811015611232576004036111fe5760ff8960c01c169060ff881697828910801590612229575b801561220b575b6111c857600282015480156121de5787046001830154881080156121d6575b80156121cc575b80156121b9575b80156121ac575b6111c8579a611e0c85878f9e8b8d67ffffffffffffffff895460801c168d612cd3565b6005840154905f9d8e5b1015611e54578d60051b8d0135908181105f14611e43575f52602052600160405f205b9d019c8e8e611e16565b905f52602052600160405f20611e39565b8f9c50036111c857604073ffffffffffffffffffffffffffffffffffffffff9160248251809481937f1b1d5b270000000000000000000000000000000000000000000000000000000083528c6004840152165afa80156111bd57611ec7915f9161217b575b5060038401549083896134e1565b928584108015612171575b6111c85773ffffffffffffffffffffffffffffffffffffffff5f9916985b8a60ff8216106121305750611f0660ff91612dbb565b1689036120ef57505f905f5b8960ff8216106120bc5750906004611f2b920154612dae565b6040519560e0870187811067ffffffffffffffff82111761208f5789977fd131b124175534f8c8bfdd7d94d6db7698ca2a7ae4c03545a802de2f5ac65ce59660409660069388528b83526020830194855287830191825260608301908152608083019087825260a084019287845260c08501965f88528c5f5260086020528d8b5f20905f5260205273ffffffffffffffffffffffffffffffffffffffff808c5f20975116167fffffffffffffffffffffffff0000000000000000000000000000000000000000875416178655516001860155516002850155516003840155516004830155516005820155019051151560ff60ff19835416911617905582519182526020820152a460ff61204381845460c01c16612dbb565b161461204b57005b80547fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff16790500000000000000000000000000000000000000000000000000179055005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b9160016120e760ff92895f52600860205260405f208487165f52602052600560405f20015490612dec565b930116611f12565b9061210d600461ffff92015492875f52600960205260405f20612c44565b90549060031b1c16908181029181830414901517156118be576127109004611f2b565b875f52600860205260405f2060ff82165f526020528973ffffffffffffffffffffffffffffffffffffffff60405f205416146111c85760010160ff16611ef0565b5084841015611ed2565b61219d915060403d6040116121a5575b6121958183612c92565b810190612d8e565b90508c611eb9565b503d61218b565b5060038301548511611de9565b50806121c58787612dae565b1415611de2565b5085851115611ddb565b508015611dd4565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5073ffffffffffffffffffffffffffffffffffffffff881615611db5565b509a999897969594939291905f5b855f52600660205260ff600960405f20015460c01c1660ff82161080612284575b1561226b576122669061363c565b612237565b60ff909c9192939495969798999a9b9c16891415611dae565b50855f52600860205260405f2060ff82165f5260205273ffffffffffffffffffffffffffffffffffffffff60405f2054161515612258565b34610d7b576020600319360112610d7b576004356122d8613608565b805f526006602052600960405f20019081549060ff8260c81c166009811015611232576003036111fe57604073ffffffffffffffffffffffffffffffffffffffff9260248251809581937f1b1d5b27000000000000000000000000000000000000000000000000000000008352866004840152165afa9182156111bd575f905f936123e9575b501580156123e1575b61183a576020927904000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790557f5bbc1faa290e6f965e63afbc2da8c6088fa598d6447a0f57885f88f6c8707ecc83604051848152a2604051908152f35b508115612367565b905061240591925060403d6040116121a5576121958183612c92565b91908461235e565b34610d7b575f600319360112610d7b57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e5b521f8474a22d84cb4d162966b3e4f559aaf70168152f35b34610d7b576040600319360112610d7b57600435602461247b612b6f565b91805f52600660205260405f2092604073ffffffffffffffffffffffffffffffffffffffff6009860154168151948580927f1b1d5b270000000000000000000000000000000000000000000000000000000082528660048301525afa9081156111bd576020946124f7945f936124ff575b5060030154926134e1565b604051908152f35b600391935061251c9060403d6040116121a5576121958183612c92565b905092906124ec565b34610d7b576040600319360112610d7b5761253e612b6f565b6004355f52600860205260ff60405f2091165f5260205260e060405f2073ffffffffffffffffffffffffffffffffffffffff815416906001810154906002810154600382015460048301549160ff600660058601549501541694604051968752602087015260408601526060850152608084015260a0830152151560c0820152f35b34610d7b575f600319360112610d7b576020600554604051908152f35b34610d7b575f600319360112610d7b576125f5613219565b60015460ff8116156126345760ff19166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b7f8dfc202b000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610d7b575f600319360112610d7b57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b34610d7b576040600319360112610d7b576126a8612bb0565b3373ffffffffffffffffffffffffffffffffffffffff8216036126d15761169e90600435613437565b7f6697b232000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610d7b5760e0600319360112610d7b5760206124f7612717612bf6565b61271f612bd3565b9060c4359160a435916084359160643591600435612cd3565b34610d7b576040600319360112610d7b5761169e600435612757612bb0565b90612770610ea4825f525f602052600160405f20015490565b613383565b34610d7b576020600319360112610d7b576004355f526007602052602060ff60405f2054166040519015158152f35b34610d7b575f600319360112610d7b576020604051818152f35b34610d7b575f600319360112610d7b5760206040516127108152f35b34610d7b576020600319360112610d7b5760206124f76004355f525f602052600160405f20015490565b34610d7b575f600319360112610d7b5760206040517f0000000000000000000000000000000000000000000000000001c6bf526340008152f35b34610d7b576040600319360112610d7b5760043560ff8116808203610d7b5760243567ffffffffffffffff8111610d7b5761287d903690600401612b7f565b9190612887613219565b67ffffffffffffffff831161208f578260051b90604051936128ac6020840186612c92565b84526020840191810190368211610d7b57915b818310612ab65750505080158015612aac575b8015612aa1575b61297e575f906004545f60045580612a3a575b505f5b60ff811692828410156129a65761ffff612909858761336f565b51161561297e5761293461292d61ffff9283612925888a61336f565b511690612dec565b948661336f565b511690600454906801000000000000000082101561208f5760ff926129628360018095016004556004612c44565b61ffff829392549160031b92831b921b191617905501166128ef565b7f2c5211c6000000000000000000000000000000000000000000000000000000005f5260045ffd5b848361271088930361297e577f23152f873e4628b1e41643f494257c951daf2cbe6044d3051aac966350dcb535927fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000006003549260a01b16911617600355612a356040519283928352604060208401526040830190612c0d565b0390a1005b600f9060045f520160041c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b017f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b818110612a9657506128ec565b5f8155600101612a89565b5080825114156128d9565b50602081116128d2565b823561ffff81168103610d7b578152602092830192016128bf565b34610d7b576020600319360112610d7b57600435907fffffffff000000000000000000000000000000000000000000000000000000008216809203610d7b57817f7965db0b0000000000000000000000000000000000000000000000000000000060209314908115612b45575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483612b3e565b6024359060ff82168203610d7b57565b9181601f84011215610d7b5782359167ffffffffffffffff8311610d7b576020808501948460051b010111610d7b57565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203610d7b57565b6044359073ffffffffffffffffffffffffffffffffffffffff82168203610d7b57565b6024359067ffffffffffffffff82168203610d7b57565b90602080835192838152019201905f5b818110612c2a5750505090565b825161ffff16845260209384019390920191600101612c1d565b9190918054831015612c65575f52601e60205f208360041c019260011b1690565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761208f57604052565b95939173ffffffffffffffffffffffffffffffffffffffff909593919567ffffffffffffffff604051976020890199468b523060408b0152847f000000000000000000000000e5b521f8474a22d84cb4d162966b3e4f559aaf701660608b015260808a01521660a08801521660c086015260e08501526101008401526101208301526101408201526101408152612d6c61016082612c92565b5190206040516020810191825260208152612d88604082612c92565b51902090565b9190826040910312610d7b5781518015158103610d7b5760209092015190565b919082039182116118be57565b60ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9116019060ff82116118be57565b919082018092116118be57565b67ffffffffffffffff6103849116019067ffffffffffffffff82116118be57565b949593855f52600660205260405f20600981019760ff895460c81c166009811015611232576001148015906131d5575b6111fe57875f52600760205260ff60405f205416156111fe5767ffffffffffffffff841692831580156131cc575b80156131c4575b80156131bc575b80156131b4575b80156131a5575b61317d5788967f84af10d1629ced0c0308081340d732b986389816d9c4fa86e7a05530e72b05cc96612fc385612f75868f612f1a60c09c63ffffffff9b907fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff77ffffffffffffffff0000000000000000000000000000000083549260801b169116179055565b856005850155866006850155876007850155907fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff000000000000000000000000000000000000000083549260a01b169116179055565b600381018c9055805477ffffffffffffffffffffffffffffffffffffffffffffffff164260c01b7fffffffffffffffff00000000000000000000000000000000000000000000000016179055565b604051958652602086015260408501526060840152169485608083015260a0820152a260ff835460c01c16811061303a5750507902000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff825416179055565b90917908000000000000000000000000000000000000000000000000007fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff8254161790556040517f53900a2f0000000000000000000000000000000000000000000000000000000081528260048201526020816024815f73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e0c08825c59563d2c9f367c0de7e2388bbd83cf0165af19081156111bd575f9161312b575b507fc4ba049834f47449d5b7abda8f9e818834d047a4fe480f083f66c4596099dc669160409182519182526020820152a2565b90506020813d602011613175575b8161314660209383612c92565b81010312610d7b57517fc4ba049834f47449d5b7abda8f9e818834d047a4fe480f083f66c4596099dc666130f8565b3d9150613139565b7fe18d5d12000000000000000000000000000000000000000000000000000000005f5260045ffd5b5063ffffffff82168810612e94565b508015612e8d565b508615612e86565b508515612e7f565b50438411612e78565b5067ffffffffffffffff825460401c164210612e4a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118be5760010190565b335f9081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff161561325157565b7fe2517d3f000000000000000000000000000000000000000000000000000000005f52336004525f60245260445ffd5b335f9081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f602052604090205460ff16156132b957565b7fe2517d3f000000000000000000000000000000000000000000000000000000005f52336004527f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92960245260445ffd5b805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff33165f5260205260ff60405f205416156133405750565b7fe2517d3f000000000000000000000000000000000000000000000000000000005f523360045260245260445ffd5b8051821015612c655760209160051b010190565b805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260ff60405f205416155f1461343157805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260405f20600160ff1982541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4600190565b50505f90565b805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260ff60405f2054165f1461343157805f525f60205260405f2073ffffffffffffffffffffffffffffffffffffffff83165f5260205260405f2060ff19815416905573ffffffffffffffffffffffffffffffffffffffff339216907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b5f80a4600190565b90919283158015613600575b61183a575f5b6040516020810186815284604083015260ff8616918260608201528360808201526080815261352360a082612c92565b5190208361353381805f0361364d565b82905f5b8183106135c557505061354a925061364d565b905f905f5b8160ff821610613573575b50501561356a57506001016134f3565b94505050505090565b865f52600860205260405f2060ff82165f5260205260405f20600281015485101590816135b7575b506135ab5760010160ff1661354f565b50505060015f8061355a565b60039150015484105f61359b565b9092506135d291506131ec565b916040516020810190828252846040820152604081526135f3606082612c92565b5190209092869290613537565b5080156134ed565b60ff6001541661361457565b7fd93c0665000000000000000000000000000000000000000000000000000000005f5260045ffd5b60ff1660ff81146118be5760010190565b81156121de57069056fea26469706673582212202bc5911991870ee862aeaa11c0460cfa4ac4009a5c3af6713448045a8e5fbd0264736f6c634300081a0033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x1940a2…d0143d | 21 days agoMon, 27 Jul 2026 19:04:22 UTC | 0x0de736…c2e7 | [0] 0x000000000000…00000001 |
| 0x1940a2…d0143d | 21 days agoMon, 27 Jul 2026 19:04:22 UTC | 0x9a1b93…1822 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000002 [2] 0x000000000000…f672db11 data: 0x000000000000000000…20f48000 |
| 0xdbff76…68466c | 21 days agoMon, 27 Jul 2026 19:04:05 UTC | 0x9a1b93…1822 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000001 [2] 0x000000000000…18d61b1e data: 0x000000000000000000…316ec000 |
| 0xfe6e4a…5bcb46 | 21 days agoMon, 27 Jul 2026 19:03:48 UTC | 0x9a1b93…1822 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000000 [2] 0x000000000000…e04a2be1 data: 0x000000000000000000…52634000 |
| 0x99e423…6db9b4 | 21 days agoMon, 27 Jul 2026 19:03:32 UTC | 0xd131b1…5ce5 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000002 [2] 0x000000000000…f672db11 data: 0x000000000000000000…20f48000 |
| 0xf09578…8b5274 | 21 days agoMon, 27 Jul 2026 19:03:15 UTC | 0xd131b1…5ce5 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000001 [2] 0x000000000000…18d61b1e data: 0x000000000000000000…316ec000 |
| 0x4f6a9d…e9729d | 21 days agoMon, 27 Jul 2026 19:02:58 UTC | 0xd131b1…5ce5 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000000 [2] 0x000000000000…e04a2be1 data: 0x000000000000000000…52634000 |
| 0xe4e189…9c598d | 21 days agoMon, 27 Jul 2026 19:02:42 UTC | 0x5bbc1f…7ecc | [0] 0x000000000000…00000001 data: 0xd6bb865e5ac502fceb…7ecb38b1 |
| 0x204b04…344d36 | 21 days agoMon, 27 Jul 2026 19:01:36 UTC | 0xa7ded6…4138 | [0] 0x000000000000…00000001 [1] 0xb48fd593184e…152283b5 [2] 0x000000000000…01c5aecf |
| 0x133902…f7063d | 21 days agoMon, 27 Jul 2026 19:00:25 UTC | 0x84af10…05cc | [0] 0x000000000000…00000001 data: 0x000000000000000000…0000001c |
| 0xa5c9da…3cfa97 | 21 days agoMon, 27 Jul 2026 19:00:19 UTC | 0x594200…0d13 | [0] 0x000000000000…00000002 [1] 0x000000000000…01c5aecf data: 0x000000000000000000…000007d0 |
| 0xd449e2…2c1d89 | 21 days agoMon, 27 Jul 2026 18:45:09 UTC | 0x594200…0d13 | [0] 0x000000000000…00000001 [1] 0x000000000000…01c5aecf data: 0x000000000000000000…000007d0 |
| 0xa9cd25…4fb0de | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0xf6391f…171b | [0] 0x000000000000…00000000 [1] 0x000000000000…c3b91553 [2] 0x000000000000…c3b91553 |
| 0x61e1d0…02e9ac | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0x2f8788…6f0d | [0] 0x000000000000…00000000 [1] 0x000000000000…4ad36264 [2] 0x000000000000…c3b91553 |
| 0x704f85…6fa4cd | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0x23152f…b535 | data: 0x000000000000000000…000007d0 |
| 0x704f85…6fa4cd | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0x2f8788…6f0d | [0] 0x65d7a28e3265…440d862a [1] 0x000000000000…4ad36264 [2] 0x000000000000…c3b91553 |
| 0x704f85…6fa4cd | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0x2f8788…6f0d | [0] 0x97667070c54e…4fa9b929 [1] 0x000000000000…c3b91553 [2] 0x000000000000…c3b91553 |
| 0x704f85…6fa4cd | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0x2f8788…6f0d | [0] 0x000000000000…00000000 [1] 0x000000000000…c3b91553 [2] 0x000000000000…c3b91553 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x1940a2…d0143d | settlePrize | 20,967,817 | 21 days agoMon, 27 Jul 2026 19:04:22 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000448 | |
| 0xdbff76…68466c | settlePrize | 20,967,653 | 21 days agoMon, 27 Jul 2026 19:04:05 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000482 | |
| 0xfe6e4a…5bcb46 | settlePrize | 20,967,484 | 21 days agoMon, 27 Jul 2026 19:03:48 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000427 | |
| 0x99e423…6db9b4 | finalizeWinner | 20,967,323 | 21 days agoMon, 27 Jul 2026 19:03:32 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000784 | |
| 0xf09578…8b5274 | finalizeWinner | 20,967,153 | 21 days agoMon, 27 Jul 2026 19:03:15 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000764 | |
| 0x4f6a9d…e9729d | finalizeWinner | 20,966,974 | 21 days agoMon, 27 Jul 2026 19:02:58 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000736 | |
| 0xe4e189…9c598d | recordRandomness | 20,966,818 | 21 days agoMon, 27 Jul 2026 19:02:42 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000144 | |
| 0x204b04…344d36 | requestRandomness | 20,966,160 | 21 days agoMon, 27 Jul 2026 19:01:36 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000419 | |
| 0x133902…f7063d | commitManifest | 20,965,457 | 21 days agoMon, 27 Jul 2026 19:00:25 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000514 | |
| 0xa5c9da…3cfa97 | openRound | 20,965,401 | 21 days agoMon, 27 Jul 2026 19:00:19 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00001134 | |
| 0xd449e2…2c1d89 | openRound | 20,956,325 | 21 days agoMon, 27 Jul 2026 18:45:09 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000808 | |
| 0xa9cd25…4fb0de | renounceRole | 20,956,014 | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000093 | |
| 0x61e1d0…02e9ac | grantRole | 20,956,014 | 21 days agoMon, 27 Jul 2026 18:44:38 UTC | 0xfcab…1553 | IN | LotteryEngine | $0.000 ETH | 0.00000192 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||