// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {IPriceOracle} from "./interfaces/IPriceOracle.sol";
import {IVerifierProxy} from "./streams/IVerifierProxy.sol";
import {StreamsLib} from "./streams/StreamsLib.sol";
/// @title RoundArena — continuous pooled price rounds
/// @notice A market is a pair (oracle, duration) running an unbroken chain of
/// rounds. Closing a round reads the oracle once and that same price
/// also opens the next round, so rounds keep turning with no players
/// and no counterparty. Anyone backs UP or DOWN with any amount; the
/// winning side splits the losing pool.
///
/// @dev Non-custodial in the same sense as OracleDuel: the contract only ever
/// holds the current rounds' pools plus unclaimed winnings, and no owner
/// function can move player funds. Payouts are pull-based so gas never
/// scales with the number of winners.
contract RoundArena is Ownable2Step, ReentrancyGuard {
// --- constants (hardcoded ceilings; see security notes) ---
uint16 public constant MAX_RAKE_BPS = 500;
uint16 public constant KEEPER_BPS = 50; // 0.5% of the losing pool
uint256 public constant STALENESS_WINDOW = 30 minutes;
uint256 public constant REFUND_GRACE = 24 hours;
uint32 public constant MIN_DURATION = 60;
uint32 public constant MAX_DURATION = 7 days;
uint16 public rakeBps = 300; // 3% of the losing pool
enum RoundStatus {
None,
Running,
Settled,
Refunded
}
struct Market {
address oracle;
uint32 duration;
uint96 minBet;
uint96 maxBet;
bool enabled;
}
/// @notice Data Streams config for a market, kept in its own mapping (not
/// appended to Market) so the existing `markets(uint256)` getter's
/// return tuple never changes shape for off-chain callers already
/// decoding it (web, indexer, keeper). Set only for streams markets;
/// `oracle` on the Market itself is address(0) for those.
struct StreamsConfig {
address verifierProxy;
bytes32 feedId; // must match the report's feedId — stops a valid report for a DIFFERENT asset from settling this market
bool marketMustBeOpen; // true for RWA/stock feeds (V8 schema), false for crypto (V3)
}
struct Round {
uint64 openTime;
uint64 closeTime;
int256 openPrice;
int256 closePrice;
uint128 upPool;
uint128 downPool;
RoundStatus status;
bool upWon;
/// @dev The rake actually skimmed when this round settled. Payouts must
/// be computed from THIS, never from the live `rakeBps`: the ETH
/// backing a settled round was already reduced by the rate in
/// force at that moment, so re-reading a later rate would either
/// strand winners' funds (rake raised) or promise more than the
/// round retained, paid out of other rounds' pools (rake lowered).
/// Packs into the same slot as status/upWon — no extra storage.
uint16 settledRakeBps;
}
struct Position {
uint128 up;
uint128 down;
bool claimed;
}
Market[] public markets;
/// @notice marketId => its Data Streams config, if it has one (see StreamsConfig).
mapping(uint256 => StreamsConfig) public streamsConfig;
/// @notice marketId => true if this market is settled by a keeper-submitted
/// price (turnWithPrice) rather than an on-chain oracle (turn) or a
/// Data Streams report (turnWithReport). Keeper markets carry no
/// oracle contract at all — the price arrives in the turn tx itself,
/// which is the cheapest path: one tx per round, no separate
/// setPrice, no oracle deployment. The keeper is the trusted price
/// source here (same trust as pushing to a settable oracle), so
/// only `priceSubmitter` may call it.
mapping(uint256 => bool) public keeperPriced;
/// @notice The one address allowed to submit prices via turnWithPrice.
address public priceSubmitter;
/// @notice marketId => id of the round currently accepting bets (0 = none yet).
mapping(uint256 => uint256) public currentRound;
mapping(uint256 => mapping(uint256 => Round)) private _rounds;
mapping(uint256 => mapping(uint256 => mapping(address => Position))) private _positions;
/// @notice Payouts that could not be pushed are parked here.
mapping(address => uint256) public pendingWithdrawals;
// --- events ---
event MarketAdded(uint256 indexed marketId, address oracle, uint32 duration, uint96 minBet, uint96 maxBet);
event StreamsMarketAdded(uint256 indexed marketId, address verifierProxy, bytes32 feedId, uint32 duration);
event KeeperMarketAdded(uint256 indexed marketId, uint32 duration, uint96 minBet, uint96 maxBet);
event PriceSubmitterUpdated(address indexed priceSubmitter);
event MarketEnabled(uint256 indexed marketId, bool enabled);
event MarketLimitsUpdated(uint256 indexed marketId, uint96 minBet, uint96 maxBet);
event RoundOpened(uint256 indexed marketId, uint256 indexed roundId, int256 openPrice, uint64 closeTime);
event BetPlaced(uint256 indexed marketId, uint256 indexed roundId, address indexed player, bool up, uint256 amount);
event RoundSettled(
uint256 indexed marketId,
uint256 indexed roundId,
int256 closePrice,
bool upWon,
uint256 winningPool,
uint256 losingPool,
uint256 rake
);
event RoundRefunded(uint256 indexed marketId, uint256 indexed roundId, string reason);
event Claimed(uint256 indexed marketId, uint256 indexed roundId, address indexed player, uint256 amount);
event RakeUpdated(uint16 rakeBps);
event PayoutQueued(address indexed to, uint256 amount);
event Withdrawn(address indexed to, uint256 amount);
// --- errors ---
error UnknownMarket();
error MarketDisabled();
error InvalidDuration();
error InvalidLimits();
error ZeroAddress();
error RakeTooHigh();
error NoRound();
error RoundClosed();
error BetOutOfBounds();
error NotDue();
error StalePrice();
error InvalidPrice();
error NothingToClaim();
error AlreadyClaimed();
error RoundNotFinished();
error GraceNotOver();
error TransferFailed();
error ReportRequired(); // this market needs turnWithReport(), not turn()
error ReportNotAccepted(); // this market needs turn(), not turnWithReport()
error FeedMismatch(); // the verified report's feedId does not match this market's
error PriceRequired(); // this market needs turnWithPrice(), not turn()
error PriceNotAccepted(); // this market is not keeper-priced
error NotPriceSubmitter(); // only the configured keeper may submit prices
constructor() Ownable(msg.sender) {}
// --- owner: market configuration only; never player funds ---
function addMarket(
address oracle,
uint32 duration,
uint96 minBet,
uint96 maxBet
) external onlyOwner returns (uint256 marketId) {
if (oracle == address(0)) revert ZeroAddress();
if (duration < MIN_DURATION || duration > MAX_DURATION) revert InvalidDuration();
if (minBet == 0 || maxBet < minBet) revert InvalidLimits();
marketId = markets.length;
markets.push(
Market({oracle: oracle, duration: duration, minBet: minBet, maxBet: maxBet, enabled: true})
);
emit MarketAdded(marketId, oracle, duration, minBet, maxBet);
}
/// @notice Adds a market settled by Chainlink Data Streams instead of a
/// plain oracle. Its Market.oracle is address(0); turn() rejects it
/// and turnWithReport() must be used instead.
function addStreamsMarket(
address verifierProxy,
bytes32 feedId,
bool marketMustBeOpen,
uint32 duration,
uint96 minBet,
uint96 maxBet
) external onlyOwner returns (uint256 marketId) {
if (verifierProxy == address(0) || feedId == bytes32(0)) revert ZeroAddress();
if (duration < MIN_DURATION || duration > MAX_DURATION) revert InvalidDuration();
if (minBet == 0 || maxBet < minBet) revert InvalidLimits();
marketId = markets.length;
markets.push(
Market({oracle: address(0), duration: duration, minBet: minBet, maxBet: maxBet, enabled: true})
);
streamsConfig[marketId] = StreamsConfig({
verifierProxy: verifierProxy,
feedId: feedId,
marketMustBeOpen: marketMustBeOpen
});
emit StreamsMarketAdded(marketId, verifierProxy, feedId, duration);
}
/// @notice Adds a keeper-priced market: the cheapest path. It carries no
/// oracle contract; the price arrives inside each turnWithPrice() tx
/// (one tx per round, no separate setPrice, no oracle to deploy).
/// turn()/turnWithReport() reject it. A priceSubmitter must be set
/// before it can be turned.
function addKeeperMarket(
uint32 duration,
uint96 minBet,
uint96 maxBet
) external onlyOwner returns (uint256 marketId) {
if (duration < MIN_DURATION || duration > MAX_DURATION) revert InvalidDuration();
if (minBet == 0 || maxBet < minBet) revert InvalidLimits();
marketId = markets.length;
markets.push(
Market({oracle: address(0), duration: duration, minBet: minBet, maxBet: maxBet, enabled: true})
);
keeperPriced[marketId] = true;
emit KeeperMarketAdded(marketId, duration, minBet, maxBet);
}
/// @notice Set the sole address permitted to submit prices via turnWithPrice.
function setPriceSubmitter(address newSubmitter) external onlyOwner {
priceSubmitter = newSubmitter;
emit PriceSubmitterUpdated(newSubmitter);
}
function setMarketEnabled(uint256 marketId, bool enabled) external onlyOwner {
_market(marketId).enabled = enabled;
emit MarketEnabled(marketId, enabled);
}
function setMarketLimits(uint256 marketId, uint96 minBet, uint96 maxBet) external onlyOwner {
if (minBet == 0 || maxBet < minBet) revert InvalidLimits();
Market storage m = _market(marketId);
m.minBet = minBet;
m.maxBet = maxBet;
emit MarketLimitsUpdated(marketId, minBet, maxBet);
}
function setRake(uint16 newRakeBps) external onlyOwner {
if (newRakeBps > MAX_RAKE_BPS) revert RakeTooHigh();
rakeBps = newRakeBps;
emit RakeUpdated(newRakeBps);
}
// --- the engine ---
/// @notice Closes the due round and opens the next one from the same price.
/// Anyone may call; the caller earns KEEPER_BPS of the losing pool.
/// This is the only action needed to keep a market alive, and it
/// needs no players. Oracle-based markets only — a market added via
/// addStreamsMarket must use turnWithReport() instead.
function turn(uint256 marketId) external nonReentrant {
Market storage m = _market(marketId);
if (!m.enabled) revert MarketDisabled();
if (streamsConfig[marketId].verifierProxy != address(0)) revert ReportRequired();
if (keeperPriced[marketId]) revert PriceRequired();
(int256 price, ) = _readFresh(m.oracle);
_turnCore(marketId, m, price);
}
/// @notice Turn a keeper-priced market with a price supplied by the trusted
/// priceSubmitter. This is the cheap fast-market path: one tx per
/// round, price carried in the call, no oracle read and no separate
/// setPrice. The submitter is trusted exactly as a settable oracle's
/// writer would be; off-chain it bounds this price against multiple
/// exchanges and a Chainlink Data Feed before sending.
function turnWithPrice(uint256 marketId, int256 price) external nonReentrant {
if (msg.sender != priceSubmitter) revert NotPriceSubmitter();
Market storage m = _market(marketId);
if (!m.enabled) revert MarketDisabled();
if (!keeperPriced[marketId]) revert PriceNotAccepted();
if (price <= 0) revert InvalidPrice();
_turnCore(marketId, m, price);
}
/// @notice Same as turn(), but for a market added via addStreamsMarket: the
/// caller supplies a Chainlink Data Streams report (fetched off-chain
/// from the Data Streams API) instead of the contract reading an
/// oracle. The report is verified on-chain (DON signature check) and
/// its feedId is checked against the market's configured feed, so a
/// valid report for a different asset cannot be used to settle this
/// one. Reverts if the report's observation is outside the same
/// staleness window the oracle path enforces.
function turnWithReport(uint256 marketId, bytes calldata report) external nonReentrant {
Market storage m = _market(marketId);
if (!m.enabled) revert MarketDisabled();
StreamsConfig storage sc = streamsConfig[marketId];
if (sc.verifierProxy == address(0)) revert ReportNotAccepted();
(bytes32 feedId, int256 price, uint256 observedAt) = StreamsLib.verifyAndDecode(
IVerifierProxy(sc.verifierProxy),
report,
sc.marketMustBeOpen
);
if (feedId != sc.feedId) revert FeedMismatch();
if (observedAt > block.timestamp || block.timestamp - observedAt > STALENESS_WINDOW) {
revert StalePrice();
}
_turnCore(marketId, m, price);
}
/// @dev Shared open/close bookkeeping for both turn() and turnWithReport(),
/// so the two price sources can never diverge in how a round is run.
function _turnCore(uint256 marketId, Market storage m, int256 price) private {
uint256 cur = currentRound[marketId];
if (cur != 0) {
Round storage round = _rounds[marketId][cur];
if (block.timestamp < round.closeTime) revert NotDue();
// Only a still-running round is decided here. A round already
// resolved by refundStuckRound() must be left exactly as it is:
// settling it a second time would re-price refunds as wins and
// losses and pay a second time out of a pool that has already
// been partly refunded. We simply open the next round instead,
// so a market that was rescued mid-outage resumes cleanly.
if (round.status == RoundStatus.Running) {
_settle(marketId, cur, round, price);
}
}
uint256 next = cur + 1;
currentRound[marketId] = next;
uint64 closeTime = uint64(block.timestamp) + m.duration;
_rounds[marketId][next] = Round({
openTime: uint64(block.timestamp),
closeTime: closeTime,
openPrice: price,
closePrice: 0,
upPool: 0,
downPool: 0,
status: RoundStatus.Running,
upWon: false,
settledRakeBps: 0 // set when the round actually settles
});
emit RoundOpened(marketId, next, price, closeTime);
}
/// @dev Decides a round and pays the rake and keeper fee out of the losing
/// pool. A tie or an empty side refunds everyone and takes no rake.
function _settle(uint256 marketId, uint256 roundId, Round storage round, int256 closePrice) private {
round.closePrice = closePrice;
bool up = closePrice > round.openPrice;
uint256 winning = up ? round.upPool : round.downPool;
uint256 losing = up ? round.downPool : round.upPool;
if (closePrice == round.openPrice) {
round.status = RoundStatus.Refunded;
emit RoundRefunded(marketId, roundId, "tie");
return;
}
if (winning == 0 || losing == 0) {
// Nobody to pay, or nobody to pay from: return every stake untouched.
round.status = RoundStatus.Refunded;
emit RoundRefunded(marketId, roundId, "one-sided");
return;
}
round.status = RoundStatus.Settled;
round.upWon = up;
// Freeze the rate this round was actually skimmed at (see Round.settledRakeBps).
uint16 rakeAtSettlement = rakeBps;
round.settledRakeBps = rakeAtSettlement;
uint256 rake = (losing * rakeAtSettlement) / 10000;
uint256 keeperFee = (losing * KEEPER_BPS) / 10000;
emit RoundSettled(marketId, roundId, closePrice, up, winning, losing, rake);
_pay(owner(), rake); // no treasury: the rake goes straight to the owner
_pay(msg.sender, keeperFee);
}
/// @notice Back UP or DOWN on the round currently accepting bets.
/// @dev Betting stays open until the round closes. This is a deliberate
/// owner decision: it favours late entrants, who have already seen the
/// price move. Live odds are surfaced in the interface so the dilution
/// is at least visible.
function bet(uint256 marketId, bool up) external payable nonReentrant {
Market storage m = _market(marketId);
if (!m.enabled) revert MarketDisabled();
uint256 roundId = currentRound[marketId];
if (roundId == 0) revert NoRound();
Round storage round = _rounds[marketId][roundId];
if (round.status != RoundStatus.Running || block.timestamp >= round.closeTime) revert RoundClosed();
if (msg.value < m.minBet || msg.value > m.maxBet) revert BetOutOfBounds();
Position storage pos = _positions[marketId][roundId][msg.sender];
if (up) {
round.upPool += uint128(msg.value);
pos.up += uint128(msg.value);
} else {
round.downPool += uint128(msg.value);
pos.down += uint128(msg.value);
}
emit BetPlaced(marketId, roundId, msg.sender, up, msg.value);
}
/// @notice Collect winnings, or a refund, for a finished round.
function claim(uint256 marketId, uint256 roundId) public nonReentrant {
uint256 amount = _collect(marketId, roundId, msg.sender);
_pay(msg.sender, amount);
emit Claimed(marketId, roundId, msg.sender, amount);
}
/// @notice Collect across several finished rounds in one transaction.
function claimMany(uint256 marketId, uint256[] calldata roundIds) external nonReentrant {
uint256 total;
for (uint256 i = 0; i < roundIds.length; i++) {
uint256 amount = _collect(marketId, roundIds[i], msg.sender);
total += amount;
emit Claimed(marketId, roundIds[i], msg.sender, amount);
}
_pay(msg.sender, total);
}
function _collect(uint256 marketId, uint256 roundId, address player) private returns (uint256) {
Round storage round = _rounds[marketId][roundId];
if (round.status != RoundStatus.Settled && round.status != RoundStatus.Refunded) {
revert RoundNotFinished();
}
Position storage pos = _positions[marketId][roundId][player];
if (pos.claimed) revert AlreadyClaimed();
uint256 amount = _payoutOf(round, pos);
if (amount == 0) revert NothingToClaim();
pos.claimed = true;
return amount;
}
/// @dev A refunded round returns both stakes; a settled round returns the
/// winning stake plus its share of what is left of the losing pool.
function _payoutOf(Round storage round, Position storage pos) private view returns (uint256) {
if (round.status == RoundStatus.Refunded) {
return uint256(pos.up) + uint256(pos.down);
}
uint256 stake = round.upWon ? pos.up : pos.down;
if (stake == 0) return 0;
uint256 winning = round.upWon ? round.upPool : round.downPool;
uint256 losing = round.upWon ? round.downPool : round.upPool;
// settledRakeBps, not the live rakeBps — a later setRake() must never
// reprice a round whose ETH was already skimmed at the old rate.
uint256 distributable = losing -
(losing * round.settledRakeBps) /
10000 -
(losing * KEEPER_BPS) /
10000;
return stake + (distributable * stake) / winning;
}
/// @notice Refund a round that could not be settled long after it closed
/// (a broken or permanently stale oracle). Anyone may call.
function refundStuckRound(uint256 marketId) external nonReentrant {
uint256 roundId = currentRound[marketId];
if (roundId == 0) revert NoRound();
Round storage round = _rounds[marketId][roundId];
if (round.status != RoundStatus.Running) revert RoundNotFinished();
if (block.timestamp <= uint256(round.closeTime) + REFUND_GRACE) revert GraceNotOver();
// Keeper- and streams-priced markets carry no on-chain oracle to
// consult (oracle == address(0)); for them, "still Running past the
// grace period" is itself the stuck condition (the keeper stopped), so
// the refund proceeds. Only an oracle market can be checked for a still
// -fresh feed, in which case turn() is the correct path, not a refund.
address oracle = _market(marketId).oracle;
if (oracle != address(0)) {
// `updatedAt` is bounded first: a feed reporting a FUTURE timestamp
// would otherwise underflow and revert here, trapping both stakes in
// the round this function exists to rescue. A future stamp counts as
// not-fresh, so the refund proceeds — funds never hinge on a broken feed.
try IPriceOracle(oracle).readPrice() returns (int256 p, uint256 updatedAt) {
if (p > 0 && updatedAt <= block.timestamp && block.timestamp - updatedAt <= STALENESS_WINDOW) {
revert NotDue();
}
} catch {}
}
round.status = RoundStatus.Refunded;
emit RoundRefunded(marketId, roundId, "stuck");
}
/// @notice Pull a payout that could not be pushed to you.
function withdraw() external nonReentrant {
uint256 amount = pendingWithdrawals[msg.sender];
if (amount == 0) revert NothingToClaim();
pendingWithdrawals[msg.sender] = 0;
(bool ok, ) = msg.sender.call{value: amount}("");
if (!ok) revert TransferFailed();
emit Withdrawn(msg.sender, amount);
}
// --- views ---
function marketCount() external view returns (uint256) {
return markets.length;
}
function getRound(uint256 marketId, uint256 roundId) external view returns (Round memory) {
return _rounds[marketId][roundId];
}
function getPosition(
uint256 marketId,
uint256 roundId,
address player
) external view returns (Position memory) {
return _positions[marketId][roundId][player];
}
/// @notice What `player` would receive for a finished round right now.
function payoutFor(uint256 marketId, uint256 roundId, address player) external view returns (uint256) {
Round storage round = _rounds[marketId][roundId];
Position storage pos = _positions[marketId][roundId][player];
if (pos.claimed) return 0;
if (round.status != RoundStatus.Settled && round.status != RoundStatus.Refunded) return 0;
return _payoutOf(round, pos);
}
// --- internals ---
function _market(uint256 marketId) private view returns (Market storage) {
if (marketId >= markets.length) revert UnknownMarket();
return markets[marketId];
}
function _readFresh(address oracle) private view returns (int256 price, uint256 updatedAt) {
(price, updatedAt) = IPriceOracle(oracle).readPrice();
if (price <= 0) revert InvalidPrice();
if (updatedAt > block.timestamp || block.timestamp - updatedAt > STALENESS_WINDOW) {
revert StalePrice();
}
}
/// @dev Push payment with a pull fallback, so a reverting recipient can
/// never block a settlement or strand anyone else's funds.
function _pay(address to, uint256 amount) private {
if (amount == 0) return;
(bool ok, ) = to.call{value: amount}("");
if (!ok) {
pendingWithdrawals[to] += amount;
emit PayoutQueued(to, amount);
}
}
}[
{
"type": "constructor",
"inputs": [],
"stateMutability": "nonpayable"
},
{
"name": "AlreadyClaimed",
"type": "error",
"inputs": []
},
{
"name": "BetOutOfBounds",
"type": "error",
"inputs": []
},
{
"name": "EmptyReport",
"type": "error",
"inputs": []
},
{
"name": "FeedMismatch",
"type": "error",
"inputs": []
},
{
"name": "GraceNotOver",
"type": "error",
"inputs": []
},
{
"name": "InvalidDuration",
"type": "error",
"inputs": []
},
{
"name": "InvalidLimits",
"type": "error",
"inputs": []
},
{
"name": "InvalidPrice",
"type": "error",
"inputs": []
},
{
"name": "MarketClosed",
"type": "error",
"inputs": []
},
{
"name": "MarketDisabled",
"type": "error",
"inputs": []
},
{
"name": "NoRound",
"type": "error",
"inputs": []
},
{
"name": "NonPositivePrice",
"type": "error",
"inputs": []
},
{
"name": "NotDue",
"type": "error",
"inputs": []
},
{
"name": "NotPriceSubmitter",
"type": "error",
"inputs": []
},
{
"name": "NothingToClaim",
"type": "error",
"inputs": []
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "PriceNotAccepted",
"type": "error",
"inputs": []
},
{
"name": "PriceRequired",
"type": "error",
"inputs": []
},
{
"name": "RakeTooHigh",
"type": "error",
"inputs": []
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "ReportNotAccepted",
"type": "error",
"inputs": []
},
{
"name": "ReportRequired",
"type": "error",
"inputs": []
},
{
"name": "RoundClosed",
"type": "error",
"inputs": []
},
{
"name": "RoundNotFinished",
"type": "error",
"inputs": []
},
{
"name": "StalePrice",
"type": "error",
"inputs": []
},
{
"name": "TransferFailed",
"type": "error",
"inputs": []
},
{
"name": "UnknownMarket",
"type": "error",
"inputs": []
},
{
"name": "UnsupportedSchema",
"type": "error",
"inputs": [
{
"name": "version",
"type": "uint16",
"internalType": "uint16"
}
]
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "BetPlaced",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "player",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "up",
"type": "bool",
"indexed": false,
"internalType": "bool"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Claimed",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "player",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "KeeperMarketAdded",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "duration",
"type": "uint32",
"indexed": false,
"internalType": "uint32"
},
{
"name": "minBet",
"type": "uint96",
"indexed": false,
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"indexed": false,
"internalType": "uint96"
}
],
"anonymous": false
},
{
"name": "MarketAdded",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "oracle",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "duration",
"type": "uint32",
"indexed": false,
"internalType": "uint32"
},
{
"name": "minBet",
"type": "uint96",
"indexed": false,
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"indexed": false,
"internalType": "uint96"
}
],
"anonymous": false
},
{
"name": "MarketEnabled",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "enabled",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "MarketLimitsUpdated",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "minBet",
"type": "uint96",
"indexed": false,
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"indexed": false,
"internalType": "uint96"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferStarted",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "PayoutQueued",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "PriceSubmitterUpdated",
"type": "event",
"inputs": [
{
"name": "priceSubmitter",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RakeUpdated",
"type": "event",
"inputs": [
{
"name": "rakeBps",
"type": "uint16",
"indexed": false,
"internalType": "uint16"
}
],
"anonymous": false
},
{
"name": "RoundOpened",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "openPrice",
"type": "int256",
"indexed": false,
"internalType": "int256"
},
{
"name": "closeTime",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "RoundRefunded",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "reason",
"type": "string",
"indexed": false,
"internalType": "string"
}
],
"anonymous": false
},
{
"name": "RoundSettled",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "closePrice",
"type": "int256",
"indexed": false,
"internalType": "int256"
},
{
"name": "upWon",
"type": "bool",
"indexed": false,
"internalType": "bool"
},
{
"name": "winningPool",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "losingPool",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "rake",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "StreamsMarketAdded",
"type": "event",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "verifierProxy",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "feedId",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
},
{
"name": "duration",
"type": "uint32",
"indexed": false,
"internalType": "uint32"
}
],
"anonymous": false
},
{
"name": "Withdrawn",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "KEEPER_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "MAX_DURATION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "MAX_RAKE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "MIN_DURATION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "REFUND_GRACE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "STALENESS_WINDOW",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "addKeeperMarket",
"type": "function",
"inputs": [
{
"name": "duration",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "minBet",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"internalType": "uint96"
}
],
"outputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "addMarket",
"type": "function",
"inputs": [
{
"name": "oracle",
"type": "address",
"internalType": "address"
},
{
"name": "duration",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "minBet",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"internalType": "uint96"
}
],
"outputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "addStreamsMarket",
"type": "function",
"inputs": [
{
"name": "verifierProxy",
"type": "address",
"internalType": "address"
},
{
"name": "feedId",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "marketMustBeOpen",
"type": "bool",
"internalType": "bool"
},
{
"name": "duration",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "minBet",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"internalType": "uint96"
}
],
"outputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "bet",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "up",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "claim",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claimMany",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "roundIds",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "currentRound",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getPosition",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "player",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "up",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "down",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "claimed",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct RoundArena.Position"
}
],
"stateMutability": "view"
},
{
"name": "getRound",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "openTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "closeTime",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "openPrice",
"type": "int256",
"internalType": "int256"
},
{
"name": "closePrice",
"type": "int256",
"internalType": "int256"
},
{
"name": "upPool",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "downPool",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "status",
"type": "uint8",
"internalType": "enum RoundArena.RoundStatus"
},
{
"name": "upWon",
"type": "bool",
"internalType": "bool"
},
{
"name": "settledRakeBps",
"type": "uint16",
"internalType": "uint16"
}
],
"internalType": "struct RoundArena.Round"
}
],
"stateMutability": "view"
},
{
"name": "keeperPriced",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "marketCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "markets",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "oracle",
"type": "address",
"internalType": "address"
},
{
"name": "duration",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "minBet",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "enabled",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "payoutFor",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "roundId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "player",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "pendingOwner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingWithdrawals",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "priceSubmitter",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "rakeBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "refundStuckRound",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMarketEnabled",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "enabled",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMarketLimits",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minBet",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "maxBet",
"type": "uint96",
"internalType": "uint96"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setPriceSubmitter",
"type": "function",
"inputs": [
{
"name": "newSubmitter",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setRake",
"type": "function",
"inputs": [
{
"name": "newRakeBps",
"type": "uint16",
"internalType": "uint16"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "streamsConfig",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "verifierProxy",
"type": "address",
"internalType": "address"
},
{
"name": "feedId",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "marketMustBeOpen",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "turn",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "turnWithPrice",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "price",
"type": "int256",
"internalType": "int256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "turnWithReport",
"type": "function",
"inputs": [
{
"name": "marketId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "report",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "withdraw",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
}
]0x60806040526001805461ffff60a01b1916604b60a21b1790553480156200002557600080fd5b5033806200004d57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000588162000083565b5060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055620000f1565b600180546001600160a01b03191690556200009e81620000a1565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61381580620001016000396000f3fe60806040526004361061021a5760003560e01c8063b043d7d611610123578063cccc0be2116100ab578063f0aa2f031161006f578063f0aa2f03146106ed578063f2fde38b1461070d578063f3f437031461072d578063f64d85af1461075a578063f937d6ad1461078757600080fd5b8063cccc0be214610663578063d02e7e831461067a578063d6c38c641461069a578063e30c3978146106ba578063ec979082146106d857600080fd5b8063bf48582b116100f2578063bf48582b146105a3578063c3490263146105c3578063c418f371146105e3578063ca2a64ba14610623578063ccb723431461064357600080fd5b8063b043d7d6146104dd578063b1283e77146104fd578063b1724b4614610562578063b6a6d1771461058e57600080fd5b80635bac70ea116101a65780637ddc4912116101755780637ddc49121461044357806387064e5f146104635780638c49597e146104785780638da5cb5b146104985780639a6d3aaa146104ca57600080fd5b80635bac70ea146103d9578063715018a6146103f957806373c7da8c1461040e57806379ba50971461042e57600080fd5b806328e70c4e116101ed57806328e70c4e146102b357806335048c571461030557806339ec68a3146103755780633ccfd60b146103a2578063425326f4146103b957600080fd5b80630f68b6081461021f578063102672ba14610252578063141e00b81461027b57806321c9c44a14610291575b600080fd5b34801561022b57600080fd5b5061023f61023a366004612d6d565b6107a7565b6040519081526020015b60405180910390f35b34801561025e57600080fd5b506102686101f481565b60405161ffff9091168152602001610249565b34801561028757600080fd5b5061023f61070881565b34801561029d57600080fd5b5060015461026890600160a01b900461ffff1681565b3480156102bf57600080fd5b506102d36102ce366004612dc5565b6109d9565b6040805182516001600160801b0390811682526020808501519091169082015291810151151590820152606001610249565b34801561031157600080fd5b5061034e610320366004612dfe565b6003602052600090815260409020805460018201546002909201546001600160a01b03909116919060ff1683565b604080516001600160a01b0390941684526020840192909252151590820152606001610249565b34801561038157600080fd5b50610395610390366004612e17565b610a5a565b6040516102499190612e71565b3480156103ae57600080fd5b506103b7610b83565b005b3480156103c557600080fd5b506103b76103d4366004612f19565b610c84565b3480156103e557600080fd5b5061023f6103f4366004612f55565b610d4f565b34801561040557600080fd5b506103b7610f59565b34801561041a57600080fd5b506103b7610429366004612f83565b610f6b565b34801561043a57600080fd5b506103b7610ff0565b34801561044f57600080fd5b506103b761045e366004612dfe565b611039565b34801561046f57600080fd5b50610268603281565b34801561048457600080fd5b506103b7610493366004612fa7565b61123b565b3480156104a457600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610249565b6103b76104d8366004612fd2565b61128d565b3480156104e957600080fd5b506103b76104f8366004612dfe565b611569565b34801561050957600080fd5b5061051d610518366004612dfe565b61164f565b604080516001600160a01b03909616865263ffffffff90941660208601526001600160601b03928316938501939093521660608301521515608082015260a001610249565b34801561056e57600080fd5b5061057962093a8081565b60405163ffffffff9091168152602001610249565b34801561059a57600080fd5b50610579603c81565b3480156105af57600080fd5b5061023f6105be366004612dc5565b6116b6565b3480156105cf57600080fd5b506103b76105de366004612e17565b611770565b3480156105ef57600080fd5b506106136105fe366004612dfe565b60046020526000908152604090205460ff1681565b6040519015158152602001610249565b34801561062f57600080fd5b506103b761063e366004613002565b6117ee565b34801561064f57600080fd5b506103b761065e366004612e17565b6118ba565b34801561066f57600080fd5b5061023f6201518081565b34801561068657600080fd5b5061023f610695366004613080565b611999565b3480156106a657600080fd5b506103b76106b53660046130f3565b611c18565b3480156106c657600080fd5b506001546001600160a01b03166104b2565b3480156106e457600080fd5b5060025461023f565b3480156106f957600080fd5b506103b7610708366004612fd2565b611d41565b34801561071957600080fd5b506103b7610728366004612fa7565b611dab565b34801561073957600080fd5b5061023f610748366004612fa7565b60096020526000908152604090205481565b34801561076657600080fd5b5061023f610775366004612dfe565b60066020526000908152604090205481565b34801561079357600080fd5b506005546104b2906001600160a01b031681565b60006107b1611e1c565b6001600160a01b0385166107d85760405163d92e233d60e01b815260040160405180910390fd5b603c63ffffffff851610806107f5575062093a8063ffffffff8516115b1561081357604051637616640160e01b815260040160405180910390fd5b6001600160601b038316158061083a5750826001600160601b0316826001600160601b0316105b156108585760405163e773e0a960e01b815260040160405180910390fd5b50600280546040805160a0810182526001600160a01b03808916825263ffffffff808916602084019081526001600160601b03808a1685870190815289821660608701908152600160808801818152908a018b5560008b905296519989027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180549551909616600160a01b026001600160c01b03199586169b9097169a909a179590951790935591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf9097018054935194511515600160c01b0260ff60c01b19958416600160601b02949092169790921696909617919091179190911693909317909255905181907f8372e50b1218687f8502c6e6ee1b41798e6494e4368dd3c4dfb24746f4c1e1c4906109c99088908890889088906001600160a01b0394909416845263ffffffff9290921660208401526001600160601b03908116604084015216606082015260800190565b60405180910390a2949350505050565b6040805160608082018352600080835260208084018290529284018190528681526008835283812086825283528381206001600160a01b038616825283528390208351918201845280546001600160801b038082168452600160801b909104169282019290925260019091015460ff161515918101919091525b9392505050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810191909152600083815260076020908152604080832085845282529182902082516101208101845281546001600160401b038082168352600160401b9091041692810192909252600181015492820192909252600282015460608201526003808301546001600160801b038082166080850152600160801b9091041660a0830152600483015491929160c084019160ff90911690811115610b4157610b41612e39565b6003811115610b5257610b52612e39565b815260049190910154610100810460ff161515602083015262010000900461ffff1660409091015290505b92915050565b610b8b611e49565b3360009081526009602052604081205490819003610bbc576040516312d37ee560e31b815260040160405180910390fd5b336000818152600960205260408082208290555190919083908381818185875af1925050503d8060008114610c0d576040519150601f19603f3d011682016040523d82523d6000602084013e610c12565b606091505b5050905080610c34576040516312171d8360e31b815260040160405180910390fd5b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a25050610c8260016000805160206137c083398151915255565b565b610c8c611e1c565b6001600160601b0382161580610cb35750816001600160601b0316816001600160601b0316105b15610cd15760405163e773e0a960e01b815260040160405180910390fd5b6000610cdc84611e65565b6001810180546001600160601b038681166001600160c01b03199092168217600160601b9187169182021790925560408051918252602082019290925291925085917f9ecac6196c6c700f83991c11d1490e77edc6b23f26331aaf20542ac40aed4b3a910160405180910390a250505050565b6000610d59611e1c565b603c63ffffffff85161080610d76575062093a8063ffffffff8516115b15610d9457604051637616640160e01b815260040160405180910390fd5b6001600160601b0383161580610dbb5750826001600160601b0316826001600160601b0316105b15610dd95760405163e773e0a960e01b815260040160405180910390fd5b50600280546040805160a081018252600080825263ffffffff80891660208085019182526001600160601b03808b168688019081528a821660608801908152600160808901818152818c018d558c895298519b8b027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180549751909816600160a01b026001600160c01b03199788166001600160a01b039e909e169d909d179c909c1790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909a018054915197511515600160c01b0260ff60c01b19988416600160601b02929095169a909216999099179890981794909416179095558381526004909152819020805460ff1916909317909255905181907fcdfedec4fb627044a98d825cf022a6ac665a89e3ae4db8ae64b0a9adf0fce5f790610f4a9087908790879063ffffffff9390931683526001600160601b03918216602084015216604082015260600190565b60405180910390a29392505050565b610f61611e1c565b610c826000611eb2565b610f73611e1c565b6101f461ffff82161115610f9a57604051631bf6744f60e31b815260040160405180910390fd5b6001805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f4c0fb7bfa248e2be3db56245fda224aa1586cc21f676ea718ad279d9f55929b99060200160405180910390a150565b60015433906001600160a01b0316811461102d5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61103681611eb2565b50565b611041611e49565b600081815260066020526040812054908190036110715760405163161e285760e21b815260040160405180910390fd5b600082815260076020908152604080832084845290915290206001600482015460ff1660038111156110a5576110a5612e39565b146110c3576040516358e2bd7f60e01b815260040160405180910390fd5b80546110e3906201518090600160401b90046001600160401b0316613171565b421161110257604051633aee3c1360e21b815260040160405180910390fd5b600061110d84611e65565b546001600160a01b0316905080156111c557806001600160a01b0316637e91400f6040518163ffffffff1660e01b81526004016040805180830381865afa925050508015611178575060408051601f3d908101601f1916820190925261117591810190613184565b60015b156111c55760008213801561118d5750428111155b80156111a457506107086111a182426131a8565b11155b156111c2576040516347a2375f60e01b815260040160405180910390fd5b50505b60048201805460ff1916600317905560408051602080825260059082015264737475636b60d81b818301529051849186917fc2d5b3fc83d5f9195041d100db1c54de598eeffc70824ecc2f00dff303907ef1916060908290030190a350505061103660016000805160206137c083398151915255565b611243611e1c565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fdf6da46c830a5c88d58f1160b0fc9f94f54602bc9014bd2b4da30cc7ee9b391690600090a250565b611295611e49565b60006112a083611e65565b6001810154909150600160c01b900460ff166112cf576040516352a422f760e01b815260040160405180910390fd5b600083815260066020526040812054908190036112ff5760405163161e285760e21b815260040160405180910390fd5b600084815260076020908152604080832084845290915290206001600482015460ff16600381111561133357611333612e39565b14158061135157508054600160401b90046001600160401b03164210155b1561136f57604051635e26bbc360e01b815260040160405180910390fd5b60018301546001600160601b031634108061139d57506001830154600160601b90046001600160601b031634115b156113bb57604051637e10802360e11b815260040160405180910390fd5b6000858152600860209081526040808320858452825280832033845290915290208415611475576003820180543491906000906114029084906001600160801b03166131bb565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550348160000160008282829054906101000a90046001600160801b031661144c91906131bb565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061150a565b348260030160108282829054906101000a90046001600160801b031661149b91906131bb565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550348160000160108282829054906101000a90046001600160801b03166114e591906131bb565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b6040805186151581523460208201523391859189917ff3ab2bcf39be4f92d45c76141f7f2c58640f9a70be1a380118dadd1191b6d53d910160405180910390a45050505061156560016000805160206137c083398151915255565b5050565b611571611e49565b600061157c82611e65565b6001810154909150600160c01b900460ff166115ab576040516352a422f760e01b815260040160405180910390fd5b6000828152600360205260409020546001600160a01b0316156115e15760405163991735ef60e01b815260040160405180910390fd5b60008281526004602052604090205460ff1615611611576040516348f82c9f60e01b815260040160405180910390fd5b8054600090611628906001600160a01b0316611ecb565b509050611636838383611f8f565b505061103660016000805160206137c083398151915255565b6002818154811061165f57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0382169250600160a01b90910463ffffffff16906001600160601b0380821691600160601b810490911690600160c01b900460ff1685565b600083815260076020908152604080832085845282528083208684526008835281842086855283528184206001600160a01b03861685529092528220600181015460ff161561170a57600092505050610a53565b6002600483015460ff16600381111561172557611725612e39565b1415801561174c57506003600483015460ff16600381111561174957611749612e39565b14155b1561175c57600092505050610a53565b61176682826121f0565b9695505050505050565b611778611e49565b60006117858383336123a0565b905061179133826124b2565b336001600160a01b031682847fb94bf7f9302edf52a596286915a69b4b0685574cffdedd0712e3c62f2550f0ba846040516117ce91815260200190565b60405180910390a45061156560016000805160206137c083398151915255565b6117f6611e49565b6000805b828110156118925760006118278686868581811061181a5761181a6131e2565b90506020020135336123a0565b90506118338184613171565b925033858584818110611848576118486131e2565b90506020020135877fb94bf7f9302edf52a596286915a69b4b0685574cffdedd0712e3c62f2550f0ba8460405161188191815260200190565b60405180910390a4506001016117fa565b5061189d33826124b2565b506118b560016000805160206137c083398151915255565b505050565b6118c2611e49565b6005546001600160a01b031633146118ed57604051635e06575360e01b815260040160405180910390fd5b60006118f883611e65565b6001810154909150600160c01b900460ff16611927576040516352a422f760e01b815260040160405180910390fd5b60008381526004602052604090205460ff1661195657604051630d1bc37360e21b815260040160405180910390fd5b600082136119765760405162bfc92160e01b815260040160405180910390fd5b611981838284611f8f565b5061156560016000805160206137c083398151915255565b60006119a3611e1c565b6001600160a01b03871615806119b7575085155b156119d55760405163d92e233d60e01b815260040160405180910390fd5b603c63ffffffff851610806119f2575062093a8063ffffffff8516115b15611a1057604051637616640160e01b815260040160405180910390fd5b6001600160601b0383161580611a375750826001600160601b0316826001600160601b0316105b15611a555760405163e773e0a960e01b815260040160405180910390fd5b50600280546040805160a081018252600080825263ffffffff80891660208085019182526001600160601b03808b168688019081528a82166060808901918252600160808a01818152818d018e558d8a5299518c8e027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180549951909a16600160a01b026001600160c01b0319998a166001600160a01b03938416171790995593517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909801805493519a511515600160c01b0260ff60c01b199b8716600160601b029490981698909516979097179190911797909716939093179055855194850186528d821685528481018d81528c15158688019081528886526003909252938690209451855492166001600160a01b031992909216919091178455915190830155519301805493151560ff1990941693909317909255905181907fefa32c75b4028170f8b9a47eacd9f314ba3345f5cc4fe9c9d350816050de83f790611c06908a908a9089906001600160a01b03939093168352602083019190915263ffffffff16604082015260600190565b60405180910390a29695505050505050565b611c20611e49565b6000611c2b84611e65565b6001810154909150600160c01b900460ff16611c5a576040516352a422f760e01b815260040160405180910390fd5b600084815260036020526040902080546001600160a01b0316611c9057604051633060bd2360e21b815260040160405180910390fd5b8054600282015460009182918291611cba916001600160a01b03909116908990899060ff16612589565b92509250925083600101548314611ce45760405163446d4d6d60e11b815260040160405180910390fd5b42811180611cfc5750610708611cfa82426131a8565b115b15611d1a57604051630cd5fa0760e11b815260040160405180910390fd5b611d25888684611f8f565b50505050506118b560016000805160206137c083398151915255565b611d49611e1c565b80611d5383611e65565b6001018054911515600160c01b0260ff60c01b19909216919091179055604051811515815282907fa756ac37231a5dc5968615cd5e498efec79aff153756133ab1d2c6270081cd499060200160405180910390a25050565b611db3611e1c565b600180546001600160a01b0383166001600160a01b03199091168117909155611de46000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000546001600160a01b03163314610c825760405163118cdaa760e01b8152336004820152602401611024565b611e516127a3565b60026000805160206137c083398151915255565b6002546000908210611e8a5760405163d8ac932560e01b815260040160405180910390fd5b60028281548110611e9d57611e9d6131e2565b90600052602060002090600202019050919050565b600180546001600160a01b0319169055611036816127d3565b600080826001600160a01b0316637e91400f6040518163ffffffff1660e01b81526004016040805180830381865afa158015611f0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2f9190613184565b909250905060008213611f545760405162bfc92160e01b815260040160405180910390fd5b42811180611f6c5750610708611f6a82426131a8565b115b15611f8a57604051630cd5fa0760e11b815260040160405180910390fd5b915091565b600083815260066020526040902054801561201d57600084815260076020908152604080832084845290915290208054600160401b90046001600160401b0316421015611fef576040516347a2375f60e01b815260040160405180910390fd5b6001600482015460ff16600381111561200a5761200a612e39565b0361201b5761201b85838386612823565b505b600061202a826001613171565b600086815260066020526040812082905585549192509061205890600160a01b900463ffffffff16426131f8565b60408051610120810182526001600160401b034281168252831660208201529081018690526000606082018190526080820181905260a082015290915060c08101600181526000602080830182905260409283018290528982526007815282822086835281529082902083518154928501516001600160401b03908116600160401b026fffffffffffffffffffffffffffffffff199094169116179190911781559082015160018281019190915560608301516002830155608083015160a08401516001600160801b03908116600160801b0291161760038084019190915560c08401516004840180549193909260ff1990921691849081111561215e5761215e612e39565b021790555060e082015160049190910180546101009384015161ffff16620100000263ffff0000199315159094029290921663ffffff001990921691909117919091179055604080518581526001600160401b0383166020820152839188917fd39d494e1b7944b76bae7cd1410c3e1d90405fee70720484556ec64efc5bd922910160405180910390a3505050505050565b60006003600484015460ff16600381111561220d5761220d612e39565b03612237578154612230906001600160801b03600160801b820481169116613171565b9050610b7d565b6004830154600090610100900460ff16612262578254600160801b90046001600160801b031661226e565b82546001600160801b03165b6001600160801b031690508060000361228b576000915050610b7d565b6004840154600090610100900460ff166122b9576003850154600160801b90046001600160801b03166122c8565b60038501546001600160801b03165b6001600160801b0316905060008560040160019054906101000a900460ff166122fe5760038601546001600160801b0316612314565b6003860154600160801b90046001600160801b03165b6001600160801b03169050600061271061232f603284613218565b6123399190613245565b6004880154612710906123569062010000900461ffff1685613218565b6123609190613245565b61236a90846131a8565b61237491906131a8565b9050826123818583613218565b61238b9190613245565b6123959085613171565b979650505050505050565b600083815260076020908152604080832085845290915281206002600482015460ff1660038111156123d4576123d4612e39565b141580156123fb57506003600482015460ff1660038111156123f8576123f8612e39565b14155b15612419576040516358e2bd7f60e01b815260040160405180910390fd5b600085815260086020908152604080832087845282528083206001600160a01b03871684529091529020600181015460ff161561246957604051630c8d9eab60e31b815260040160405180910390fd5b600061247583836121f0565b905080600003612498576040516312d37ee560e31b815260040160405180910390fd5b6001918201805460ff191690921790915595945050505050565b806000036124be575050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461250b576040519150601f19603f3d011682016040523d82523d6000602084013e612510565b606091505b50509050806118b5576001600160a01b03831660009081526009602052604081208054849290612541908490613171565b90915550506040518281526001600160a01b038416907fa7f6dcc09fce33324178c36b6b82157be4823c869006a07047058ca7f2dfe0889060200160405180910390a2505050565b600080808481036125ac5760405162bf199760e01b815260040160405180910390fd5b60006125ba86880188613345565b91505060006125c98983612a99565b90506000896001600160a01b031663f7e83aee8a8a856040518463ffffffff1660e01b81526004016125fd93929190613438565b6000604051808303816000875af115801561261c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126449190810190613476565b90506000612656846020015160f01c90565b905060021961ffff8216016126dd5760008280602001905181019061267b9190613520565b905060008160c0015160170b136126a5576040516309e5775760e11b815260040160405180910390fd5b805160c08201516126bf906402540be4009060170b6135cf565b82604001518063ffffffff1690509750975097505050505050612799565b60071961ffff82160161277a576000828060200190518101906127009190613614565b905088801561271b575061010081015163ffffffff16600214155b156127385760405162b5f6bf60e41b815260040160405180910390fd5b60008160e0015160170b13612760576040516309e5775760e11b815260040160405180910390fd5b805160e08201516126bf906402540be4009060170b6135cf565b604051635d654bf360e11b815261ffff82166004820152602401611024565b9450945094915050565b6000805160206137c083398151915254600203610c8257604051633ee5aeb560e01b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002820181905560018201548113600081612852576003840154600160801b90046001600160801b0316612861565b60038401546001600160801b03165b6001600160801b031690506000826128865760038501546001600160801b031661289c565b6003850154600160801b90046001600160801b03165b6001600160801b031690508460010154840361291f576004850180546003919060ff1916600183021790555085877fc2d5b3fc83d5f9195041d100db1c54de598eeffc70824ecc2f00dff303907ef160405161290f9060208082526003908201526274696560e81b604082015260600190565b60405180910390a3505050612a93565b81158061292a575080155b1561298f5760048501805460ff19166003179055604080516020808252600990820152681bdb994b5cda59195960ba1b91810191909152869088907fc2d5b3fc83d5f9195041d100db1c54de598eeffc70824ecc2f00dff303907ef19060600161290f565b600485018054600261ffff198216610100871515029081178217845560015463ffffffff1990931663ffff00001990911617600160a01b90920461ffff16620100008102929092171790915560006127106129ea8385613218565b6129f49190613245565b90506000612710612a06603286613218565b612a109190613245565b604080518981528815156020820152908101879052606081018690526080810184905290915089908b907fb2d1c844d060441643c11b3f7840ad6aa873014f7f83ca709fc1def7980731e89060a00160405180910390a3612a82612a7c6000546001600160a01b031690565b836124b2565b612a8c33826124b2565b5050505050505b50505050565b60606000836001600160a01b03166338416b5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff91906136b8565b90506001600160a01b038116612b25575050604080516020810190915260008152610b7d565b60008190506000816001600160a01b031663ea4b861b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8e91906136b8565b90506000826001600160a01b031663e03dab1a3088856040518463ffffffff1660e01b8152600401612bc2939291906136d5565b60a0604051808303816000875af1158015612be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c059190613764565b5050602081015190915015612cfb57816001600160a01b031663095ea7b3846001600160a01b0316633aa5ac076040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8591906136b8565b60208401516040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015612cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf991906137a2565b505b604080516001600160a01b03841660208201520160405160208183030381529060405294505050505092915050565b6001600160a01b038116811461103657600080fd5b63ffffffff8116811461103657600080fd5b80356001600160601b0381168114612d6857600080fd5b919050565b60008060008060808587031215612d8357600080fd5b8435612d8e81612d2a565b93506020850135612d9e81612d3f565b9250612dac60408601612d51565b9150612dba60608601612d51565b905092959194509250565b600080600060608486031215612dda57600080fd5b83359250602084013591506040840135612df381612d2a565b809150509250925092565b600060208284031215612e1057600080fd5b5035919050565b60008060408385031215612e2a57600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b60048110612e6d57634e487b7160e01b600052602160045260246000fd5b9052565b6000610120820190506001600160401b038084511683528060208501511660208401525060408301516040830152606083015160608301526080830151612ec360808401826001600160801b03169052565b5060a0830151612ede60a08401826001600160801b03169052565b5060c0830151612ef160c0840182612e4f565b5060e0830151612f0560e084018215159052565b506101009283015161ffff16919092015290565b600080600060608486031215612f2e57600080fd5b83359250612f3e60208501612d51565b9150612f4c60408501612d51565b90509250925092565b600080600060608486031215612f6a57600080fd5b8335612f7581612d3f565b9250612f3e60208501612d51565b600060208284031215612f9557600080fd5b813561ffff81168114610a5357600080fd5b600060208284031215612fb957600080fd5b8135610a5381612d2a565b801515811461103657600080fd5b60008060408385031215612fe557600080fd5b823591506020830135612ff781612fc4565b809150509250929050565b60008060006040848603121561301757600080fd5b8335925060208401356001600160401b038082111561303557600080fd5b818601915086601f83011261304957600080fd5b81358181111561305857600080fd5b8760208260051b850101111561306d57600080fd5b6020830194508093505050509250925092565b60008060008060008060c0878903121561309957600080fd5b86356130a481612d2a565b95506020870135945060408701356130bb81612fc4565b935060608701356130cb81612d3f565b92506130d960808801612d51565b91506130e760a08801612d51565b90509295509295509295565b60008060006040848603121561310857600080fd5b8335925060208401356001600160401b038082111561312657600080fd5b818601915086601f83011261313a57600080fd5b81358181111561314957600080fd5b87602082850101111561306d57600080fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610b7d57610b7d61315b565b6000806040838503121561319757600080fd5b505080516020909101519092909150565b81810381811115610b7d57610b7d61315b565b6001600160801b038181168382160190808211156131db576131db61315b565b5092915050565b634e487b7160e01b600052603260045260246000fd5b6001600160401b038181168382160190808211156131db576131db61315b565b8082028115828204841417610b7d57610b7d61315b565b634e487b7160e01b600052601260045260246000fd5b6000826132545761325461322f565b500490565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561329257613292613259565b60405290565b604051601f8201601f191681016001600160401b03811182821017156132c0576132c0613259565b604052919050565b60006001600160401b038211156132e1576132e1613259565b50601f01601f191660200190565b600082601f83011261330057600080fd5b813561331361330e826132c8565b613298565b81815284602083860101111561332857600080fd5b816020850160208301376000918101602001919091529392505050565b6000806080838503121561335857600080fd5b83601f84011261336757600080fd5b604051606081016001600160401b03828210818311171561338a5761338a613259565b8160405282915060608601878111156133a257600080fd5b865b818110156133bc5780358452602093840193016133a4565b50929450913591808311156133d057600080fd5b50506133de858286016132ef565b9150509250929050565b60005b838110156134035781810151838201526020016133eb565b50506000910152565b600081518084526134248160208601602086016133e8565b601f01601f19169290920160200192915050565b60408152826040820152828460608301376000606084830101526000601f19601f85011682016060838203016020840152611766606082018561340c565b60006020828403121561348857600080fd5b81516001600160401b0381111561349e57600080fd5b8201601f810184136134af57600080fd5b80516134bd61330e826132c8565b8181528560208385010111156134d257600080fd5b6134e38260208301602086016133e8565b95945050505050565b8051612d6881612d3f565b80516001600160c01b0381168114612d6857600080fd5b8051601781900b8114612d6857600080fd5b6000610120828403121561353357600080fd5b61353b61326f565b8251815261354b602084016134ec565b602082015261355c604084016134ec565b604082015261356d606084016134f7565b606082015261357e608084016134f7565b608082015261358f60a084016134ec565b60a08201526135a060c0840161350e565b60c08201526135b160e0840161350e565b60e08201526101006135c481850161350e565b908201529392505050565b6000826135de576135de61322f565b600160ff1b8214600019841416156135f8576135f861315b565b500590565b80516001600160401b0381168114612d6857600080fd5b6000610120828403121561362757600080fd5b61362f61326f565b8251815261363f602084016134ec565b6020820152613650604084016134ec565b6040820152613661606084016134f7565b6060820152613672608084016134f7565b608082015261368360a084016134ec565b60a082015261369460c084016135fd565b60c08201526136a560e0840161350e565b60e08201526101006135c48185016134ec565b6000602082840312156136ca57600080fd5b8151610a5381612d2a565b600060018060a01b038086168352606060208401526136f7606084018661340c565b9150808416604084015250949350505050565b60006040828403121561371c57600080fd5b604051604081018181106001600160401b038211171561373e5761373e613259565b8060405250809150825161375181612d2a565b8152602092830151920191909152919050565b600080600060a0848603121561377957600080fd5b613783858561370a565b9250613792856040860161370a565b9150608084015190509250925092565b6000602082840312156137b457600080fd5b8151610a5381612fc456fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212205d4d1751797d8d2bb0a57abf8b79b248b2c6dc6d8c1b68118b605d999e1abfdf64736f6c63430008180033
0x60806040526004361061021a5760003560e01c8063b043d7d611610123578063cccc0be2116100ab578063f0aa2f031161006f578063f0aa2f03146106ed578063f2fde38b1461070d578063f3f437031461072d578063f64d85af1461075a578063f937d6ad1461078757600080fd5b8063cccc0be214610663578063d02e7e831461067a578063d6c38c641461069a578063e30c3978146106ba578063ec979082146106d857600080fd5b8063bf48582b116100f2578063bf48582b146105a3578063c3490263146105c3578063c418f371146105e3578063ca2a64ba14610623578063ccb723431461064357600080fd5b8063b043d7d6146104dd578063b1283e77146104fd578063b1724b4614610562578063b6a6d1771461058e57600080fd5b80635bac70ea116101a65780637ddc4912116101755780637ddc49121461044357806387064e5f146104635780638c49597e146104785780638da5cb5b146104985780639a6d3aaa146104ca57600080fd5b80635bac70ea146103d9578063715018a6146103f957806373c7da8c1461040e57806379ba50971461042e57600080fd5b806328e70c4e116101ed57806328e70c4e146102b357806335048c571461030557806339ec68a3146103755780633ccfd60b146103a2578063425326f4146103b957600080fd5b80630f68b6081461021f578063102672ba14610252578063141e00b81461027b57806321c9c44a14610291575b600080fd5b34801561022b57600080fd5b5061023f61023a366004612d6d565b6107a7565b6040519081526020015b60405180910390f35b34801561025e57600080fd5b506102686101f481565b60405161ffff9091168152602001610249565b34801561028757600080fd5b5061023f61070881565b34801561029d57600080fd5b5060015461026890600160a01b900461ffff1681565b3480156102bf57600080fd5b506102d36102ce366004612dc5565b6109d9565b6040805182516001600160801b0390811682526020808501519091169082015291810151151590820152606001610249565b34801561031157600080fd5b5061034e610320366004612dfe565b6003602052600090815260409020805460018201546002909201546001600160a01b03909116919060ff1683565b604080516001600160a01b0390941684526020840192909252151590820152606001610249565b34801561038157600080fd5b50610395610390366004612e17565b610a5a565b6040516102499190612e71565b3480156103ae57600080fd5b506103b7610b83565b005b3480156103c557600080fd5b506103b76103d4366004612f19565b610c84565b3480156103e557600080fd5b5061023f6103f4366004612f55565b610d4f565b34801561040557600080fd5b506103b7610f59565b34801561041a57600080fd5b506103b7610429366004612f83565b610f6b565b34801561043a57600080fd5b506103b7610ff0565b34801561044f57600080fd5b506103b761045e366004612dfe565b611039565b34801561046f57600080fd5b50610268603281565b34801561048457600080fd5b506103b7610493366004612fa7565b61123b565b3480156104a457600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610249565b6103b76104d8366004612fd2565b61128d565b3480156104e957600080fd5b506103b76104f8366004612dfe565b611569565b34801561050957600080fd5b5061051d610518366004612dfe565b61164f565b604080516001600160a01b03909616865263ffffffff90941660208601526001600160601b03928316938501939093521660608301521515608082015260a001610249565b34801561056e57600080fd5b5061057962093a8081565b60405163ffffffff9091168152602001610249565b34801561059a57600080fd5b50610579603c81565b3480156105af57600080fd5b5061023f6105be366004612dc5565b6116b6565b3480156105cf57600080fd5b506103b76105de366004612e17565b611770565b3480156105ef57600080fd5b506106136105fe366004612dfe565b60046020526000908152604090205460ff1681565b6040519015158152602001610249565b34801561062f57600080fd5b506103b761063e366004613002565b6117ee565b34801561064f57600080fd5b506103b761065e366004612e17565b6118ba565b34801561066f57600080fd5b5061023f6201518081565b34801561068657600080fd5b5061023f610695366004613080565b611999565b3480156106a657600080fd5b506103b76106b53660046130f3565b611c18565b3480156106c657600080fd5b506001546001600160a01b03166104b2565b3480156106e457600080fd5b5060025461023f565b3480156106f957600080fd5b506103b7610708366004612fd2565b611d41565b34801561071957600080fd5b506103b7610728366004612fa7565b611dab565b34801561073957600080fd5b5061023f610748366004612fa7565b60096020526000908152604090205481565b34801561076657600080fd5b5061023f610775366004612dfe565b60066020526000908152604090205481565b34801561079357600080fd5b506005546104b2906001600160a01b031681565b60006107b1611e1c565b6001600160a01b0385166107d85760405163d92e233d60e01b815260040160405180910390fd5b603c63ffffffff851610806107f5575062093a8063ffffffff8516115b1561081357604051637616640160e01b815260040160405180910390fd5b6001600160601b038316158061083a5750826001600160601b0316826001600160601b0316105b156108585760405163e773e0a960e01b815260040160405180910390fd5b50600280546040805160a0810182526001600160a01b03808916825263ffffffff808916602084019081526001600160601b03808a1685870190815289821660608701908152600160808801818152908a018b5560008b905296519989027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180549551909616600160a01b026001600160c01b03199586169b9097169a909a179590951790935591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf9097018054935194511515600160c01b0260ff60c01b19958416600160601b02949092169790921696909617919091179190911693909317909255905181907f8372e50b1218687f8502c6e6ee1b41798e6494e4368dd3c4dfb24746f4c1e1c4906109c99088908890889088906001600160a01b0394909416845263ffffffff9290921660208401526001600160601b03908116604084015216606082015260800190565b60405180910390a2949350505050565b6040805160608082018352600080835260208084018290529284018190528681526008835283812086825283528381206001600160a01b038616825283528390208351918201845280546001600160801b038082168452600160801b909104169282019290925260019091015460ff161515918101919091525b9392505050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810191909152600083815260076020908152604080832085845282529182902082516101208101845281546001600160401b038082168352600160401b9091041692810192909252600181015492820192909252600282015460608201526003808301546001600160801b038082166080850152600160801b9091041660a0830152600483015491929160c084019160ff90911690811115610b4157610b41612e39565b6003811115610b5257610b52612e39565b815260049190910154610100810460ff161515602083015262010000900461ffff1660409091015290505b92915050565b610b8b611e49565b3360009081526009602052604081205490819003610bbc576040516312d37ee560e31b815260040160405180910390fd5b336000818152600960205260408082208290555190919083908381818185875af1925050503d8060008114610c0d576040519150601f19603f3d011682016040523d82523d6000602084013e610c12565b606091505b5050905080610c34576040516312171d8360e31b815260040160405180910390fd5b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a25050610c8260016000805160206137c083398151915255565b565b610c8c611e1c565b6001600160601b0382161580610cb35750816001600160601b0316816001600160601b0316105b15610cd15760405163e773e0a960e01b815260040160405180910390fd5b6000610cdc84611e65565b6001810180546001600160601b038681166001600160c01b03199092168217600160601b9187169182021790925560408051918252602082019290925291925085917f9ecac6196c6c700f83991c11d1490e77edc6b23f26331aaf20542ac40aed4b3a910160405180910390a250505050565b6000610d59611e1c565b603c63ffffffff85161080610d76575062093a8063ffffffff8516115b15610d9457604051637616640160e01b815260040160405180910390fd5b6001600160601b0383161580610dbb5750826001600160601b0316826001600160601b0316105b15610dd95760405163e773e0a960e01b815260040160405180910390fd5b50600280546040805160a081018252600080825263ffffffff80891660208085019182526001600160601b03808b168688019081528a821660608801908152600160808901818152818c018d558c895298519b8b027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180549751909816600160a01b026001600160c01b03199788166001600160a01b039e909e169d909d179c909c1790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909a018054915197511515600160c01b0260ff60c01b19988416600160601b02929095169a909216999099179890981794909416179095558381526004909152819020805460ff1916909317909255905181907fcdfedec4fb627044a98d825cf022a6ac665a89e3ae4db8ae64b0a9adf0fce5f790610f4a9087908790879063ffffffff9390931683526001600160601b03918216602084015216604082015260600190565b60405180910390a29392505050565b610f61611e1c565b610c826000611eb2565b610f73611e1c565b6101f461ffff82161115610f9a57604051631bf6744f60e31b815260040160405180910390fd5b6001805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f4c0fb7bfa248e2be3db56245fda224aa1586cc21f676ea718ad279d9f55929b99060200160405180910390a150565b60015433906001600160a01b0316811461102d5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61103681611eb2565b50565b611041611e49565b600081815260066020526040812054908190036110715760405163161e285760e21b815260040160405180910390fd5b600082815260076020908152604080832084845290915290206001600482015460ff1660038111156110a5576110a5612e39565b146110c3576040516358e2bd7f60e01b815260040160405180910390fd5b80546110e3906201518090600160401b90046001600160401b0316613171565b421161110257604051633aee3c1360e21b815260040160405180910390fd5b600061110d84611e65565b546001600160a01b0316905080156111c557806001600160a01b0316637e91400f6040518163ffffffff1660e01b81526004016040805180830381865afa925050508015611178575060408051601f3d908101601f1916820190925261117591810190613184565b60015b156111c55760008213801561118d5750428111155b80156111a457506107086111a182426131a8565b11155b156111c2576040516347a2375f60e01b815260040160405180910390fd5b50505b60048201805460ff1916600317905560408051602080825260059082015264737475636b60d81b818301529051849186917fc2d5b3fc83d5f9195041d100db1c54de598eeffc70824ecc2f00dff303907ef1916060908290030190a350505061103660016000805160206137c083398151915255565b611243611e1c565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fdf6da46c830a5c88d58f1160b0fc9f94f54602bc9014bd2b4da30cc7ee9b391690600090a250565b611295611e49565b60006112a083611e65565b6001810154909150600160c01b900460ff166112cf576040516352a422f760e01b815260040160405180910390fd5b600083815260066020526040812054908190036112ff5760405163161e285760e21b815260040160405180910390fd5b600084815260076020908152604080832084845290915290206001600482015460ff16600381111561133357611333612e39565b14158061135157508054600160401b90046001600160401b03164210155b1561136f57604051635e26bbc360e01b815260040160405180910390fd5b60018301546001600160601b031634108061139d57506001830154600160601b90046001600160601b031634115b156113bb57604051637e10802360e11b815260040160405180910390fd5b6000858152600860209081526040808320858452825280832033845290915290208415611475576003820180543491906000906114029084906001600160801b03166131bb565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550348160000160008282829054906101000a90046001600160801b031661144c91906131bb565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061150a565b348260030160108282829054906101000a90046001600160801b031661149b91906131bb565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550348160000160108282829054906101000a90046001600160801b03166114e591906131bb565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b6040805186151581523460208201523391859189917ff3ab2bcf39be4f92d45c76141f7f2c58640f9a70be1a380118dadd1191b6d53d910160405180910390a45050505061156560016000805160206137c083398151915255565b5050565b611571611e49565b600061157c82611e65565b6001810154909150600160c01b900460ff166115ab576040516352a422f760e01b815260040160405180910390fd5b6000828152600360205260409020546001600160a01b0316156115e15760405163991735ef60e01b815260040160405180910390fd5b60008281526004602052604090205460ff1615611611576040516348f82c9f60e01b815260040160405180910390fd5b8054600090611628906001600160a01b0316611ecb565b509050611636838383611f8f565b505061103660016000805160206137c083398151915255565b6002818154811061165f57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0382169250600160a01b90910463ffffffff16906001600160601b0380821691600160601b810490911690600160c01b900460ff1685565b600083815260076020908152604080832085845282528083208684526008835281842086855283528184206001600160a01b03861685529092528220600181015460ff161561170a57600092505050610a53565b6002600483015460ff16600381111561172557611725612e39565b1415801561174c57506003600483015460ff16600381111561174957611749612e39565b14155b1561175c57600092505050610a53565b61176682826121f0565b9695505050505050565b611778611e49565b60006117858383336123a0565b905061179133826124b2565b336001600160a01b031682847fb94bf7f9302edf52a596286915a69b4b0685574cffdedd0712e3c62f2550f0ba846040516117ce91815260200190565b60405180910390a45061156560016000805160206137c083398151915255565b6117f6611e49565b6000805b828110156118925760006118278686868581811061181a5761181a6131e2565b90506020020135336123a0565b90506118338184613171565b925033858584818110611848576118486131e2565b90506020020135877fb94bf7f9302edf52a596286915a69b4b0685574cffdedd0712e3c62f2550f0ba8460405161188191815260200190565b60405180910390a4506001016117fa565b5061189d33826124b2565b506118b560016000805160206137c083398151915255565b505050565b6118c2611e49565b6005546001600160a01b031633146118ed57604051635e06575360e01b815260040160405180910390fd5b60006118f883611e65565b6001810154909150600160c01b900460ff16611927576040516352a422f760e01b815260040160405180910390fd5b60008381526004602052604090205460ff1661195657604051630d1bc37360e21b815260040160405180910390fd5b600082136119765760405162bfc92160e01b815260040160405180910390fd5b611981838284611f8f565b5061156560016000805160206137c083398151915255565b60006119a3611e1c565b6001600160a01b03871615806119b7575085155b156119d55760405163d92e233d60e01b815260040160405180910390fd5b603c63ffffffff851610806119f2575062093a8063ffffffff8516115b15611a1057604051637616640160e01b815260040160405180910390fd5b6001600160601b0383161580611a375750826001600160601b0316826001600160601b0316105b15611a555760405163e773e0a960e01b815260040160405180910390fd5b50600280546040805160a081018252600080825263ffffffff80891660208085019182526001600160601b03808b168688019081528a82166060808901918252600160808a01818152818d018e558d8a5299518c8e027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180549951909a16600160a01b026001600160c01b0319998a166001600160a01b03938416171790995593517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909801805493519a511515600160c01b0260ff60c01b199b8716600160601b029490981698909516979097179190911797909716939093179055855194850186528d821685528481018d81528c15158688019081528886526003909252938690209451855492166001600160a01b031992909216919091178455915190830155519301805493151560ff1990941693909317909255905181907fefa32c75b4028170f8b9a47eacd9f314ba3345f5cc4fe9c9d350816050de83f790611c06908a908a9089906001600160a01b03939093168352602083019190915263ffffffff16604082015260600190565b60405180910390a29695505050505050565b611c20611e49565b6000611c2b84611e65565b6001810154909150600160c01b900460ff16611c5a576040516352a422f760e01b815260040160405180910390fd5b600084815260036020526040902080546001600160a01b0316611c9057604051633060bd2360e21b815260040160405180910390fd5b8054600282015460009182918291611cba916001600160a01b03909116908990899060ff16612589565b92509250925083600101548314611ce45760405163446d4d6d60e11b815260040160405180910390fd5b42811180611cfc5750610708611cfa82426131a8565b115b15611d1a57604051630cd5fa0760e11b815260040160405180910390fd5b611d25888684611f8f565b50505050506118b560016000805160206137c083398151915255565b611d49611e1c565b80611d5383611e65565b6001018054911515600160c01b0260ff60c01b19909216919091179055604051811515815282907fa756ac37231a5dc5968615cd5e498efec79aff153756133ab1d2c6270081cd499060200160405180910390a25050565b611db3611e1c565b600180546001600160a01b0383166001600160a01b03199091168117909155611de46000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000546001600160a01b03163314610c825760405163118cdaa760e01b8152336004820152602401611024565b611e516127a3565b60026000805160206137c083398151915255565b6002546000908210611e8a5760405163d8ac932560e01b815260040160405180910390fd5b60028281548110611e9d57611e9d6131e2565b90600052602060002090600202019050919050565b600180546001600160a01b0319169055611036816127d3565b600080826001600160a01b0316637e91400f6040518163ffffffff1660e01b81526004016040805180830381865afa158015611f0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2f9190613184565b909250905060008213611f545760405162bfc92160e01b815260040160405180910390fd5b42811180611f6c5750610708611f6a82426131a8565b115b15611f8a57604051630cd5fa0760e11b815260040160405180910390fd5b915091565b600083815260066020526040902054801561201d57600084815260076020908152604080832084845290915290208054600160401b90046001600160401b0316421015611fef576040516347a2375f60e01b815260040160405180910390fd5b6001600482015460ff16600381111561200a5761200a612e39565b0361201b5761201b85838386612823565b505b600061202a826001613171565b600086815260066020526040812082905585549192509061205890600160a01b900463ffffffff16426131f8565b60408051610120810182526001600160401b034281168252831660208201529081018690526000606082018190526080820181905260a082015290915060c08101600181526000602080830182905260409283018290528982526007815282822086835281529082902083518154928501516001600160401b03908116600160401b026fffffffffffffffffffffffffffffffff199094169116179190911781559082015160018281019190915560608301516002830155608083015160a08401516001600160801b03908116600160801b0291161760038084019190915560c08401516004840180549193909260ff1990921691849081111561215e5761215e612e39565b021790555060e082015160049190910180546101009384015161ffff16620100000263ffff0000199315159094029290921663ffffff001990921691909117919091179055604080518581526001600160401b0383166020820152839188917fd39d494e1b7944b76bae7cd1410c3e1d90405fee70720484556ec64efc5bd922910160405180910390a3505050505050565b60006003600484015460ff16600381111561220d5761220d612e39565b03612237578154612230906001600160801b03600160801b820481169116613171565b9050610b7d565b6004830154600090610100900460ff16612262578254600160801b90046001600160801b031661226e565b82546001600160801b03165b6001600160801b031690508060000361228b576000915050610b7d565b6004840154600090610100900460ff166122b9576003850154600160801b90046001600160801b03166122c8565b60038501546001600160801b03165b6001600160801b0316905060008560040160019054906101000a900460ff166122fe5760038601546001600160801b0316612314565b6003860154600160801b90046001600160801b03165b6001600160801b03169050600061271061232f603284613218565b6123399190613245565b6004880154612710906123569062010000900461ffff1685613218565b6123609190613245565b61236a90846131a8565b61237491906131a8565b9050826123818583613218565b61238b9190613245565b6123959085613171565b979650505050505050565b600083815260076020908152604080832085845290915281206002600482015460ff1660038111156123d4576123d4612e39565b141580156123fb57506003600482015460ff1660038111156123f8576123f8612e39565b14155b15612419576040516358e2bd7f60e01b815260040160405180910390fd5b600085815260086020908152604080832087845282528083206001600160a01b03871684529091529020600181015460ff161561246957604051630c8d9eab60e31b815260040160405180910390fd5b600061247583836121f0565b905080600003612498576040516312d37ee560e31b815260040160405180910390fd5b6001918201805460ff191690921790915595945050505050565b806000036124be575050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461250b576040519150601f19603f3d011682016040523d82523d6000602084013e612510565b606091505b50509050806118b5576001600160a01b03831660009081526009602052604081208054849290612541908490613171565b90915550506040518281526001600160a01b038416907fa7f6dcc09fce33324178c36b6b82157be4823c869006a07047058ca7f2dfe0889060200160405180910390a2505050565b600080808481036125ac5760405162bf199760e01b815260040160405180910390fd5b60006125ba86880188613345565b91505060006125c98983612a99565b90506000896001600160a01b031663f7e83aee8a8a856040518463ffffffff1660e01b81526004016125fd93929190613438565b6000604051808303816000875af115801561261c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126449190810190613476565b90506000612656846020015160f01c90565b905060021961ffff8216016126dd5760008280602001905181019061267b9190613520565b905060008160c0015160170b136126a5576040516309e5775760e11b815260040160405180910390fd5b805160c08201516126bf906402540be4009060170b6135cf565b82604001518063ffffffff1690509750975097505050505050612799565b60071961ffff82160161277a576000828060200190518101906127009190613614565b905088801561271b575061010081015163ffffffff16600214155b156127385760405162b5f6bf60e41b815260040160405180910390fd5b60008160e0015160170b13612760576040516309e5775760e11b815260040160405180910390fd5b805160e08201516126bf906402540be4009060170b6135cf565b604051635d654bf360e11b815261ffff82166004820152602401611024565b9450945094915050565b6000805160206137c083398151915254600203610c8257604051633ee5aeb560e01b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002820181905560018201548113600081612852576003840154600160801b90046001600160801b0316612861565b60038401546001600160801b03165b6001600160801b031690506000826128865760038501546001600160801b031661289c565b6003850154600160801b90046001600160801b03165b6001600160801b031690508460010154840361291f576004850180546003919060ff1916600183021790555085877fc2d5b3fc83d5f9195041d100db1c54de598eeffc70824ecc2f00dff303907ef160405161290f9060208082526003908201526274696560e81b604082015260600190565b60405180910390a3505050612a93565b81158061292a575080155b1561298f5760048501805460ff19166003179055604080516020808252600990820152681bdb994b5cda59195960ba1b91810191909152869088907fc2d5b3fc83d5f9195041d100db1c54de598eeffc70824ecc2f00dff303907ef19060600161290f565b600485018054600261ffff198216610100871515029081178217845560015463ffffffff1990931663ffff00001990911617600160a01b90920461ffff16620100008102929092171790915560006127106129ea8385613218565b6129f49190613245565b90506000612710612a06603286613218565b612a109190613245565b604080518981528815156020820152908101879052606081018690526080810184905290915089908b907fb2d1c844d060441643c11b3f7840ad6aa873014f7f83ca709fc1def7980731e89060a00160405180910390a3612a82612a7c6000546001600160a01b031690565b836124b2565b612a8c33826124b2565b5050505050505b50505050565b60606000836001600160a01b03166338416b5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff91906136b8565b90506001600160a01b038116612b25575050604080516020810190915260008152610b7d565b60008190506000816001600160a01b031663ea4b861b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8e91906136b8565b90506000826001600160a01b031663e03dab1a3088856040518463ffffffff1660e01b8152600401612bc2939291906136d5565b60a0604051808303816000875af1158015612be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c059190613764565b5050602081015190915015612cfb57816001600160a01b031663095ea7b3846001600160a01b0316633aa5ac076040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8591906136b8565b60208401516040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015612cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf991906137a2565b505b604080516001600160a01b03841660208201520160405160208183030381529060405294505050505092915050565b6001600160a01b038116811461103657600080fd5b63ffffffff8116811461103657600080fd5b80356001600160601b0381168114612d6857600080fd5b919050565b60008060008060808587031215612d8357600080fd5b8435612d8e81612d2a565b93506020850135612d9e81612d3f565b9250612dac60408601612d51565b9150612dba60608601612d51565b905092959194509250565b600080600060608486031215612dda57600080fd5b83359250602084013591506040840135612df381612d2a565b809150509250925092565b600060208284031215612e1057600080fd5b5035919050565b60008060408385031215612e2a57600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b60048110612e6d57634e487b7160e01b600052602160045260246000fd5b9052565b6000610120820190506001600160401b038084511683528060208501511660208401525060408301516040830152606083015160608301526080830151612ec360808401826001600160801b03169052565b5060a0830151612ede60a08401826001600160801b03169052565b5060c0830151612ef160c0840182612e4f565b5060e0830151612f0560e084018215159052565b506101009283015161ffff16919092015290565b600080600060608486031215612f2e57600080fd5b83359250612f3e60208501612d51565b9150612f4c60408501612d51565b90509250925092565b600080600060608486031215612f6a57600080fd5b8335612f7581612d3f565b9250612f3e60208501612d51565b600060208284031215612f9557600080fd5b813561ffff81168114610a5357600080fd5b600060208284031215612fb957600080fd5b8135610a5381612d2a565b801515811461103657600080fd5b60008060408385031215612fe557600080fd5b823591506020830135612ff781612fc4565b809150509250929050565b60008060006040848603121561301757600080fd5b8335925060208401356001600160401b038082111561303557600080fd5b818601915086601f83011261304957600080fd5b81358181111561305857600080fd5b8760208260051b850101111561306d57600080fd5b6020830194508093505050509250925092565b60008060008060008060c0878903121561309957600080fd5b86356130a481612d2a565b95506020870135945060408701356130bb81612fc4565b935060608701356130cb81612d3f565b92506130d960808801612d51565b91506130e760a08801612d51565b90509295509295509295565b60008060006040848603121561310857600080fd5b8335925060208401356001600160401b038082111561312657600080fd5b818601915086601f83011261313a57600080fd5b81358181111561314957600080fd5b87602082850101111561306d57600080fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610b7d57610b7d61315b565b6000806040838503121561319757600080fd5b505080516020909101519092909150565b81810381811115610b7d57610b7d61315b565b6001600160801b038181168382160190808211156131db576131db61315b565b5092915050565b634e487b7160e01b600052603260045260246000fd5b6001600160401b038181168382160190808211156131db576131db61315b565b8082028115828204841417610b7d57610b7d61315b565b634e487b7160e01b600052601260045260246000fd5b6000826132545761325461322f565b500490565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561329257613292613259565b60405290565b604051601f8201601f191681016001600160401b03811182821017156132c0576132c0613259565b604052919050565b60006001600160401b038211156132e1576132e1613259565b50601f01601f191660200190565b600082601f83011261330057600080fd5b813561331361330e826132c8565b613298565b81815284602083860101111561332857600080fd5b816020850160208301376000918101602001919091529392505050565b6000806080838503121561335857600080fd5b83601f84011261336757600080fd5b604051606081016001600160401b03828210818311171561338a5761338a613259565b8160405282915060608601878111156133a257600080fd5b865b818110156133bc5780358452602093840193016133a4565b50929450913591808311156133d057600080fd5b50506133de858286016132ef565b9150509250929050565b60005b838110156134035781810151838201526020016133eb565b50506000910152565b600081518084526134248160208601602086016133e8565b601f01601f19169290920160200192915050565b60408152826040820152828460608301376000606084830101526000601f19601f85011682016060838203016020840152611766606082018561340c565b60006020828403121561348857600080fd5b81516001600160401b0381111561349e57600080fd5b8201601f810184136134af57600080fd5b80516134bd61330e826132c8565b8181528560208385010111156134d257600080fd5b6134e38260208301602086016133e8565b95945050505050565b8051612d6881612d3f565b80516001600160c01b0381168114612d6857600080fd5b8051601781900b8114612d6857600080fd5b6000610120828403121561353357600080fd5b61353b61326f565b8251815261354b602084016134ec565b602082015261355c604084016134ec565b604082015261356d606084016134f7565b606082015261357e608084016134f7565b608082015261358f60a084016134ec565b60a08201526135a060c0840161350e565b60c08201526135b160e0840161350e565b60e08201526101006135c481850161350e565b908201529392505050565b6000826135de576135de61322f565b600160ff1b8214600019841416156135f8576135f861315b565b500590565b80516001600160401b0381168114612d6857600080fd5b6000610120828403121561362757600080fd5b61362f61326f565b8251815261363f602084016134ec565b6020820152613650604084016134ec565b6040820152613661606084016134f7565b6060820152613672608084016134f7565b608082015261368360a084016134ec565b60a082015261369460c084016135fd565b60c08201526136a560e0840161350e565b60e08201526101006135c48185016134ec565b6000602082840312156136ca57600080fd5b8151610a5381612d2a565b600060018060a01b038086168352606060208401526136f7606084018661340c565b9150808416604084015250949350505050565b60006040828403121561371c57600080fd5b604051604081018181106001600160401b038211171561373e5761373e613259565b8060405250809150825161375181612d2a565b8152602092830151920191909152919050565b600080600060a0848603121561377957600080fd5b613783858561370a565b9250613792856040860161370a565b9150608084015190509250925092565b6000602082840312156137b457600080fd5b8151610a5381612fc456fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212205d4d1751797d8d2bb0a57abf8b79b248b2c6dc6d8c1b68118b605d999e1abfdf64736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| 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) | ||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x34a3d2…af6a5e | 27 days agoTue, 21 Jul 2026 19:41:10 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000008 data: 0x000000000000000000…6a5fcc82 |
| 0x34a3d2…af6a5e | 27 days agoTue, 21 Jul 2026 19:41:10 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000007 data: 0x000000000000000000…00000000 |
| 0xe3ae6c…f604ad | 27 days agoTue, 21 Jul 2026 19:41:09 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000000 [1] 0x000000000000…0000000c data: 0x000000000000000000…6a5fcc81 |
| 0xe3ae6c…f604ad | 27 days agoTue, 21 Jul 2026 19:41:09 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000000 [1] 0x000000000000…0000000b data: 0x000000000000000000…00000000 |
| 0xd3668f…6c58ea | 27 days agoTue, 21 Jul 2026 19:38:14 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000006 data: 0x000000000000000000…6a5fcbd2 |
| 0xd3668f…6c58ea | 27 days agoTue, 21 Jul 2026 19:38:14 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000005 data: 0x000000000000000000…00000000 |
| 0x6d1ef2…141bed | 27 days agoTue, 21 Jul 2026 19:34:11 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000007 data: 0x000000000000000000…6a5fcadf |
| 0x6d1ef2…141bed | 27 days agoTue, 21 Jul 2026 19:34:11 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000006 data: 0x000000000000000000…00000000 |
| 0x5e8bd0…f1b613 | 27 days agoTue, 21 Jul 2026 19:34:09 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000000 [1] 0x000000000000…0000000b data: 0x000000000000000000…6a5fcadd |
| 0x5e8bd0…f1b613 | 27 days agoTue, 21 Jul 2026 19:34:09 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000000 [1] 0x000000000000…0000000a data: 0x000000000000000000…00000000 |
| 0x401594…1941ff | 27 days agoTue, 21 Jul 2026 19:28:11 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000005 data: 0x000000000000000000…6a5fc977 |
| 0x401594…1941ff | 27 days agoTue, 21 Jul 2026 19:28:11 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000004 data: 0x000000000000000000…00000000 |
| 0x88d425…1c6f1f | 27 days agoTue, 21 Jul 2026 19:28:10 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000006 data: 0x000000000000000000…6a5fc976 |
| 0x88d425…1c6f1f | 27 days agoTue, 21 Jul 2026 19:28:10 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000005 data: 0x000000000000000000…00000000 |
| 0x581288…69e85f | 27 days agoTue, 21 Jul 2026 19:27:08 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000000 [1] 0x000000000000…0000000a data: 0x000000000000000000…6a5fc938 |
| 0x581288…69e85f | 27 days agoTue, 21 Jul 2026 19:27:08 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000000 [1] 0x000000000000…00000009 data: 0x000000000000000000…00000000 |
| 0xa06efc…fc2166 | 27 days agoTue, 21 Jul 2026 19:23:09 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000004 data: 0x000000000000000000…6a5fc849 |
| 0xa06efc…fc2166 | 27 days agoTue, 21 Jul 2026 19:23:09 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000003 data: 0x000000000000000000…00000000 |
| 0xce845c…34d9f7 | 27 days agoTue, 21 Jul 2026 19:22:16 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000005 data: 0x000000000000000000…6a5fc814 |
| 0xce845c…34d9f7 | 27 days agoTue, 21 Jul 2026 19:22:16 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000004 data: 0x000000000000000000…00000000 |
| 0xc598ee…b374b1 | 27 days agoTue, 21 Jul 2026 19:20:10 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000000 [1] 0x000000000000…00000009 data: 0x000000000000000000…6a5fc796 |
| 0xc598ee…b374b1 | 27 days agoTue, 21 Jul 2026 19:20:10 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000000 [1] 0x000000000000…00000008 data: 0x000000000000000000…00000000 |
| 0x737546…946a21 | 27 days agoTue, 21 Jul 2026 19:14:11 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000003 data: 0x000000000000000000…6a5fc62f |
| 0x737546…946a21 | 27 days agoTue, 21 Jul 2026 19:14:11 UTC | 0xc2d5b3…7ef1 | [0] 0x000000000000…00000002 [1] 0x000000000000…00000002 data: 0x000000000000000000…00000000 |
| 0xcd737a…5007b5 | 27 days agoTue, 21 Jul 2026 19:14:09 UTC | 0xd39d49…d922 | [0] 0x000000000000…00000001 [1] 0x000000000000…00000004 data: 0x000000000000000000…6a5fc62d |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x34a3d2…af6a5e | turnWithPrice | 15,822,284 | 27 days agoTue, 21 Jul 2026 19:41:10 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001074 | |
| 0xe3ae6c…f604ad | turnWithPrice | 15,822,271 | 27 days agoTue, 21 Jul 2026 19:41:09 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001034 | |
| 0xd3668f…6c58ea | turnWithPrice | 15,820,531 | 27 days agoTue, 21 Jul 2026 19:38:14 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001024 | |
| 0x6d1ef2…141bed | turnWithPrice | 15,818,089 | 27 days agoTue, 21 Jul 2026 19:34:11 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001018 | |
| 0x5e8bd0…f1b613 | turnWithPrice | 15,818,071 | 27 days agoTue, 21 Jul 2026 19:34:09 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001026 | |
| 0x401594…1941ff | turnWithPrice | 15,814,498 | 27 days agoTue, 21 Jul 2026 19:28:11 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001017 | |
| 0x88d425…1c6f1f | turnWithPrice | 15,814,487 | 27 days agoTue, 21 Jul 2026 19:28:10 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001015 | |
| 0x581288…69e85f | turnWithPrice | 15,813,866 | 27 days agoTue, 21 Jul 2026 19:27:08 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001029 | |
| 0xa06efc…fc2166 | turnWithPrice | 15,811,492 | 27 days agoTue, 21 Jul 2026 19:23:09 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001011 | |
| 0xce845c…34d9f7 | turnWithPrice | 15,810,951 | 27 days agoTue, 21 Jul 2026 19:22:16 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001019 | |
| 0xc598ee…b374b1 | turnWithPrice | 15,809,698 | 27 days agoTue, 21 Jul 2026 19:20:10 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001019 | |
| 0x737546…946a21 | turnWithPrice | 15,806,105 | 27 days agoTue, 21 Jul 2026 19:14:11 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001023 | |
| 0xcd737a…5007b5 | turnWithPrice | 15,806,094 | 27 days agoTue, 21 Jul 2026 19:14:09 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001032 | |
| 0x3f5f84…9bf411 | turnWithPrice | 15,806,080 | 27 days agoTue, 21 Jul 2026 19:14:08 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001012 | |
| 0xa73021…c161b9 | turnWithPrice | 15,803,101 | 27 days agoTue, 21 Jul 2026 19:09:10 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001019 | |
| 0x7319de…b5229a | turnWithPrice | 15,803,090 | 27 days agoTue, 21 Jul 2026 19:09:09 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001023 | |
| 0x58bfa8…8457c1 | turnWithPrice | 15,803,074 | 27 days agoTue, 21 Jul 2026 19:09:07 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001034 | |
| 0x559ae8…b0a30b | turnWithPrice | 15,799,606 | 27 days agoTue, 21 Jul 2026 19:03:18 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001025 | |
| 0x67e24b…bd6fc9 | turnWithPrice | 15,798,899 | 27 days agoTue, 21 Jul 2026 19:02:09 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001003 | |
| 0xb1379c…7836b7 | turnWithPrice | 15,796,479 | 27 days agoTue, 21 Jul 2026 18:58:05 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00000879 | |
| 0xdb8d6d…81ed91 | turnWithPrice | 15,796,468 | 27 days agoTue, 21 Jul 2026 18:58:04 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00000878 | |
| 0xc5f75a…ee78c7 | transferOwnership | 15,794,944 | 27 days agoTue, 21 Jul 2026 18:55:33 UTC | 0x40f5…c8e3 | IN | RoundArena | $0.000 ETH | 0.00000203 | |
| 0xe598ef…0578b6 | addKeeperMarket | 15,794,900 | 27 days agoTue, 21 Jul 2026 18:55:28 UTC | 0x40f5…c8e3 | IN | RoundArena | $0.000 ETH | 0.00000658 | |
| 0xa50489…086b2b | addKeeperMarket | 15,794,872 | 27 days agoTue, 21 Jul 2026 18:55:25 UTC | 0x40f5…c8e3 | IN | RoundArena | $0.000 ETH | 0.00000661 | |
| 0xe76677…55a45a | turnWithPrice | 15,794,100 | 27 days agoTue, 21 Jul 2026 18:54:08 UTC | 0x0885…1955 | IN | RoundArena | $0.000 ETH | 0.00001001 |