// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20, IStackVault} from "./Interfaces.sol";
import {IStackBuyer} from "./IStackBuyer.sol";
import {StackBuyerV3} from "./StackBuyerV3.sol";
interface IStackersRead {
function ownerOf(uint256 tokenId) external view returns (address);
function isActive(uint256 tokenId) external view returns (bool);
function weightOf(uint256 tokenId) external view returns (uint256);
function parts(uint256 tokenId) external view returns (uint8);
function fusedArt(uint256 tokenId) external view returns (uint32);
function artworkOf(uint256 tokenId) external view returns (uint256);
}
interface IReforgeRead {
function extra(uint256 tokenId) external view returns (uint256);
}
/// The previous engine, read once per token at adoption so nobody's picks
/// reset when the engine changes.
interface IPrevEngine {
function splitOf(uint256 tokenId) external view returns (uint8[3] memory, uint16[3] memory, uint8);
function collectToWallet(uint256 tokenId) external view returns (bool);
}
/// The earnings engine, third attempt. See ENGINE_V3.md for the design.
///
/// What is new against V2, in one breath: an asset is bought through a route
/// of up to four legs on V2, V3 or V4 pools instead of two fixed V3 pools, so
/// anything with liquidity on this chain can be earned and the route can move
/// when the liquidity does; the price floor is either the V3 TWAP or the
/// engine's own hourly observations, so a V4 or V2 route is never bought
/// blind; a per-asset cap keeps a thin pool from taking the whole hour;
/// reforged weight is read natively; a moved Stacker is dropped at delivery
/// whether or not anyone synced it; and a fused Stacker's absorbed parts have
/// a path for their credit and their vault balance to follow the survivor.
contract StackRoundsV3 {
// ---------------------------------------------------------------- errors
error NotAuthorized();
error BadConfig();
error BadAsset();
error BadRoute();
error Reentrant();
error NotBurned();
error NotAbsorbedBy();
error NoFloor();
error BelowFloor();
error SendFailed();
// ---------------------------------------------------------------- events
event RoundSettled(uint256 indexed round, uint256 pot, uint256 totalWeight);
event Synced(uint256 indexed tokenId, uint256 weight, uint256 liveFrom);
event Delivered(uint256 indexed tokenId, uint8 indexed assetIdx, uint256 ethIn, uint256 out);
event SwapSkipped(uint8 indexed assetIdx, uint256 ethAmount);
event CreditRolled(uint256 indexed tokenId, uint8 indexed assetIdx, uint256 ethAmount);
event SplitSet(uint256 indexed tokenId, uint8 count);
event AssetAdded(uint8 indexed idx, address token, bool isStock, uint8 floorMode);
event RouteSet(uint8 indexed idx, uint8 legs);
event AssetTuned(uint8 indexed idx, uint16 slipBps, uint256 maxPerRound);
event Observed(uint8 indexed idx, uint256 quotePerEth);
event Absorbed(uint256 indexed survivorId, uint256 indexed deadId, uint256 creditMoved);
event Rescued(address indexed token, address indexed to, uint256 amount);
event OwnershipOffered(address indexed to);
event OwnershipTaken(address indexed by);
event OperatorSet(address indexed operator);
// ---------------------------------------------------------------- config
uint256 public constant ROUND = 3600;
uint8 public constant MAX_ASSETS = 64;
uint8 internal constant MAX_LEGS = 4;
uint32 internal constant TWAP_WINDOW = 1800;
uint16 internal constant MAX_SLIP_BPS = 1000;
/// Delivery and observation are the keeper's while it is alive. If it has
/// not delivered for this many rounds, anyone may, so a dead keeper can
/// never lock holders' money; while it is alive nobody else can choose
/// the moment a buy or a price reading happens.
uint256 internal constant KEEPER_STALE_ROUNDS = 4;
/// A new route must quote within this of the old one, so re-routing
/// cannot quietly point holders' ETH at a pool priced far from market.
uint256 internal constant ROUTE_DRIFT_BPS = 1500;
/// The floor for an observed asset is the keeper's freshest reading, the
/// way a bot quotes just before it buys: the market price at that moment,
/// whatever it moved since. The buy fills within `slipBps` of it, every
/// hour, on the hour. No brake on how far the price moved: that is the
/// protocol, and the per-round cap is what bounds any one hour.
/// A reading is a price for the round it was taken in and the next one.
uint64 internal constant OBS_MAX_AGE = 1;
uint16 internal constant DEFAULT_SLIP_BPS = 300;
uint8 internal constant OBS = 3;
uint8 internal constant FLOOR_TWAP = 1;
uint8 internal constant FLOOR_OBS = 2;
address public owner;
address public pendingOwner;
/// The keeper. Runs the hourly duties (observe, deliver) and fusion
/// follow-through (absorb), none of which can move money anywhere the
/// chain does not already dictate. Cannot adopt, touch routes, assets,
/// the vault, or any ETH.
address public operator;
address public immutable nft;
address public immutable weth;
IStackBuyer public immutable buyer;
address public immutable reforge;
address public immutable prev;
address public vault;
uint256 public minSwap = 0.01 ether;
struct Asset {
address token;
bool isStock;
bool exists;
uint8 floorMode;
uint8 legCount;
uint16 slipBps;
uint256 maxPerRound; // 0 = no cap
}
Asset[MAX_ASSETS] public assets;
mapping(uint8 => IStackBuyer.Leg[MAX_LEGS]) internal legs;
uint8 public assetCount;
/// The engine's own hourly price record for OBS mode: the route's spot
/// quote for 1 ETH, taken at each settle. Median of the last three is the
/// floor. Zero entries are "not yet observed" and are ignored.
mapping(uint8 => uint256[OBS]) internal obs;
mapping(uint8 => uint64[OBS]) internal obsRound;
mapping(uint8 => uint8) internal obsIdx;
/// a route may change once per round, so bounded steps cannot be chained
/// into a leap inside one hour
mapping(uint8 => uint256) internal routeRound;
/// the cap is per round, however many delivery batches the round has:
/// what has been bought of an asset this round, and which round that was
mapping(uint8 => uint256) public spentInRound;
mapping(uint8 => uint256) internal spentRound;
/// the round the keeper (owner or operator) last observed or delivered
/// in; the public fallback keys off it, and only the keeper moves it
uint256 public lastKeeperRound;
/// a token's split and collect mode are copied from the previous engine
/// once, never again, so a holder's later choice here is never overwritten
mapping(uint256 => bool) public prefsImported;
struct Split {
uint8[3] idx;
uint16[3] bps;
uint8 count;
}
mapping(uint256 => Split) internal splits;
struct TokenState {
uint128 weight; // as counted by this engine
uint128 creditedEth; // earned, not yet delivered
uint256 debt; // accPerWeight at the last weight change
bool live; // counted in totalWeight
uint64 liveFrom; // the first round it may earn in, or that a parked rise applies from
uint128 nextWeight; // a rise waiting for the round to turn; zero when none
}
mapping(uint256 => TokenState) public tokenState;
uint256 public totalWeight;
uint256 public accPerWeight;
uint256 public potBuffer;
uint256 public lastSettledRound;
uint256 public lastObservedRound;
mapping(uint256 => mapping(uint8 => uint256)) public owedToken;
/// everything currently owed of a token, so a rescue can never take it
mapping(address => uint256) public owedTotal;
mapping(uint256 => bool) public collectToWallet;
uint256 private _lock = 1;
/// While a buy is in flight, ETH arriving here (unwrapped WETH, native
/// taken from a V4 pool) is the buy's own money, not a fee.
bool private _inSwap;
modifier lock() {
if (_lock != 1) revert Reentrant();
_lock = 2;
_;
_lock = 1;
}
modifier onlyOwner() {
if (msg.sender != owner) revert NotAuthorized();
_;
}
modifier onlyKeeper() {
if (msg.sender != owner && msg.sender != operator) revert NotAuthorized();
_;
}
/// The engine deploys its own buyer, bound to it, so the two can never be
/// mismatched and nobody can point the engine at a different executor.
constructor(
address nft_,
address weth_,
address router_,
address factory_,
address poolManager_,
address reforge_,
address prev_
) {
if (nft_ == address(0)) revert BadConfig();
owner = msg.sender;
nft = nft_;
buyer = IStackBuyer(address(new StackBuyerV3(weth_, router_, factory_, poolManager_, address(this))));
weth = weth_;
reforge = reforge_;
prev = prev_;
lastSettledRound = block.timestamp / ROUND;
// the keeper is alive at birth: nobody else delivers or observes
// until it has actually been quiet for KEEPER_STALE_ROUNDS
lastKeeperRound = lastSettledRound;
}
/// Fees arrive here. During a buy, ETH is the buy's own and is not a fee.
/// Closes the round if one has ended, but takes no price observations:
/// a plain transfer must never need more gas than a plain transfer.
receive() external payable {
if (_inSwap) return;
_closeRound();
potBuffer += msg.value;
}
function currentRound() public view returns (uint256) {
return block.timestamp / ROUND;
}
// ---------------------------------------------------------------- rounds
/// Close the hour: hand the pot to whoever was live for it. Anyone.
function settle() public {
_closeRound();
}
/// Record this hour's price for every OBS asset. Once per round, and only
/// ever by the keeper: an observation taken at a moment an outsider chose,
/// in a transaction an outsider built, is not a price. If the keeper is
/// dead the ring ages out and observed-floor buys wait (credit rolls,
/// nothing is lost); TWAP assets and everything else carry on, and anyone
/// may deliver them once the keeper is stale.
function observe() public {
_closeRound();
if (!_isKeeper()) revert NotAuthorized();
lastKeeperRound = currentRound();
if (lastObservedRound < lastSettledRound) {
lastObservedRound = lastSettledRound;
_observeAll();
}
}
function _isKeeper() internal view returns (bool) {
return msg.sender == owner || msg.sender == operator;
}
function _keeperOrStale() internal view returns (bool) {
if (_isKeeper()) return true;
return currentRound() > lastKeeperRound + KEEPER_STALE_ROUNDS;
}
function _closeRound() internal {
uint256 nowRound = currentRound();
if (nowRound <= lastSettledRound) return;
if (totalWeight > 0 && potBuffer > 0) {
accPerWeight += (potBuffer * 1e18) / totalWeight;
emit RoundSettled(nowRound, potBuffer, totalWeight);
potBuffer = 0;
}
lastSettledRound = nowRound;
}
/// Bring these tokens' weights in line with the NFT (and the reforge
/// contract). Permissionless: the numbers come from the chain, so the
/// caller cannot influence them. A rise counts from the next round; a fall
/// applies at once.
function sync(uint256[] calldata ids) external {
settle();
uint256 nowRound = currentRound();
for (uint256 i = 0; i < ids.length; i++) {
_syncOne(ids[i], nowRound);
}
}
function _syncOne(uint256 id, uint256 nowRound) internal {
TokenState storage t = tokenState[id];
// bank what it has earned at the weight it actually held
if (t.live) {
t.creditedEth += uint128((uint256(t.weight) * (accPerWeight - t.debt)) / 1e18);
}
t.debt = accPerWeight;
// a rise parked earlier applies once its round has come. The round it
// was parked in has been settled by now (sync settles first), at the
// old weight, which is the whole point.
if (t.live && t.nextWeight != 0 && nowRound >= t.liveFrom) {
totalWeight = totalWeight - t.weight + t.nextWeight;
t.weight = t.nextWeight;
t.nextWeight = 0;
}
uint256 w = _liveWeight(id);
if (w == 0) {
if (t.live) {
totalWeight -= t.weight;
t.live = false;
}
t.weight = 0;
t.nextWeight = 0;
// a token that sleeps and wakes serves the waiting round again.
// Left as it was, the old admission round let it straight back in.
t.liveFrom = 0;
emit Synced(id, 0, 0);
return;
}
if (!t.live) {
// waiting to be admitted: record the weight, set the waiting round
// once, and never push it out on a re-sync
t.weight = uint128(w);
t.nextWeight = 0;
if (t.liveFrom == 0) t.liveFrom = uint64(nowRound + 1);
emit Synced(id, w, t.liveFrom);
} else if (w < t.weight) {
// a fall applies at once, and cancels any parked rise
totalWeight = totalWeight - t.weight + w;
t.weight = uint128(w);
t.nextWeight = 0;
emit Synced(id, w, nowRound);
} else if (w > t.weight) {
// a rise waits for the round to turn: parked, not counted yet
if (t.nextWeight != uint128(w)) {
t.nextWeight = uint128(w);
t.liveFrom = uint64(nowRound + 1);
emit Synced(id, w, t.liveFrom);
}
} else if (t.nextWeight != 0) {
// back to exactly the counted weight before the rise landed
t.nextWeight = 0;
}
if (!t.live && t.liveFrom != 0 && nowRound >= t.liveFrom) {
t.live = true;
totalWeight += t.weight;
}
}
/// The weight this engine counts for a token right now: the NFT's own
/// figure plus reforged weight scaled by the same fuse bonus the NFT
/// applies. Zero if asleep.
function _liveWeight(uint256 id) internal view returns (uint256 w) {
if (!IStackersRead(nft).isActive(id)) return 0;
w = IStackersRead(nft).weightOf(id);
if (w == 0 || reforge == address(0)) return w;
uint8 p = IStackersRead(nft).parts(id);
if (p < 2) return w;
uint256 x = IReforgeRead(reforge).extra(id);
if (x == 0) return w;
w += (x * (p >= 3 ? 13_000 : 12_000)) / 10_000;
}
/// Admit these tokens at once, without the waiting round. Migration only:
/// they served their round on the previous engine. Owner only, weights
/// still read from the chain, and each token's split and collect mode
/// are copied from the previous engine once, if it has none here.
function adopt(uint256[] calldata ids) external onlyOwner {
settle();
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
TokenState storage t = tokenState[id];
_importPrefs(id);
if (t.live) continue;
uint256 w = _liveWeight(id);
if (w == 0) continue;
t.weight = uint128(w);
t.debt = accPerWeight;
t.live = true;
t.liveFrom = uint64(currentRound());
totalWeight += w;
emit Synced(id, w, t.liveFrom);
}
}
function _importPrefs(uint256 id) internal {
if (prev == address(0) || prefsImported[id]) return;
prefsImported[id] = true;
if (splits[id].count == 0) {
try IPrevEngine(prev).splitOf(id) returns (uint8[3] memory idx, uint16[3] memory bps, uint8 count) {
if (count > 0 && count <= 3) {
bool ok = true;
uint256 sum;
for (uint256 j = 0; j < count; j++) {
if (idx[j] >= assetCount || !assets[idx[j]].exists) ok = false;
sum += bps[j];
}
if (ok && sum == 10_000) {
Split storage s = splits[id];
s.idx = idx;
s.bps = bps;
s.count = count;
emit SplitSet(id, count);
}
}
} catch {}
}
try IPrevEngine(prev).collectToWallet(id) returns (bool toWallet) {
if (toWallet) collectToWallet[id] = true;
} catch {}
}
/// What a token has earned but not yet been paid.
function pendingEth(uint256 tokenId) external view returns (uint256) {
TokenState storage t = tokenState[tokenId];
uint256 acc = t.creditedEth;
if (t.live) acc += (uint256(t.weight) * (accPerWeight - t.debt)) / 1e18;
return acc;
}
/// Fusion follow-through. The NFT burned `deadIds` into `survivor`; this
/// moves their undelivered credit to the survivor and their vault
/// balances with it. Only a token the NFT reports as burned can be
/// absorbed, and only into the survivor the NFT records as having taken
/// it, so this cannot be pointed at a live token or a wrong one. Owner or
/// operator (the keeper watches the Fused event), or anyone once the
/// keeper is stale.
function absorb(uint256 survivor, uint256[] calldata deadIds) external lock {
if (!_keeperOrStale()) revert NotAuthorized();
settle();
TokenState storage s = tokenState[survivor];
for (uint256 i = 0; i < deadIds.length; i++) {
uint256 dead = deadIds[i];
if (dead == survivor) revert BadConfig();
try IStackersRead(nft).ownerOf(dead) returns (address) {
revert NotBurned();
} catch {}
// The NFT remembers, on the survivor, the artwork of every part
// it took (two 16-bit slots), and the dead token's artwork
// outlives its burn. So the pairing is provable here, and a
// wrong survivor cannot be given someone else's stranded credit.
uint32 marks = IStackersRead(nft).fusedArt(survivor);
uint16 art = uint16(IStackersRead(nft).artworkOf(dead));
if (art == 0 || (uint16(marks) != art && uint16(marks >> 16) != art)) revert NotAbsorbedBy();
TokenState storage d = tokenState[dead];
uint256 credit = d.creditedEth;
if (d.live) {
credit += (uint256(d.weight) * (accPerWeight - d.debt)) / 1e18;
totalWeight -= d.weight;
d.live = false;
}
d.creditedEth = 0;
d.weight = 0;
d.nextWeight = 0;
d.liveFrom = 0;
d.debt = accPerWeight;
s.creditedEth += uint128(credit);
for (uint8 a = 0; a < assetCount; a++) {
uint256 owed = owedToken[dead][a];
if (owed != 0) {
owedToken[dead][a] = 0;
owedToken[survivor][a] += owed;
}
}
if (vault != address(0)) IStackVault(vault).merge(survivor, dead);
emit Absorbed(survivor, dead, credit);
}
}
// ---------------------------------------------------------------- splits
function setSplit(uint256 tokenId, uint8[] calldata idx, uint16[] calldata bps) external {
if (IStackersRead(nft).ownerOf(tokenId) != msg.sender) revert NotAuthorized();
if (idx.length == 0 || idx.length > 3 || idx.length != bps.length) revert BadConfig();
uint256 sum;
Split storage s = splits[tokenId];
for (uint256 i = 0; i < idx.length; i++) {
if (idx[i] >= assetCount || !assets[idx[i]].exists) revert BadAsset();
for (uint256 j = 0; j < i; j++) {
if (idx[j] == idx[i]) revert BadConfig();
}
s.idx[i] = idx[i];
s.bps[i] = bps[i];
sum += bps[i];
}
if (sum != 10_000) revert BadConfig();
s.count = uint8(idx.length);
emit SplitSet(tokenId, s.count);
}
function splitOf(uint256 tokenId) external view returns (uint8[3] memory, uint16[3] memory, uint8) {
Split storage s = splits[tokenId];
return (s.idx, s.bps, s.count);
}
function setCollectMode(uint256 tokenId, bool toWallet) external {
if (IStackersRead(nft).ownerOf(tokenId) != msg.sender) revert NotAuthorized();
collectToWallet[tokenId] = toWallet;
}
function _defaultIdx() internal view returns (uint8) {
for (uint8 i = 0; i < assetCount; i++) {
if (assets[i].exists && !assets[i].isStock) return i;
}
return 0;
}
// ---------------------------------------------------------------- deliver
/// Turn credit into the assets each Stacker chose. One buy per asset, then
/// pro rata to the holders who paid into it. A failure on one asset can
/// never cost anyone else their round: the credit is handed straight back.
///
/// Every token is checked against the NFT first: one that is asleep but
/// still live here (moved since its last sync) has its credit banked and
/// its weight dropped before anything is paid.
function deliver(uint256[] calldata ids) external lock {
if (!_keeperOrStale()) revert NotAuthorized();
_closeRound();
uint256 nowRound = currentRound();
if (_isKeeper()) lastKeeperRound = nowRound;
uint256 n = ids.length;
uint256[MAX_ASSETS] memory assetPot;
uint256[3][] memory portions = new uint256[3][](n);
uint8[3][] memory slotAsset = new uint8[3][](n);
uint8[] memory slotCount = new uint8[](n);
for (uint256 i = 0; i < n; i++) {
uint256 id = ids[i];
TokenState storage t = tokenState[id];
if (t.live && !IStackersRead(nft).isActive(id)) {
_syncOne(id, nowRound); // banks its credit and drops it
}
uint256 credit = t.creditedEth;
if (t.live) {
credit += (uint256(t.weight) * (accPerWeight - t.debt)) / 1e18;
t.debt = accPerWeight;
}
if (credit == 0) continue;
Split storage s = splits[id];
uint8 count = s.count;
uint8[3] memory useIdx;
uint16[3] memory useBps;
if (count == 0) {
count = 1;
useIdx[0] = _defaultIdx();
useBps[0] = 10_000;
} else {
useIdx = s.idx;
useBps = s.bps;
}
t.creditedEth = 0;
slotCount[i] = count;
uint256 used;
for (uint256 j = 0; j < count; j++) {
uint256 part = j + 1 == count ? credit - used : (credit * useBps[j]) / 10_000;
used += part;
portions[i][j] = part;
slotAsset[i][j] = useIdx[j];
assetPot[useIdx[j]] += part;
}
}
// one buy per asset, capped, isolated
uint256[MAX_ASSETS] memory bought;
uint256[MAX_ASSETS] memory spent;
for (uint8 a = 0; a < assetCount; a++) {
uint256 pot = assetPot[a];
if (pot == 0 || pot < minSwap) continue;
uint256 cap = assets[a].maxPerRound;
uint256 amt = pot;
if (cap != 0) {
if (spentRound[a] != nowRound) {
spentRound[a] = nowRound;
spentInRound[a] = 0;
}
uint256 room = cap > spentInRound[a] ? cap - spentInRound[a] : 0;
if (amt > room) amt = room;
}
if (amt < minSwap) continue;
try this.swapFor(a, amt) returns (uint256 out, uint256 used) {
bought[a] = out;
spent[a] = used;
if (cap != 0) spentInRound[a] += used;
} catch {
emit SwapSkipped(a, amt);
}
}
// pro rata back, roll what was not spent
for (uint256 i = 0; i < n; i++) {
uint256 id = ids[i];
for (uint256 j = 0; j < slotCount[i]; j++) {
uint256 part = portions[i][j];
if (part == 0) continue;
uint8 a = slotAsset[i][j];
if (spent[a] == 0) {
tokenState[id].creditedEth += uint128(part);
emit CreditRolled(id, a, part);
continue;
}
// what the cap left unspent goes back, rounded DOWN, so the
// sum of rolls never exceeds what was actually kept; what was
// spent stays spent even if this share of the buy rounds to
// nothing, so credit never exceeds the ETH behind it
uint256 roll = (part * (assetPot[a] - spent[a])) / assetPot[a];
uint256 ethIn = part - roll;
uint256 out = (bought[a] * part) / assetPot[a];
if (roll > 0) {
tokenState[id].creditedEth += uint128(roll);
emit CreditRolled(id, a, roll);
}
if (out == 0) continue;
bool paid;
if (collectToWallet[id] || vault == address(0)) {
// a token burned since its credit was earned has no owner
// to pay: it goes to owed, and follows the survivor in absorb
try IStackersRead(nft).ownerOf(id) returns (address holder) {
paid = _payout(assets[a].token, holder, out);
} catch {
paid = false;
}
} else {
try this.vaultCredit(id, a, out) {
paid = true;
} catch {
paid = false;
}
}
if (paid) {
emit Delivered(id, a, ethIn, out);
} else {
owedToken[id][a] += out; // claimable later, never lost
owedTotal[assets[a].token] += out;
}
}
}
}
/// External so `deliver` can wrap it in try/catch. Self call only.
function swapFor(uint8 a, uint256 ethIn) external returns (uint256, uint256) {
if (msg.sender != address(this)) revert NotAuthorized();
return _buy(a, ethIn);
}
function vaultCredit(uint256 tokenId, uint8 a, uint256 out) external {
if (msg.sender != address(this)) revert NotAuthorized();
address token = assets[a].token;
uint256 before = IERC20(token).balanceOf(vault);
if (!_payout(token, vault, out)) revert BadConfig();
uint256 got = IERC20(token).balanceOf(vault) - before;
if (got == 0) revert BadConfig();
IStackVault(vault).credit(tokenId, a, token, got);
}
function claimOwed(uint256 tokenId, uint8 assetIdx) external lock {
uint256 amount = owedToken[tokenId][assetIdx];
if (amount == 0) revert BadConfig();
address holder = IStackersRead(nft).ownerOf(tokenId);
owedToken[tokenId][assetIdx] = 0;
address tok = assets[assetIdx].token;
owedTotal[tok] -= amount;
if (!_payout(tok, holder, amount)) {
owedToken[tokenId][assetIdx] = amount;
owedTotal[tok] += amount;
revert BadConfig();
}
emit Delivered(tokenId, assetIdx, 0, amount);
}
function _payout(address token, address to, uint256 amount) internal returns (bool) {
(bool ok, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, amount));
return ok && (data.length == 0 || abi.decode(data, (bool)));
}
// ---------------------------------------------------------------- buying
/// Buy asset `a` with `ethIn` of the pot through its route. Reverts if the
/// floor cannot be met, cannot be computed, or any leg fails; the caller
/// (deliver) treats that as a skip. The buyer does the legs; this
/// contract measures what actually arrived and holds the line on the
/// floor itself, so a fee-on-transfer token or a hook cannot pass more
/// than was received.
function _buy(uint8 a, uint256 ethIn) internal returns (uint256 out, uint256 spent) {
Asset storage ast = assets[a];
if (!ast.exists) revert BadAsset();
uint256 minOut = floorQuote(a, ethIn);
if (minOut == 0) revert NoFloor();
uint256 before = IERC20(ast.token).balanceOf(address(this));
_inSwap = true;
(, spent) = buyer.buy{value: ethIn}(_route(a), minOut);
_inSwap = false;
out = IERC20(ast.token).balanceOf(address(this)) - before;
if (out < minOut) revert BelowFloor();
if (spent > ethIn) spent = ethIn;
// ETH the route did not consume came back and is reported as unspent:
// deliver rolls it to the tokens it belonged to, pro rata
}
function _route(uint8 a) internal view returns (IStackBuyer.Leg[] memory r) {
uint8 n = assets[a].legCount;
r = new IStackBuyer.Leg[](n);
for (uint8 j = 0; j < n; j++) {
r[j] = legs[a][j];
}
}
// ---------------------------------------------------------------- pricing
/// The route's spot quote for `ethIn`. Zero if any leg cannot be priced.
function spotQuote(uint8 a, uint256 ethIn) public view returns (uint256) {
if (!assets[a].exists) return 0;
return buyer.spotQuote(_route(a), ethIn);
}
/// The V3 TWAP through the route, for TWAP mode. Reverts if a pool has
/// too little history, which the caller treats as "cannot price".
function twapQuote(uint8 a, uint256 ethIn) public view returns (uint256) {
if (!assets[a].exists) revert BadAsset();
return buyer.twapQuote(_route(a), ethIn, TWAP_WINDOW);
}
/// The least this engine will accept for `ethIn` of asset `a`: the
/// reference quote less the asset's slip. Zero means "cannot price".
function floorQuote(uint8 a, uint256 ethIn) public view returns (uint256) {
Asset storage ast = assets[a];
if (!ast.exists) return 0;
uint256 q;
if (ast.floorMode == FLOOR_TWAP) {
try this.twapQuote(a, ethIn) returns (uint256 t) {
q = t;
} catch {
return 0;
}
} else {
uint256 per = _reference(a);
if (per == 0) return 0;
q = (per * ethIn) / 1e18;
}
return (q * (10_000 - ast.slipBps)) / 10_000;
}
/// The reference price for OBS mode: the keeper's newest reading, if it
/// was taken this round or last. Only the keeper ever records one, in
/// its own transaction, moments before it delivers: a quote before the
/// buy, exactly as a bot works. Older than that there is no floor and
/// the asset waits for the next reading rather than buying blind.
function _reference(uint8 a) internal view returns (uint256) {
uint8 i = obsIdx[a];
uint8 last = i == 0 ? OBS - 1 : i - 1;
uint256 q = obs[a][last];
uint64 at = obsRound[a][last];
uint64 nowRound = uint64(currentRound());
if (q == 0 || at > nowRound || at + OBS_MAX_AGE < nowRound) return 0;
return q;
}
function observations(uint8 a) external view returns (uint256[OBS] memory, uint64[OBS] memory) {
return (obs[a], obsRound[a]);
}
/// One observation per OBS asset per round: the route's spot quote as it
/// stands, unadjusted. A zero or failed quote is skipped so a broken
/// venue cannot poison the ring or block the round.
function _observeAll() internal {
uint64 nowRound = uint64(currentRound());
for (uint8 a = 0; a < assetCount; a++) {
if (!assets[a].exists || assets[a].floorMode != FLOOR_OBS) continue;
uint256 q;
try this.spotQuote(a, 1e18) returns (uint256 got) {
q = got;
} catch {
continue;
}
if (q == 0) continue;
// one reading a round, the seed of a fresh route included
uint8 i = obsIdx[a];
uint8 last = i == 0 ? OBS - 1 : i - 1;
if (obs[a][last] != 0 && obsRound[a][last] == nowRound) continue;
obs[a][i] = q;
obsRound[a][i] = nowRound;
obsIdx[a] = (i + 1) % OBS;
emit Observed(a, q);
}
}
// ---------------------------------------------------------------- admin
function addAsset(
address token,
bool isStock,
uint8 floorMode,
uint16 slipBps,
uint256 maxPerRound,
IStackBuyer.Leg[] calldata route
) external onlyOwner {
if (assetCount >= MAX_ASSETS) revert BadConfig();
if (token == address(0)) revert BadConfig();
for (uint8 i = 0; i < assetCount; i++) {
if (assets[i].token == token) revert BadConfig();
}
if (floorMode != FLOOR_TWAP && floorMode != FLOOR_OBS) revert BadConfig();
if (slipBps == 0) slipBps = DEFAULT_SLIP_BPS;
if (slipBps > MAX_SLIP_BPS) revert BadConfig();
uint8 idx = assetCount;
assets[idx] = Asset({
token: token,
isStock: isStock,
exists: true,
floorMode: floorMode,
legCount: 0,
slipBps: slipBps,
maxPerRound: maxPerRound
});
assetCount++;
_setRoute(idx, route);
emit AssetAdded(idx, token, isStock, floorMode);
}
/// Replace an asset's route. Token, index, balances, splits, credit: untouched.
function setRoute(uint8 idx, IStackBuyer.Leg[] calldata route) external onlyOwner {
if (!assets[idx].exists) revert BadAsset();
_setRoute(idx, route);
}
function _setRoute(uint8 idx, IStackBuyer.Leg[] calldata route) internal {
Asset storage ast = assets[idx];
// shape, chaining, venue/token agreement: the buyer knows the venues
buyer.validate(route, ast.token);
if (ast.floorMode == FLOOR_TWAP && !buyer.allV3(route)) revert BadRoute();
// a replacement must price near what the engine already believes:
// the floor reference if it has one, else the old route's spot.
// Re-routing is for following liquidity, not for choosing a price,
// and it happens at most once a round.
if (ast.legCount != 0) {
if (routeRound[idx] == currentRound()) revert BadRoute();
routeRound[idx] = currentRound();
}
// two yardsticks: what the engine currently believes (the floor
// reference) and what the old route quotes now. The new route must
// sit within the drift of at least one, so a griefed ring cannot
// lock the owner out of an honest re-route, and a venue that has
// started reverting can still be left.
uint256 refQuote;
uint256 oldSpot;
if (ast.legCount != 0) {
uint256 f = floorQuote(idx, 1e18);
if (f != 0) refQuote = (f * 10_000) / (10_000 - ast.slipBps);
try this.spotQuote(idx, 1e18) returns (uint256 q0) {
oldSpot = q0;
} catch {}
}
for (uint8 j = 0; j < MAX_LEGS; j++) {
if (j < route.length) legs[idx][j] = route[j];
else delete legs[idx][j];
}
ast.legCount = uint8(route.length);
// the route must be priceable now, or it is the wrong route
uint256 q = spotQuote(idx, 1e18);
if (q == 0) revert BadRoute();
if (refQuote != 0 || oldSpot != 0) {
bool okRef = refQuote != 0 && _within(q, refQuote);
bool okSpot = oldSpot != 0 && _within(q, oldSpot);
if (!okRef && !okSpot) revert BadRoute();
}
// a new route means a new price series. It starts with one reading,
// tagged with this round, so no buy can happen on it until two more
// rounds have been observed: a route change is never a same-hour
// window.
delete obs[idx];
delete obsRound[idx];
obsIdx[idx] = 0;
if (ast.floorMode == FLOOR_OBS) {
obs[idx][0] = q;
obsRound[idx][0] = uint64(currentRound());
obsIdx[idx] = 1;
}
emit RouteSet(idx, uint8(route.length));
}
function _within(uint256 q, uint256 base) internal pure returns (bool) {
return q >= (base * (10_000 - ROUTE_DRIFT_BPS)) / 10_000 && q <= (base * (10_000 + ROUTE_DRIFT_BPS)) / 10_000;
}
function legOf(uint8 idx, uint8 j) external view returns (IStackBuyer.Leg memory) {
return legs[idx][j];
}
function tuneAsset(uint8 idx, uint16 slipBps, uint256 maxPerRound) external onlyOwner {
if (!assets[idx].exists) revert BadAsset();
if (slipBps == 0 || slipBps > MAX_SLIP_BPS) revert BadConfig();
assets[idx].slipBps = slipBps;
assets[idx].maxPerRound = maxPerRound;
emit AssetTuned(idx, slipBps, maxPerRound);
}
/// Once, from zero. The vault is where holders' assets live; it is not a
/// thing to be swapped underneath them.
function setVault(address v) external onlyOwner {
if (vault != address(0) || v == address(0)) revert BadConfig();
vault = v;
}
function setMinSwap(uint256 v) external onlyOwner {
minSwap = v;
}
function setOperator(address o) external onlyOwner {
operator = o;
emit OperatorSet(o);
}
function transferOwnership(address to) external onlyOwner {
pendingOwner = to;
emit OwnershipOffered(to);
}
function acceptOwnership() external {
if (msg.sender != pendingOwner || pendingOwner == address(0)) revert NotAuthorized();
owner = pendingOwner;
pendingOwner = address(0);
emit OwnershipTaken(owner);
}
/// The lesson from the first engine, kept from the second. Holder funds
/// must never depend on one code path working. Owner only, public on
/// chain, and the reason this engine can be retired safely.
function rescueEth(address to) external onlyOwner {
uint256 bal = address(this).balance;
(bool ok,) = to.call{value: bal}("");
if (!ok) revert SendFailed();
emit Rescued(address(0), to, bal);
}
function rescueToken(address token, address to) external onlyOwner {
uint256 bal = IERC20(token).balanceOf(address(this));
// what holders are owed of this token stays for them
uint256 keep = owedTotal[token];
bal = keep >= bal ? 0 : bal - keep;
if (!_payout(token, to, bal)) revert SendFailed();
emit Rescued(token, to, bal);
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "nft_",
"type": "address",
"internalType": "address"
},
{
"name": "weth_",
"type": "address",
"internalType": "address"
},
{
"name": "router_",
"type": "address",
"internalType": "address"
},
{
"name": "factory_",
"type": "address",
"internalType": "address"
},
{
"name": "poolManager_",
"type": "address",
"internalType": "address"
},
{
"name": "reforge_",
"type": "address",
"internalType": "address"
},
{
"name": "prev_",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "BadAsset",
"type": "error",
"inputs": []
},
{
"name": "BadConfig",
"type": "error",
"inputs": []
},
{
"name": "BadRoute",
"type": "error",
"inputs": []
},
{
"name": "BelowFloor",
"type": "error",
"inputs": []
},
{
"name": "NoFloor",
"type": "error",
"inputs": []
},
{
"name": "NotAbsorbedBy",
"type": "error",
"inputs": []
},
{
"name": "NotAuthorized",
"type": "error",
"inputs": []
},
{
"name": "NotBurned",
"type": "error",
"inputs": []
},
{
"name": "Reentrant",
"type": "error",
"inputs": []
},
{
"name": "SendFailed",
"type": "error",
"inputs": []
},
{
"name": "Absorbed",
"type": "event",
"inputs": [
{
"name": "survivorId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "deadId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "creditMoved",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "AssetAdded",
"type": "event",
"inputs": [
{
"name": "idx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "token",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "isStock",
"type": "bool",
"indexed": false,
"internalType": "bool"
},
{
"name": "floorMode",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
}
],
"anonymous": false
},
{
"name": "AssetTuned",
"type": "event",
"inputs": [
{
"name": "idx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "slipBps",
"type": "uint16",
"indexed": false,
"internalType": "uint16"
},
{
"name": "maxPerRound",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "CreditRolled",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "assetIdx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "ethAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Delivered",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "assetIdx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "ethIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "out",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Observed",
"type": "event",
"inputs": [
{
"name": "idx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "quotePerEth",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "OperatorSet",
"type": "event",
"inputs": [
{
"name": "operator",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipOffered",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTaken",
"type": "event",
"inputs": [
{
"name": "by",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Rescued",
"type": "event",
"inputs": [
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "RoundSettled",
"type": "event",
"inputs": [
{
"name": "round",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "pot",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "totalWeight",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "RouteSet",
"type": "event",
"inputs": [
{
"name": "idx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "legs",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
}
],
"anonymous": false
},
{
"name": "SplitSet",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "count",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
}
],
"anonymous": false
},
{
"name": "SwapSkipped",
"type": "event",
"inputs": [
{
"name": "assetIdx",
"type": "uint8",
"indexed": true,
"internalType": "uint8"
},
{
"name": "ethAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Synced",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "weight",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "liveFrom",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "MAX_ASSETS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "ROUND",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "absorb",
"type": "function",
"inputs": [
{
"name": "survivor",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "deadIds",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "accPerWeight",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "addAsset",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "isStock",
"type": "bool",
"internalType": "bool"
},
{
"name": "floorMode",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "slipBps",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "maxPerRound",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "route",
"type": "tuple[]",
"components": [
{
"name": "kind",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "tokenIn",
"type": "address",
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"internalType": "address"
},
{
"name": "venue",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct IStackBuyer.Leg[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "adopt",
"type": "function",
"inputs": [
{
"name": "ids",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "assetCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "assets",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "isStock",
"type": "bool",
"internalType": "bool"
},
{
"name": "exists",
"type": "bool",
"internalType": "bool"
},
{
"name": "floorMode",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "legCount",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "slipBps",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "maxPerRound",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "buyer",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IStackBuyer"
}
],
"stateMutability": "view"
},
{
"name": "claimOwed",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "assetIdx",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "collectToWallet",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "currentRound",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "deliver",
"type": "function",
"inputs": [
{
"name": "ids",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "floorQuote",
"type": "function",
"inputs": [
{
"name": "a",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "ethIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "lastKeeperRound",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "lastObservedRound",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "lastSettledRound",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "legOf",
"type": "function",
"inputs": [
{
"name": "idx",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "j",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "kind",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "tokenIn",
"type": "address",
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"internalType": "address"
},
{
"name": "venue",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct IStackBuyer.Leg"
}
],
"stateMutability": "view"
},
{
"name": "minSwap",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "nft",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "observations",
"type": "function",
"inputs": [
{
"name": "a",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "",
"type": "uint256[3]",
"internalType": "uint256[3]"
},
{
"name": "",
"type": "uint64[3]",
"internalType": "uint64[3]"
}
],
"stateMutability": "view"
},
{
"name": "observe",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "operator",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "owedToken",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owedTotal",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingEth",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "pendingOwner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "potBuffer",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "prefsImported",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "prev",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "reforge",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "rescueEth",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "rescueToken",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setCollectMode",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "toWallet",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMinSwap",
"type": "function",
"inputs": [
{
"name": "v",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setOperator",
"type": "function",
"inputs": [
{
"name": "o",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setRoute",
"type": "function",
"inputs": [
{
"name": "idx",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "route",
"type": "tuple[]",
"components": [
{
"name": "kind",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "tokenIn",
"type": "address",
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"internalType": "address"
},
{
"name": "venue",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct IStackBuyer.Leg[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setSplit",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "idx",
"type": "uint8[]",
"internalType": "uint8[]"
},
{
"name": "bps",
"type": "uint16[]",
"internalType": "uint16[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setVault",
"type": "function",
"inputs": [
{
"name": "v",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "settle",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "spentInRound",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "splitOf",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint8[3]",
"internalType": "uint8[3]"
},
{
"name": "",
"type": "uint16[3]",
"internalType": "uint16[3]"
},
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "spotQuote",
"type": "function",
"inputs": [
{
"name": "a",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "ethIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "swapFor",
"type": "function",
"inputs": [
{
"name": "a",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "ethIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "sync",
"type": "function",
"inputs": [
{
"name": "ids",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "tokenState",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "weight",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "creditedEth",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "debt",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "live",
"type": "bool",
"internalType": "bool"
},
{
"name": "liveFrom",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "nextWeight",
"type": "uint128",
"internalType": "uint128"
}
],
"stateMutability": "view"
},
{
"name": "totalWeight",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "tuneAsset",
"type": "function",
"inputs": [
{
"name": "idx",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "slipBps",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "maxPerRound",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "twapQuote",
"type": "function",
"inputs": [
{
"name": "a",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "ethIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "vault",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "vaultCredit",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "a",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "out",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "weth",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x610120604052662386f26fc100006004556001609955348015610020575f80fd5b50604051619ffc380380619ffc83398101604081905261003f9161014c565b6001600160a01b038716610066576040516301f30c8760e21b815260040160405180910390fd5b5f80546001600160a01b031916331790556001600160a01b0387166080526040518690869086908690309061009a90610124565b6001600160a01b0395861681529385166020850152918416604084015283166060830152909116608082015260a001604051809103905ff0801580156100e2573d5f803e3d5ffd5b506001600160a01b0390811660c05286811660a05282811660e05281166101005261010f610e10426101cd565b6094819055608d55506101ec95505050505050565b613e8a8061617283390190565b80516001600160a01b0381168114610147575f80fd5b919050565b5f805f805f805f60e0888a031215610162575f80fd5b61016b88610131565b965061017960208901610131565b955061018760408901610131565b945061019560608901610131565b93506101a360808901610131565b92506101b160a08901610131565b91506101bf60c08901610131565b905092959891949750929550565b5f826101e757634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e05161010051615eb66102bc5f395f81816104ea01528181614aee01528181614b7c0152614d5a01525f81816105e301528181614f130152614ffc01525f818161067f01528181611376015281816115b201528181613848015281816138de01526147db01525f61048001525f818161051d01528181610e9e015281816117950152818161215301528181612a2301528181612fc9015281816133a201528181613443015281816134d701528181614e0501528181614e960152614f5f0152615eb65ff3fe608060405260043610610344575f3560e01c80638a19c8bc116101bd578063cf35bdd0116100f2578063eb6e17b511610092578063fb6241c01161006d578063fb6241c014610b43578063fbfa77cf14610b62578063fe51b95514610b81578063fff2d49b14610b96575f80fd5b8063eb6e17b514610ad7578063ed26f2e814610b05578063f2fde38b14610b24575f80fd5b8063e5f04edb116100cd578063e5f04edb14610a6b578063e92d1f3a14610a80578063ea49c35e14610a9f578063eafe7a7414610abe575f80fd5b8063cf35bdd0146109c3578063d3dcde9a14610a2d578063e30c397814610a4c575f80fd5b8063a9e282b81161015d578063b24ae1f811610138578063b24ae1f814610951578063b3ab15fb14610966578063c1dbd1c314610985578063ccc73973146109a4575f80fd5b8063a9e282b8146108df578063aca4894c146108fe578063b10d9e421461091d575f80fd5b806395d8e5291161019857806395d8e529146107c557806396c82e57146107fb5780639745cc3d14610810578063a7345519146108c0575f80fd5b80638a19c8bc146107745780638da5cb5b146107885780638f45e94b146107a6575f80fd5b806351e42ab511610293578063705bc3c41161023357806379ba50971161020e57806379ba5097146106c75780637c242121146106db57806381236d1614610719578063861cf55414610747575f80fd5b8063705bc3c4146106435780637150d8ae1461066e57806376b1d08f146106a1575f80fd5b806359f026391161026e57806359f02639146105a7578063668318d5146105d25780636817031b146106055780636e3e495e14610624575f80fd5b806351e42ab51461055e578063570ca7351461057357806359cd903114610592575f80fd5b80631e134423116102fe5780634707d000116102d95780634707d000146104ba578063479c9254146104d957806347ccca021461050c5780634b7314e41461053f575f80fd5b80631e1344231461043b5780633b1ab44c146104505780633fc8cef31461046f575f80fd5b80630158a1fb1461037b578063065353961461039c57806306a72686146103d157806311da60b4146103f457806314fc78fc1461040857806317adc2111461041c575f80fd5b3661037757609a5460ff161561035657005b61035e610bb5565b3460935f82825461036f919061528d565b925050819055005b5f80fd5b348015610386575f80fd5b5061039a6103953660046152ee565b610c6b565b005b3480156103a7575f80fd5b506103bb6103b636600461533e565b610ce7565b6040516103c891906153f0565b60405180910390f35b3480156103dc575f80fd5b506103e6608d5481565b6040519081526020016103c8565b3480156103ff575f80fd5b5061039a610dc5565b348015610413575f80fd5b5061039a610dcf565b348015610427575f80fd5b5061039a6104363660046153fe565b610e21565b348015610446575f80fd5b506103e660935481565b34801561045b575f80fd5b5061039a61046a366004615445565b611037565b34801561047a575f80fd5b506104a27f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016103c8565b3480156104c5575f80fd5b5061039a6104d4366004615460565b611117565b3480156104e4575f80fd5b506104a27f000000000000000000000000000000000000000000000000000000000000000081565b348015610517575f80fd5b506104a27f000000000000000000000000000000000000000000000000000000000000000081565b34801561054a575f80fd5b5061039a6105593660046154cc565b61125a565b348015610569575f80fd5b506103e660925481565b34801561057e575f80fd5b506002546104a2906001600160a01b031681565b34801561059d575f80fd5b506103e660045481565b3480156105b2575f80fd5b506103e66105c136600461550a565b608b6020525f908152604090205481565b3480156105dd575f80fd5b506104a27f000000000000000000000000000000000000000000000000000000000000000081565b348015610610575f80fd5b5061039a61061f366004615445565b6112a7565b34801561062f575f80fd5b506103e661063e366004615525565b611331565b34801561064e575f80fd5b506103e661065d366004615445565b60976020525f908152604090205481565b348015610679575f80fd5b506104a27f000000000000000000000000000000000000000000000000000000000000000081565b3480156106ac575f80fd5b506106b5604081565b60405160ff90911681526020016103c8565b3480156106d2575f80fd5b5061039a611414565b3480156106e6575f80fd5b506107096106f536600461554f565b608e6020525f908152604090205460ff1681565b60405190151581526020016103c8565b348015610724575f80fd5b5061070961073336600461554f565b60986020525f908152604090205460ff1681565b348015610752575f80fd5b5061076661076136600461550a565b6114a5565b6040516103c8929190615566565b34801561077f575f80fd5b506103e661156d565b348015610793575f80fd5b505f546104a2906001600160a01b031681565b3480156107b1575f80fd5b506103e66107c0366004615525565b61157f565b3480156107d0575f80fd5b506103e66107df3660046153fe565b609660209081525f928352604080842090915290825290205481565b348015610806575f80fd5b506103e660915481565b34801561081b575f80fd5b5061087b61082a36600461554f565b60906020525f90815260409020805460018201546002909201546001600160801b0380831693600160801b9093048116929160ff8116916001600160401b0361010083041691600160481b90041686565b604080516001600160801b039788168152958716602087015285019390935290151560608401526001600160401b0316608083015290911660a082015260c0016103c8565b3480156108cb575f80fd5b5061039a6108da3660046155d8565b611606565b3480156108ea575f80fd5b5061039a6108f936600461554f565b611746565b348015610909575f80fd5b5061039a610918366004615616565b611775565b348015610928575f80fd5b5061093c610937366004615525565b611b09565b604080519283526020830191909152016103c8565b34801561095c575f80fd5b506103e6610e1081565b348015610971575f80fd5b5061039a610980366004615445565b611b41565b348015610990575f80fd5b5061039a61099f36600461569a565b611bb4565b3480156109af575f80fd5b506103e66109be36600461554f565b611eae565b3480156109ce575f80fd5b506109e26109dd36600461554f565b611f28565b604080516001600160a01b03909816885295151560208801529315159486019490945260ff918216606086015216608084015261ffff90911660a083015260c082015260e0016103c8565b348015610a38575f80fd5b5061039a610a473660046154cc565b611f88565b348015610a57575f80fd5b506001546104a2906001600160a01b031681565b348015610a76575f80fd5b506103e660955481565b348015610a8b575f80fd5b506103e6610a9a366004615525565b612c2b565b348015610aaa575f80fd5b5061039a610ab93660046154cc565b612d6a565b348015610ac9575f80fd5b506086546106b59060ff1681565b348015610ae2575f80fd5b50610af6610af136600461554f565b612ece565b6040516103c89392919061572b565b348015610b10575f80fd5b5061039a610b1f366004615793565b612fa9565b348015610b2f575f80fd5b5061039a610b3e366004615445565b613078565b348015610b4e575f80fd5b5061039a610b5d3660046157b6565b6130eb565b348015610b6d575f80fd5b506003546104a2906001600160a01b031681565b348015610b8c575f80fd5b506103e660945481565b348015610ba1575f80fd5b5061039a610bb03660046157da565b6132e4565b5f610bbe61156d565b90506094548111610bcc5750565b5f609154118015610bde57505f609354115b15610c6657609154609354610bfb90670de0b6b3a7640000615814565b610c05919061583f565b60925f828254610c15919061528d565b909155505060935460915460405183927f866f813a2289b14a1e94be9b6a7db4b5ad759df3fb1466245f650642f3cc7a5692610c5992918252602082015260400190565b60405180910390a25f6093555b609455565b5f546001600160a01b03163314610c955760405163ea8e4eb560e01b815260040160405180910390fd5b60058360ff1660408110610cab57610cab615852565b6002020154600160a81b900460ff16610cd757604051633640530560e01b815260040160405180910390fd5b610ce2838383613811565b505050565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915260ff8084165f90815260856020526040902090831660048110610d4457610d44615852565b6040805160e08101825260049290920292909201805460ff811683526001600160a01b03610100909104811660208401526001820154811693830193909352600280820154808516606085015262ffffff600160a01b8204166080850152600160b81b9004900b60a08301526003015490911660c082015290505b92915050565b610dcd610bb5565b565b610dd7610bb5565b610ddf613d39565b610dfc5760405163ea8e4eb560e01b815260040160405180910390fd5b610e0461156d565b608d556094546095541015610dcd57609454609555610dcd613d5f565b609954600114610e445760405163769dd35360e11b815260040160405180910390fd5b60026099555f82815260966020908152604080832060ff8516845290915281205490819003610e86576040516301f30c8760e21b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018490525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610eeb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0f9190615866565b5f85815260966020908152604080832060ff881680855292528083208390559293509091600591908110610f4557610f45615852565b60020201546001600160a01b03165f81815260976020526040812080549293508592909190610f75908490615881565b90915550610f86905081838561402a565b610feb575f85815260966020908152604080832060ff8816845282528083208690556001600160a01b0384168352609790915281208054859290610fcb90849061528d565b925050819055506040516301f30c8760e21b815260040160405180910390fd5b604080515f81526020810185905260ff86169187917f8110a247e3bf84088ca20c991ad431b68293ca3bdfe626df91b9744bf4d7b9ce910160405180910390a350506001609955505050565b5f546001600160a01b031633146110615760405163ea8e4eb560e01b815260040160405180910390fd5b60405147905f906001600160a01b0384169083908381818185875af1925050503d805f81146110ab576040519150601f19603f3d011682016040523d82523d5f602084013e6110b0565b606091505b50509050806110d2576040516381063e5160e01b815260040160405180910390fd5b6040518281526001600160a01b038416905f907f3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc9060200160405180910390a3505050565b5f546001600160a01b031633146111415760405163ea8e4eb560e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611185573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111a99190615894565b6001600160a01b0384165f90815260976020526040902054909150818110156111db576111d68183615881565b6111dd565b5f5b91506111ea84848461402a565b611207576040516381063e5160e01b815260040160405180910390fd5b826001600160a01b0316846001600160a01b03167f3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc8460405161124c91815260200190565b60405180910390a350505050565b611262610dc5565b5f61126b61156d565b90505f5b828110156112a15761129984848381811061128c5761128c615852565b90506020020135836140f9565b60010161126f565b50505050565b5f546001600160a01b031633146112d15760405163ea8e4eb560e01b815260040160405180910390fd5b6003546001600160a01b03161515806112f157506001600160a01b038116155b1561130f576040516301f30c8760e21b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b5f60058360ff166040811061134857611348615852565b6002020154600160a81b900460ff1661137457604051633640530560e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632a8504676113ac85614559565b846107086040518463ffffffff1660e01b81526004016113ce939291906158f0565b602060405180830381865afa1580156113e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061140d9190615894565b9392505050565b6001546001600160a01b03163314158061143757506001546001600160a01b0316155b156114555760405163ea8e4eb560e01b815260040160405180910390fd5b600180545f80546001600160a01b0383166001600160a01b031991821681178355921690925560405190917fdc3c82f4776932041f15a08f769aadd6ed44c2a975e64bbf0fde8cf812f8b6b891a2565b6114ad615115565b6114b5615115565b60ff83165f90815260876020908152604080832060889092529182902082516060810190935290918260038282826020028201915b8154815260200190600101908083116114ea575050604080516060810191829052949650859350600392509050825f855b82829054906101000a90046001600160401b03166001600160401b03168152602001906008019060208260070104928301926001038202915080841161151b5790505050505050905091509150915091565b5f61157a610e104261583f565b905090565b5f60058360ff166040811061159657611596615852565b6002020154600160a81b900460ff166115b057505f610dbf565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c55cd26b6115e885614559565b846040518363ffffffff1660e01b81526004016113ce92919061591e565b5f546001600160a01b031633146116305760405163ea8e4eb560e01b815260040160405180910390fd5b60058360ff166040811061164657611646615852565b6002020154600160a81b900460ff1661167257604051633640530560e01b815260040160405180910390fd5b61ffff8216158061168857506103e861ffff8316115b156116a6576040516301f30c8760e21b815260040160405180910390fd5b8160058460ff16604081106116bd576116bd615852565b60020201805461ffff92909216600160c01b0261ffff60c01b1990921691909117905580600560ff8516604081106116f7576116f7615852565b60020201600101556040805161ffff841681526020810183905260ff8516917f21d534072f91477f5fe629b59c0768b993e0a19aae8b98a464910bee3803f095910160405180910390a2505050565b5f546001600160a01b031633146117705760405163ea8e4eb560e01b815260040160405180910390fd5b600455565b6040516331a9108f60e11b81526004810186905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa1580156117da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117fe9190615866565b6001600160a01b0316146118255760405163ea8e4eb560e01b815260040160405180910390fd5b8215806118325750600383115b8061183d5750828114155b1561185b576040516301f30c8760e21b815260040160405180910390fd5b5f858152608f60205260408120815b85811015611a935760865460ff1687878381811061188a5761188a615852565b905060200201602081019061189f919061550a565b60ff161015806118f7575060058787838181106118be576118be615852565b90506020020160208101906118d3919061550a565b60ff16604081106118e6576118e6615852565b6002020154600160a81b900460ff16155b1561191557604051633640530560e01b815260040160405180910390fd5b5f5b818110156119995787878381811061193157611931615852565b9050602002016020810190611946919061550a565b60ff1688888381811061195b5761195b615852565b9050602002016020810190611970919061550a565b60ff1603611991576040516301f30c8760e21b815260040160405180910390fd5b600101611917565b508686828181106119ac576119ac615852565b90506020020160208101906119c1919061550a565b8282600381106119d3576119d3615852565b602091828204019190066101000a81548160ff021916908360ff160217905550848482818110611a0557611a05615852565b9050602002016020810190611a1a919061593f565b826001018260038110611a2f57611a2f615852565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550848482818110611a6657611a66615852565b9050602002016020810190611a7b919061593f565b611a899061ffff168461528d565b925060010161186a565b508161271014611ab6576040516301f30c8760e21b815260040160405180910390fd5b60028101805460ff191660ff871690811790915560405190815287907f9289c2bdf2133c72d7dccab03946c733038fb8d5b7e24787b0afbd7a77aad935906020015b60405180910390a250505050505050565b5f80333014611b2b5760405163ea8e4eb560e01b815260040160405180910390fd5b611b3584846146e3565b915091505b9250929050565b5f546001600160a01b03163314611b6b5760405163ea8e4eb560e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f99d737e0adf2c449d71890b86772885ec7959b152ddb265f76325b6e68e105d3905f90a250565b5f546001600160a01b03163314611bde5760405163ea8e4eb560e01b815260040160405180910390fd5b608654604060ff90911610611c06576040516301f30c8760e21b815260040160405180910390fd5b6001600160a01b038716611c2d576040516301f30c8760e21b815260040160405180910390fd5b5f5b60865460ff9081169082161015611c9457876001600160a01b031660058260ff1660408110611c6057611c60615852565b60020201546001600160a01b031603611c8c576040516301f30c8760e21b815260040160405180910390fd5b600101611c2f565b5060ff8516600114801590611cad575060ff8516600214155b15611ccb576040516301f30c8760e21b815260040160405180910390fd5b8361ffff165f03611cdc5761012c93505b6103e861ffff85161115611d03576040516301f30c8760e21b815260040160405180910390fd5b6086546040805160e0810182526001600160a01b038a168152881515602082015260018183015260ff88811660608301525f608083015261ffff881660a083015260c08201879052909216919060059083908110611d6357611d63615852565b8251600291909102919091018054602084015160408501516060860151608087015160a088015161ffff16600160c01b0261ffff60c01b1960ff928316600160b81b021662ffffff60b81b19938316600160b01b0260ff60b01b19951515600160a81b029590951661ffff60a81b19961515600160a01b026001600160a81b03199098166001600160a01b03909a169990991796909617949094169690961791909117169190911717815560c09092015160019092019190915560868054909116905f611e2f8361595a565b91906101000a81548160ff021916908360ff16021790555050611e53818484613811565b604080516001600160a01b038a168152881515602082015260ff888116828401529151918316917f0e6b0001da0748dd2bd3e559964cc3186cda6147278313f57e20122694649b5d9181900360600190a25050505050505050565b5f81815260906020526040812080546002820154600160801b9091046001600160801b03169060ff161561140d57670de0b6b3a76400008260010154609254611ef79190615881565b8354611f0c91906001600160801b0316615814565b611f16919061583f565b611f20908261528d565b949350505050565b60058160408110611f37575f80fd5b6002020180546001909101546001600160a01b038216925060ff600160a01b8304811692600160a81b8104821692600160b01b8204831692600160b81b8304169161ffff600160c01b909104169087565b609954600114611fab5760405163769dd35360e11b815260040160405180910390fd5b6002609955611fb8614922565b611fd55760405163ea8e4eb560e01b815260040160405180910390fd5b611fdd610bb5565b5f611fe661156d565b9050611ff0613d39565b15611ffb57608d8190555b81612004615133565b5f826001600160401b0381111561201d5761201d615978565b60405190808252806020026020018201604052801561205657816020015b612043615115565b81526020019060019003908161203b5790505b5090505f836001600160401b0381111561207257612072615978565b6040519080825280602002602001820160405280156120ab57816020015b612098615115565b8152602001906001900390816120905790505b5090505f846001600160401b038111156120c7576120c7615978565b6040519080825280602002602001820160405280156120f0578160200160208202803683370190505b5090505f5b858110156124c5575f89898381811061211057612110615852565b602090810292909201355f8181526090909352604090922060028101549293509160ff16905080156121c657506040516382afd23b60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906382afd23b90602401602060405180830381865afa1580156121a0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121c4919061598c565b155b156121d5576121d5828a6140f9565b80546002820154600160801b9091046001600160801b03169060ff161561224557670de0b6b3a764000082600101546092546122119190615881565b835461222691906001600160801b0316615814565b612230919061583f565b61223a908261528d565b609254600184015590505b805f03612254575050506124bd565b5f838152608f60205260409020600281015460ff16612271615115565b612279615115565b8260ff165f0361229e576001925061228f614953565b60ff1682526127108152612343565b604080516060810191829052908590600390825f855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116122b457505060408051606081019182905295975060018a0194506003935091508390505f855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411612303579050505050505090505b85546001600160801b03168655885183908a908a90811061236657612366615852565b60ff909216602092830291909101909101525f805b8460ff168110156124b3575f60ff861661239683600161528d565b146123d2576127108483600381106123b0576123b0615852565b60200201516123c39061ffff168a615814565b6123cd919061583f565b6123dc565b6123dc8389615881565b90506123e8818461528d565b9250808e8c815181106123fd576123fd615852565b6020026020010151836003811061241657612416615852565b602002015284826003811061242d5761242d615852565b60200201518d8c8151811061244457612444615852565b6020026020010151836003811061245d5761245d615852565b60ff9092166020929092020152808f86846003811061247e5761247e615852565b602002015160ff166040811061249657612496615852565b602002018181516124a7919061528d565b9052505060010161237b565b5050505050505050505b6001016120f5565b506124ce615133565b6124d6615133565b5f5b60865460ff90811690821610156126f8575f878260ff16604081106124ff576124ff615852565b60200201519050801580612514575060045481105b1561251f57506126f0565b5f60058360ff166040811061253657612536615852565b600202016001015490505f829050815f146125cd5760ff84165f908152608c60205260409020548c146125835760ff84165f908152608c602090815260408083208f9055608b9091528120555b60ff84165f908152608b602052604081205483116125a1575f6125bd565b60ff85165f908152608b60205260409020546125bd9084615881565b9050808211156125cb578091505b505b6004548110156125df575050506126f0565b604051635886cf2160e11b815260ff8516600482015260248101829052309063b10d9e429060440160408051808303815f875af1925050508015612640575060408051601f3d908101601f1916820190925261263d918101906159a7565b60015b612686578360ff167f658935f8cd82af21d125a8f1e19e9e8b5b1137a405b0218bc5ee4b3ddac76cc28260405161267991815260200190565b60405180910390a26126ec565b81888760ff166040811061269c5761269c615852565b6020020152808760ff8816604081106126b7576126b7615852565b602002015283156126e95760ff86165f908152608b6020526040812080548392906126e390849061528d565b90915550505b50505b5050505b6001016124d8565b505f5b87811015612c19575f8b8b8381811061271657612716615852565b9050602002013590505f5b85838151811061273357612733615852565b602002602001015160ff16811015612c0f575f88848151811061275857612758615852565b6020026020010151826003811061277157612771615852565b60200201519050805f036127855750612c07565b5f88858151811061279857612798615852565b602002602001015183600381106127b1576127b1615852565b60200201519050858160ff16604081106127cd576127cd615852565b60200201515f03612871575f8481526090602052604090208054839190601090612808908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508060ff16847fc2cda032f63ebe7629abecffad35589c71515edfd5b2c2048e340b3033a536e48460405161286291815260200190565b60405180910390a35050612c07565b5f8b8260ff166040811061288757612887615852565b6020020151878360ff16604081106128a1576128a1615852565b60200201518d8460ff16604081106128bb576128bb615852565b60200201516128ca9190615881565b6128d49085615814565b6128de919061583f565b90505f6128eb8285615881565b90505f8d8460ff166040811061290357612903615852565b6020020151858b8660ff166040811061291e5761291e615852565b602002015161292d9190615814565b612937919061583f565b905082156129d2575f878152609060205260409020805484919060109061296f908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508360ff16877fc2cda032f63ebe7629abecffad35589c71515edfd5b2c2048e340b3033a536e4856040516129c991815260200190565b60405180910390a35b805f036129e3575050505050612c07565b5f8781526098602052604081205460ff1680612a0857506003546001600160a01b0316155b15612acf576040516331a9108f60e11b8152600481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa925050508015612a8e575060408051601f3d908101601f19168201909252612a8b91810190615866565b60015b612a9957505f612b35565b612ac760058760ff1660408110612ab257612ab2615852565b60020201546001600160a01b0316828561402a565b915050612b35565b6040516303ed890760e61b81526004810189905260ff8616602482015260448101839052309063fb6241c0906064015f604051808303815f87803b158015612b15575f80fd5b505af1925050508015612b26575060015b612b3157505f612b35565b5060015b8015612b8057604080518481526020810184905260ff8716918a917f8110a247e3bf84088ca20c991ad431b68293ca3bdfe626df91b9744bf4d7b9ce910160405180910390a3612c00565b5f88815260966020908152604080832060ff8916845290915281208054849290612bab90849061528d565b9091555082905060975f600560ff891660408110612bcb57612bcb615852565b60020201546001600160a01b0316815260208101919091526040015f9081208054909190612bfa90849061528d565b90915550505b5050505050505b600101612721565b50506001016126fb565b50506001609955505050505050505050565b5f8060058460ff1660408110612c4357612c43615852565b600202018054909150600160a81b900460ff16612c63575f915050610dbf565b80545f905f19600160b01b90910460ff1601612cef5760405163371f24af60e11b815260ff86166004820152602481018590523090636e3e495e90604401602060405180830381865afa925050508015612cda575060408051601f3d908101601f19168201909252612cd791810190615894565b60015b612ce8575f92505050610dbf565b9050612d2e565b5f612cf9866149d3565b9050805f03612d0d575f9350505050610dbf565b670de0b6b3a7640000612d208683615814565b612d2a919061583f565b9150505b815461271090612d4990600160c01b900461ffff16826159e8565b612d579061ffff1683615814565b612d61919061583f565b95945050505050565b5f546001600160a01b03163314612d945760405163ea8e4eb560e01b815260040160405180910390fd5b612d9c610dc5565b5f5b81811015610ce2575f838383818110612db957612db9615852565b9050602002013590505f60905f8381526020019081526020015f209050612ddf82614aec565b600281015460ff1615612df3575050612ec6565b5f612dfd83614ded565b9050805f03612e0e57505050612ec6565b81546001600160801b0319166001600160801b03821617825560925460018084019190915560028301805460ff19169091179055612e4a61156d565b8260020160016101000a8154816001600160401b0302191690836001600160401b031602179055508060915f828254612e83919061528d565b90915550506002820154604080518381526101009092046001600160401b0316602083015284915f80516020615e61833981519152910160405180910390a25050505b600101612d9e565b612ed6615115565b612ede615115565b5f838152608f602052604080822060028101548251606081019384905291928392600184019260ff169184906003908289855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612f115750506040805160608101918290529598508794506003935091508390505f855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411612f5d5750979d949c50949a509298505050505050505050565b6040516331a9108f60e11b81526004810183905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa15801561300e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130329190615866565b6001600160a01b0316146130595760405163ea8e4eb560e01b815260040160405180910390fd5b5f91825260986020526040909120805460ff1916911515919091179055565b5f546001600160a01b031633146130a25760405163ea8e4eb560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f239a2ddded15777fa246aed5f7e1a9bc69a39d4eb4a397034d1d85766cca7d4c905f90a250565b33301461310b5760405163ea8e4eb560e01b815260040160405180910390fd5b5f60058360ff166040811061312257613122615852565b60020201546003546040516370a0823160e01b81526001600160a01b039182166004820152911691505f9082906370a0823190602401602060405180830381865afa158015613173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131979190615894565b6003549091506131b29083906001600160a01b03168561402a565b6131cf576040516301f30c8760e21b815260040160405180910390fd5b6003546040516370a0823160e01b81526001600160a01b0391821660048201525f918391908516906370a0823190602401602060405180830381865afa15801561321b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061323f9190615894565b6132499190615881565b9050805f0361326b576040516301f30c8760e21b815260040160405180910390fd5b6003546040516307e0ace760e21b81526004810188905260ff871660248201526001600160a01b0385811660448301526064820184905290911690631f82b39c906084015f604051808303815f87803b1580156132c6575f80fd5b505af11580156132d8573d5f803e3d5ffd5b50505050505050505050565b6099546001146133075760405163769dd35360e11b815260040160405180910390fd5b6002609955613314614922565b6133315760405163ea8e4eb560e01b815260040160405180910390fd5b613339610dc5565b5f838152609060205260408120905b82811015613805575f84848381811061336357613363615852565b90506020020135905085810361338c576040516301f30c8760e21b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa92505050801561340d575060408051601f3d908101601f1916820190925261340a91810190615866565b60015b1561342b57604051636f5888a160e11b815260040160405180910390fd5b60405163ac36e81560e01b8152600481018790525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ac36e81590602401602060405180830381865afa158015613490573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134b49190615a02565b604051638cfd9b5b60e01b8152600481018490529091505f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638cfd9b5b90602401602060405180830381865afa15801561351c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135409190615894565b905061ffff8116158061357857508061ffff168261ffff161415801561357857508061ffff1660108363ffffffff16901c61ffff1614155b1561359657604051631b81740360e11b815260040160405180910390fd5b5f83815260906020526040902080546002820154600160801b9091046001600160801b03169060ff161561363c57670de0b6b3a764000082600101546092546135df9190615881565b83546135f491906001600160801b0316615814565b6135fe919061583f565b613608908261528d565b8254609180549293506001600160801b03909116915f9061362a908490615881565b909155505060028201805460ff191690555b5f8255600282018054610100600160c81b0319169055609254600183015586548190889060109061367e908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505f5b60865460ff9081169082161015613746575f86815260966020908152604080832060ff85168452909152902054801561373d575f60965f8981526020019081526020015f205f8460ff1660ff1681526020019081526020015f20819055508060965f8e81526020019081526020015f205f8460ff1660ff1681526020019081526020015f205f828254613737919061528d565b90915550505b506001016136a4565b506003546001600160a01b0316156137b95760035460405163d1c2babb60e01b8152600481018c9052602481018790526001600160a01b039091169063d1c2babb906044015f604051808303815f87803b1580156137a2575f80fd5b505af11580156137b4573d5f803e3d5ffd5b505050505b848a7faf5c71ea635d254063d323b6a94cb2a66d3b966e1de036d93ec664e3991b01fe836040516137ec91815260200190565b60405180910390a3505060019093019250613348915050565b50506001609955505050565b5f60058460ff166040811061382857613828615852565b600202018054604051631a860ecf60e31b81529192506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263d430767892613884928892889290911690600401615b2f565b5f6040518083038186803b15801561389a575f80fd5b505afa1580156138ac573d5f803e3d5ffd5b50508254600160b01b900460ff1660011491505080156139565750604051633cda067560e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f36819d4906139159086908690600401615b5a565b602060405180830381865afa158015613930573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613954919061598c565b155b156139745760405163c4c321d160e01b815260040160405180910390fd5b8054600160b81b900460ff16156139d85761398d61156d565b60ff85165f908152608a6020526040902054036139bd5760405163c4c321d160e01b815260040160405180910390fd5b6139c561156d565b60ff85165f908152608a60205260409020555b80545f908190600160b81b900460ff1615613ab0575f613a0087670de0b6b3a7640000612c2b565b90508015613a3e578354613a2190600160c01b900461ffff166127106159e8565b61ffff16613a3182612710615814565b613a3b919061583f565b92505b604051638f45e94b60e01b815260ff88166004820152670de0b6b3a764000060248201523090638f45e94b90604401602060405180830381865afa925050508015613aa6575060408051601f3d908101601f19168201909252613aa391810190615894565b60015b15613aae5791505b505b5f5b600460ff82161015613b985760ff8116851115613b255785858260ff16818110613ade57613ade615852565b905060e0020160855f8960ff1660ff1681526020019081526020015f208260ff1660048110613b0f57613b0f615852565b60040201613b1d8282615bb1565b905050613b90565b60ff8088165f90815260856020526040902090821660048110613b4a57613b4a615852565b6004020180546001600160a81b03191681556001810180546001600160a01b03199081169091556002820180546001600160d01b03191690556003909101805490911690555b600101613ab2565b50825460ff60b81b1916600160b81b60ff8616021783555f613bc287670de0b6b3a764000061157f565b9050805f03613be45760405163c4c321d160e01b815260040160405180910390fd5b82151580613bf157508115155b15613c51575f8315801590613c0b5750613c0b82856150ba565b90505f8315801590613c225750613c2283856150ba565b905081158015613c30575080155b15613c4e5760405163c4c321d160e01b815260040160405180910390fd5b50505b60ff8781165f908152608760209081526040808320838155600181018490556002018390556088825280832083905560899091529020805460ff191690558454600160b01b90041660011901613d025760ff87165f908152608760205260409020819055613cbd61156d565b60ff88165f908152608860209081526040808320805467ffffffffffffffff19166001600160401b0395909516949094179093556089905220805460ff191660011790555b60405160ff86811682528816907f9ec53258cd9bc0432e41797e0a280c6bf75cc16ae1e1e19d4228e521c4e7566590602001611af8565b5f80546001600160a01b031633148061157a5750506002546001600160a01b0316331490565b5f613d6861156d565b90505f5b60865460ff90811690821610156140265760058160ff1660408110613d9357613d93615852565b6002020154600160a81b900460ff161580613dd357506002600560ff831660408110613dc157613dc1615852565b6002020154600160b01b900460ff1614155b61401e57604051638f45e94b60e01b815260ff82166004820152670de0b6b3a764000060248201525f903090638f45e94b90604401602060405180830381865afa925050508015613e41575060408051601f3d908101601f19168201909252613e3e91810190615894565b60015b613e4b575061401e565b9050805f03613e5a575061401e565b60ff8083165f90815260896020526040812054909116908115613e8757613e82600183615ca2565b613e93565b613e9360016003615ca2565b60ff8086165f908152608760205260409020919250821660038110613eba57613eba615852565b015415801590613f1e575060ff8085165f9081526088602052604090206001600160401b03871691831660038110613ef457613ef4615852565b600491828204019190066008029054906101000a90046001600160401b03166001600160401b0316145b15613f2b5750505061401e565b60ff8085165f9081526087602052604090208491841660038110613f5157613f51615852565b015560ff8085165f9081526088602052604090208691841660038110613f7957613f79615852565b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055506003826001613fb79190615cbb565b613fc19190615cd4565b60ff8581165f81815260896020908152604091829020805460ff19169590941694909417909255905185815290917ff3e2eaa484b746f047e870b63f6a8b13f6540040c3e1e2c1efa26ce7fd24f687910160405180910390a25050505b600101613d6c565b5050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f9283928392918816916140879190615cf5565b5f604051808303815f865af19150503d805f81146140c0576040519150601f19603f3d011682016040523d82523d5f602084013e6140c5565b606091505b50915091508180156140ef5750805115806140ef5750808060200190518101906140ef919061598c565b9695505050505050565b5f828152609060205260409020600281015460ff161561419457670de0b6b3a7640000816001015460925461412e9190615881565b825461414391906001600160801b0316615814565b61414d919061583f565b8154829060109061416f908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b6092546001820155600281015460ff1680156141c357506002810154600160481b90046001600160801b031615155b80156141e15750600281015461010090046001600160401b03168210155b1561425057600281015481546091546001600160801b03600160481b90930483169261420e921690615881565b614218919061528d565b60915560028101805482546001600160801b0319166001600160801b03600160481b830416178355600160481b600160c81b03191690555b5f61425a84614ded565b9050805f036142ef57600282015460ff16156142a1578154609180546001600160801b03909216915f9061428f908490615881565b909155505060028201805460ff191690555b81546001600160801b0319168255600282018054610100600160c81b0319169055604080515f808252602082015285915f80516020615e61833981519152910160405180910390a250505050565b600282015460ff166143b35781546001600160801b0319166001600160801b038216178255600282018054600160481b600160c81b0319169081905561010090046001600160401b03165f036143735761434a83600161528d565b8260020160016101000a8154816001600160401b0302191690836001600160401b031602179055505b6002820154604080518381526101009092046001600160401b0316602083015285915f80516020615e6183398151915291015b60405180910390a26144d7565b81546001600160801b031681101561444157815460915482916143e1916001600160801b0390911690615881565b6143eb919061528d565b60915581546001600160801b0319166001600160801b038216178255600282018054600160481b600160c81b0319169055604080518281526020810185905285915f80516020615e6183398151915291016143a6565b81546001600160801b03168111156144a75760028201546001600160801b03828116600160481b90920416146144a257600282018054600160481b600160c81b031916600160481b6001600160801b0384160217905561434a83600161528d565b6144d7565b6002820154600160481b90046001600160801b0316156144d757600282018054600160481b600160c81b03191690555b600282015460ff161580156144fd5750600282015461010090046001600160401b031615155b801561451b5750600282015461010090046001600160401b03168310155b156112a15760028201805460ff191660011790558154609180546001600160801b03909216915f9061454e90849061528d565b909155505050505050565b60605f60058360ff166040811061457257614572615852565b6002020154600160b81b900460ff169050806001600160401b0381111561459b5761459b615978565b60405190808252806020026020018201604052801561460057816020015b6040805160e0810182525f8082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282525f199092019101816145b95790505b5091505f5b8160ff168160ff1610156146dc5760ff8085165f9081526085602052604090209082166004811061463857614638615852565b6040805160e08101825260049290920292909201805460ff80821684526001600160a01b03610100909204821660208501526001830154821694840194909452600280830154808316606086015262ffffff600160a01b8204166080860152600160b81b9004900b60a08401526003909101541660c08201528451909185919084169081106146c9576146c9615852565b6020908102919091010152600101614605565b5050919050565b5f805f60058560ff16604081106146fc576146fc615852565b600202018054909150600160a81b900460ff1661472c57604051633640530560e01b815260040160405180910390fd5b5f6147378686612c2b565b9050805f0361475957604051631368280d60e31b815260040160405180910390fd5b81546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa15801561479e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906147c29190615894565b609a805460ff1916600117905590506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b253b1fc8761480a8a614559565b856040518463ffffffff1660e01b815260040161482892919061591e565b604080518083038185885af1158015614843573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061486891906159a7565b609a805460ff1916905584546040516370a0823160e01b81523060048201529196508392506001600160a01b0316906370a0823190602401602060405180830381865afa1580156148bb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906148df9190615894565b6148e99190615881565b94508185101561490c5760405163273f148b60e11b815260040160405180910390fd5b85841115614918578593505b5050509250929050565b5f61492b613d39565b156149365750600190565b6004608d54614945919061528d565b61494d61156d565b11905090565b5f805b60865460ff90811690821610156149cc5760058160ff166040811061497d5761497d615852565b6002020154600160a81b900460ff1680156149ba575060058160ff16604081106149a9576149a9615852565b6002020154600160a01b900460ff16155b156149c457919050565b600101614956565b505f905090565b60ff8082165f90815260896020526040812054909116818115614a00576149fb600183615ca2565b614a0c565b614a0c60016003615ca2565b60ff8086165f9081526087602052604081209293509190831660038110614a3557614a35615852565b015460ff8087165f9081526088602052604081209293509190841660038110614a6057614a60615852565b600491828204019190066008029054906101000a90046001600160401b031690505f614a8a61156d565b9050821580614aaa5750806001600160401b0316826001600160401b0316115b80614ad057506001600160401b038116614ac5600184615d0b565b6001600160401b0316105b15614ae157505f9695505050505050565b509095945050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161580614b2f57505f818152608e602052604090205460ff165b15614b375750565b5f818152608e60209081526040808320805460ff19166001179055608f90915281206002015460ff169003614d445760405163eb6e17b560e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063eb6e17b59060240160e060405180830381865afa925050508015614be7575060408051601f3d908101601f19168201909252614be491810190615d71565b60015b15614d44575f8160ff16118015614c02575060038160ff1611155b15614d405760015f805b8360ff16811015614cb45760865460ff16868260038110614c2f57614c2f615852565b602002015160ff16101580614c7c57506005868260038110614c5357614c53615852565b602002015160ff1660408110614c6b57614c6b615852565b6002020154600160a81b900460ff16155b15614c85575f92505b848160038110614c9757614c97615852565b6020020151614caa9061ffff168361528d565b9150600101614c0c565b50818015614cc3575080612710145b15614d3d575f868152608f60205260409020614ce181876003615152565b50614cf1600182018660036151e2565b5060028101805460ff191660ff861690811790915560405190815287907f9289c2bdf2133c72d7dccab03946c733038fb8d5b7e24787b0afbd7a77aad9359060200160405180910390a2505b50505b5050505b604051634091b68b60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906381236d1690602401602060405180830381865afa925050508015614dc5575060408051601f3d908101601f19168201909252614dc29181019061598c565b60015b15614dea578015614026575f828152609860205260409020805460ff19166001179055505b50565b6040516382afd23b60e01b8152600481018290525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906382afd23b90602401602060405180830381865afa158015614e52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614e76919061598c565b614e8157505f919050565b60405162ecfa2f60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630767d17890602401602060405180830381865afa158015614ee3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614f079190615894565b9050801580614f3d57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316155b15614f4757919050565b6040516364f5a33160e11b8152600481018390525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c9eb466290602401602060405180830381865afa158015614fac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614fd09190615e45565b905060028160ff161015614fe45750919050565b604051636f2641e160e01b8152600481018490525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636f2641e190602401602060405180830381865afa158015615049573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061506d9190615894565b9050805f0361507d575050919050565b61271060038360ff16101561509457612ee0615098565b6132c85b6150a69061ffff1683615814565b6150b0919061583f565b611f20908461528d565b5f6127106150ca6105dc82615881565b6150d49084615814565b6150de919061583f565b831015801561140d57506127106150f76105dc8261528d565b6151019084615814565b61510b919061583f565b9092111592915050565b60405180606001604052806003906020820280368337509192915050565b6040518061080001604052806040906020820280368337509192915050565b6001830191839082156151d2579160200282015f5b838211156151a457835183826101000a81548160ff021916908360ff16021790555092602001926001016020815f01049283019260010302615167565b80156151d05782816101000a81549060ff02191690556001016020815f010492830192600103026151a4565b505b506151de929150615265565b5090565b6001830191839082156151d2579160200282015f5b8382111561523757835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026151f7565b80156151d05782816101000a81549061ffff0219169055600201602081600101049283019260010302615237565b5b808211156151de575f8155600101615266565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610dbf57610dbf615279565b60ff81168114614dea575f80fd5b5f8083601f8401126152be575f80fd5b5081356001600160401b038111156152d4575f80fd5b60208301915083602060e083028501011115611b3a575f80fd5b5f805f60408486031215615300575f80fd5b833561530b816152a0565b925060208401356001600160401b03811115615325575f80fd5b615331868287016152ae565b9497909650939450505050565b5f806040838503121561534f575f80fd5b823561535a816152a0565b9150602083013561536a816152a0565b809150509250929050565b60ff815116825260018060a01b03602082015116602083015260018060a01b03604082015116604083015260018060a01b03606082015116606083015262ffffff608082015116608083015260a08101516153d560a084018260020b9052565b5060c0810151610ce260c08401826001600160a01b03169052565b60e08101610dbf8284615375565b5f806040838503121561540f575f80fd5b82359150602083013561536a816152a0565b6001600160a01b0381168114614dea575f80fd5b803561544081615421565b919050565b5f60208284031215615455575f80fd5b813561140d81615421565b5f8060408385031215615471575f80fd5b823561547c81615421565b9150602083013561536a81615421565b5f8083601f84011261549c575f80fd5b5081356001600160401b038111156154b2575f80fd5b6020830191508360208260051b8501011115611b3a575f80fd5b5f80602083850312156154dd575f80fd5b82356001600160401b038111156154f2575f80fd5b6154fe8582860161548c565b90969095509350505050565b5f6020828403121561551a575f80fd5b813561140d816152a0565b5f8060408385031215615536575f80fd5b8235615541816152a0565b946020939093013593505050565b5f6020828403121561555f575f80fd5b5035919050565b60c0810181845f5b600381101561558d57815183526020928301929091019060010161556e565b50505060608201835f5b60038110156155bf5781516001600160401b0316835260209283019290910190600101615597565b5050509392505050565b61ffff81168114614dea575f80fd5b5f805f606084860312156155ea575f80fd5b83356155f5816152a0565b92506020840135615605816155c9565b929592945050506040919091013590565b5f805f805f6060868803121561562a575f80fd5b8535945060208601356001600160401b03811115615646575f80fd5b6156528882890161548c565b90955093505060408601356001600160401b03811115615670575f80fd5b61567c8882890161548c565b969995985093965092949392505050565b8015158114614dea575f80fd5b5f805f805f805f60c0888a0312156156b0575f80fd5b87356156bb81615421565b965060208801356156cb8161568d565b955060408801356156db816152a0565b945060608801356156eb816155c9565b93506080880135925060a08801356001600160401b0381111561570c575f80fd5b6157188a828b016152ae565b989b979a50959850939692959293505050565b60e0810181855f5b600381101561575557815160ff16835260209283019290910190600101615733565b50505060608201845f5b600381101561578257815161ffff1683526020928301929091019060010161575f565b50505060ff831660c0830152611f20565b5f80604083850312156157a4575f80fd5b82359150602083013561536a8161568d565b5f805f606084860312156157c8575f80fd5b833592506020840135615605816152a0565b5f805f604084860312156157ec575f80fd5b8335925060208401356001600160401b03811115615808575f80fd5b6153318682870161548c565b8082028115828204841417610dbf57610dbf615279565b634e487b7160e01b5f52601260045260245ffd5b5f8261584d5761584d61582b565b500490565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215615876575f80fd5b815161140d81615421565b81810381811115610dbf57610dbf615279565b5f602082840312156158a4575f80fd5b5051919050565b5f8151808452602084019350602083015f5b828110156158e6576158d0868351615375565b60e09590950194602091909101906001016158bd565b5093949350505050565b606081525f61590260608301866158ab565b905083602083015263ffffffff83166040830152949350505050565b604081525f61593060408301856158ab565b90508260208301529392505050565b5f6020828403121561594f575f80fd5b813561140d816155c9565b5f60ff821660ff810361596f5761596f615279565b60010192915050565b634e487b7160e01b5f52604160045260245ffd5b5f6020828403121561599c575f80fd5b815161140d8161568d565b5f80604083850312156159b8575f80fd5b505080516020909101519092909150565b6001600160801b038181168382160190811115610dbf57610dbf615279565b61ffff8281168282160390811115610dbf57610dbf615279565b5f60208284031215615a12575f80fd5b815163ffffffff8116811461140d575f80fd5b62ffffff81168114614dea575f80fd5b803561544081615a25565b8060020b8114614dea575f80fd5b803561544081615a40565b8183526020830192505f815f5b848110156158e6578135615a79816152a0565b60ff1686526020820135615a8c81615421565b6001600160a01b031660208701526040820135615aa881615421565b6001600160a01b03166040870152615ac260608301615435565b6001600160a01b03166060870152615adc60808301615a35565b62ffffff166080870152615af260a08301615a4e565b615b0160a088018260020b9052565b50615b0e60c08301615435565b6001600160a01b031660c087015260e0958601959190910190600101615a66565b604081525f615b42604083018587615a59565b905060018060a01b0383166020830152949350505050565b602081525f611f20602083018486615a59565b5f8135610dbf81615421565b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f8135610dbf81615a25565b5f8135610dbf81615a40565b8135615bbc816152a0565b60ff811660ff19835416178255506020820135615bd881615421565b8154610100600160a81b03191660089190911b610100600160a81b0316178155615c10615c0760408401615b6d565b60018301615b79565b60028101615c29615c2360608501615b6d565b82615b79565b615c5a615c3860808501615b99565b82805462ffffff60a01b191660a09290921b62ffffff60a01b16919091179055565b615c89615c6960a08501615ba5565b825460b89190911b62ffffff60b81b1662ffffff60b81b19909116178255565b50614026615c9960c08401615b6d565b60038301615b79565b60ff8281168282160390811115610dbf57610dbf615279565b60ff8181168382160190811115610dbf57610dbf615279565b5f60ff831680615ce657615ce661582b565b8060ff84160691505092915050565b5f82518060208501845e5f920191825250919050565b6001600160401b038181168382160190811115610dbf57610dbf615279565b604051601f8201601f191681016001600160401b0381118282101715615d5e57634e487b7160e01b5f52604160045260245ffd5b604052919050565b8051615440816152a0565b5f805f60e08486031215615d83575f80fd5b84601f850112615d91575f80fd5b6060615d9c81615d2a565b8082870188811115615dac575f80fd5b875b81811015615dcf578051615dc1816152a0565b845260209384019301615dae565b508196505f925088601f820112615de4575f80fd5b839150615df082615d2a565b9381019391508189851115615e03575f80fd5b84821015615e28578151615e16816155c9565b83526020928301929190910190615e03565b9550615e3c9350505060c086019050615d66565b90509250925092565b5f60208284031215615e55575f80fd5b815161140d816152a056fe9aa1a56064c83c34d45ce0f34a60a04b6c6fd4bf28b61a19c16235ebedb30b19a26469706673582212203ea97dc94c537a8fbcf65d7dd46a27e5e1f946684c017ac2bc1221ac9e510a6464736f6c634300081a0033610120604052348015610010575f80fd5b50604051613e8a380380613e8a83398101604081905261002f916100e4565b6001600160a01b038516158061004c57506001600160a01b038416155b8061005e57506001600160a01b038316155b8061007057506001600160a01b038216155b8061008257506001600160a01b038116155b156100a05760405163c4c321d160e01b815260040160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0521661010052610145565b80516001600160a01b03811681146100df575f80fd5b919050565b5f805f805f60a086880312156100f8575f80fd5b610101866100c9565b945061010f602087016100c9565b935061011d604087016100c9565b925061012b606087016100c9565b9150610139608087016100c9565b90509295509295909350565b60805160a05160c05160e05161010051613c6e61021c5f395f81816102be015281816109e00152610f2101525f81816103100152818161045c0152818161053801528181610725015281816107cb01528181610828015281816108850152818161093a01528181611f85015261254501525f818161026c01526115ea01525f818161038601528181611ddf0152611e0601525f818161018501528181610d6601528181610db3015281816112530152818161129601528181611c1c01528181611c5701528181611ccf0152611d300152613c6e5ff3fe6080604052600436106100fd575f3560e01c8063b8dc491b11610092578063d430767811610062578063d4307678146102e0578063dc4c90d3146102ff578063e22b155214610332578063f36819d414610346578063f887ea4014610375575f80fd5b8063b8dc491b1461023a578063c45a01551461025b578063c55cd26b1461028e578063c9d4623f146102ad575f80fd5b806391dd7346116100cd57806391dd7346146101bf578063a0cf0aea146101eb578063a20d3f4e146101fe578063b253b1fc14610212575f80fd5b8063260bfc99146101085780632a85046714610133578063330ec614146101605780633fc8cef314610174575f80fd5b3661010457005b5f80fd5b348015610113575f80fd5b5061011c600281565b60405160ff90911681526020015b60405180910390f35b34801561013e575f80fd5b5061015261014d3660046132ea565b6103a8565b60405190815260200161012a565b34801561016b575f80fd5b5061011c600181565b34801561017f575f80fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161012a565b3480156101ca575f80fd5b506101de6101d9366004613344565b61044f565b60405161012a91906133de565b3480156101f6575f80fd5b506101a75f81565b348015610209575f80fd5b5061011c600381565b6102256102203660046133f0565b6109d3565b6040805192835260208301919091520161012a565b348015610245575f80fd5b5061025961025436600461344b565b610f1f565b005b348015610266575f80fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b348015610299575f80fd5b506101526102a83660046133f0565b611119565b3480156102b8575f80fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156102eb575f80fd5b506102596102fa366004613482565b611168565b34801561030a575f80fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b34801561033d575f80fd5b5061011c600481565b348015610351575f80fd5b506103656103603660046134d4565b611aab565b604051901515815260200161012a565b348015610380575f80fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b815f5b8481101561044657368686838181106103c6576103c6613512565b60e002919091019150600290506103e06020830183613534565b60ff16146104015760405163c4c321d160e01b815260040160405180910390fd5b61043b610414608083016060840161354f565b85610425604085016020860161354f565b610435606086016040870161354f565b87611b02565b9250506001016103ab565b50949350505050565b6060336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461049a5760405163ea8e4eb560e01b815260040160405180910390fd5b5f80808080806104ac888a018a613588565b9550955095509550955095505f856001600160a01b0316876001600160a01b03161090505f6040518060a00160405280836104e757886104e9565b895b6001600160a01b03168152602001836105025789610504565b885b6001600160a01b031681526020018762ffffff1681526020018660020b8152602001856001600160a01b031681525090505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f3cd914c83604051806060016040528087151581526020018861058390613611565b8152602001876105b1576105ac600173fffd8963efd1fc6a506488495d951d5263988d2661362b565b6105c1565b6105c16401000276a3600161364a565b6001600160a01b03908116909152604080516001600160e01b031960e087901b168152845183166004820152602080860151841660248301528583015162ffffff166044830152606086015160020b6064830152608090950151831660848201528351151560a48201529383015160c485015291909101511660e48201526101206101048201525f610124820152610144016020604051808303815f875af115801561066f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106939190613669565b9050608081901d815f80866106a95782846106ac565b83835b915091505f82600f0b1280156106c457505f81600f0b135b6107005760405162461bcd60e51b815260206004820152600860248201526776342064656c746160c01b60448201526064015b60405180910390fd5b5f61070a83613680565b6001600160801b031690506001600160a01b038e166107ac577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166311da60b4826040518263ffffffff1660e01b815260040160206040518083038185885af1158015610781573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906107a69190613669565b50610906565b604051632961046560e21b81526001600160a01b038f811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063a5841194906024015f604051808303815f87803b15801561080c575f80fd5b505af115801561081e573d5f803e3d5ffd5b5050505061084d8e7f000000000000000000000000000000000000000000000000000000000000000083611b22565b6108835760405162461bcd60e51b81526020600482015260076024820152661d8d081cd95b9960ca1b60448201526064016106f7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166311da60b46040518163ffffffff1660e01b81526004016020604051808303815f875af11580156108e0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109049190613669565b505b604051630b0d9c0960e01b81526001600160a01b038e811660048301523060248301526001600160801b03841660448301527f00000000000000000000000000000000000000000000000000000000000000001690630b0d9c09906064015f604051808303815f87803b15801561097b575f80fd5b505af115801561098d573d5f803e3d5ffd5b50505050816001600160801b03166040516020016109ad91815260200190565b6040516020818303038152906040529e5050505050505050505050505050505b92915050565b5f80336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a1e5760405163ea8e4eb560e01b815260040160405180910390fd5b831580610a2b5750600484115b15610a495760405163c4c321d160e01b815260040160405180910390fd5b5f610a5434476136ad565b90505f856001600160401b03811115610a6f57610a6f6136c0565b604051908082528060200260200182016040528015610a98578160200160208202803683370190505b5090505f5b86811015610b74575f888883818110610ab857610ab8613512565b905060e002016020016020810190610ad0919061354f565b90506001600160a01b03811615610b4c576040516370a0823160e01b81523060048201526001600160a01b038216906370a0823190602401602060405180830381865afa158015610b23573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b479190613669565b610b4e565b5f5b838381518110610b6057610b60613512565b602090810291909101015250600101610a9d565b50345f805b88811015610be257368a8a83818110610b9457610b94613512565b905060e002019050610bb983826020016020810190610bb3919061354f565b86611be7565b9350610bc58185611d97565b9350610bd7606082016040830161354f565b925050600101610b79565b5081955086861015610c1e5760405162461bcd60e51b8152602060048201526005602482015264333637b7b960d91b60448201526064016106f7565b610c29813388611b22565b610c605760405162461bcd60e51b81526020600482015260086024820152671cd95b99081bdd5d60c21b60448201526064016106f7565b5f5b88811015610e5a575f8a8a83818110610c7d57610c7d613512565b905060e002016020016020810190610c95919061354f565b90506001600160a01b038116610cab5750610e52565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610cef573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d139190613669565b9050858381518110610d2757610d27613512565b60200260200101518111610d3c575050610e52565b5f868481518110610d4f57610d4f613512565b602002602001015182610d6291906136ad565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610e1757604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015610dfc575f80fd5b505af1158015610e0e573d5f803e3d5ffd5b50505050610e4e565b60405162461bcd60e51b815260206004820152600c60248201526b1c185c9d1a585b08199a5b1b60a21b60448201526064016106f7565b5050505b600101610c62565b505f844711610e69575f610e73565b610e7385476136ad565b905034811115610e805750345b610e8a81346136ad565b95508015610f12576040515f90339083908381818185875af1925050503d805f8114610ed1576040519150601f19603f3d011682016040523d82523d5f602084013e610ed6565b606091505b5050905080610f105760405162461bcd60e51b81526020600482015260066024820152651c99599d5b9960d21b60448201526064016106f7565b505b5050505050935093915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f9f91906136d4565b6001600160a01b0316336001600160a01b031614610fd05760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821661106e575f816001600160a01b0316476040515f6040518083038185875af1925050503d805f8114611027576040519150601f19603f3d011682016040523d82523d5f602084013e61102c565b606091505b50509050806110695760405162461bcd60e51b81526020600482015260096024820152680e6eecacae040cae8d60bb1b60448201526064016106f7565b505050565b6040516370a0823160e01b81523060048201526110e190839083906001600160a01b038316906370a0823190602401602060405180830381865afa1580156110b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110dc9190613669565b611b22565b6111155760405162461bcd60e51b8152602060048201526005602482015264073776565760dc1b60448201526064016106f7565b5050565b805f5b8381101561115f5761114585858381811061113957611139613512565b905060e002018361210b565b9150815f03611157575f915050611161565b60010161111c565b505b9392505050565b8115806111755750600482115b156111935760405163c4c321d160e01b815260040160405180910390fd5b5f805b83811015611a7257368585838181106111b1576111b1613512565b905060e0020190508060400160208101906111cc919061354f565b6001600160a01b03166111e5604083016020840161354f565b6001600160a01b03160361120c5760405163c4c321d160e01b815260040160405180910390fd5b5f6001600160a01b038416611227604084016020850161354f565b6001600160a01b0316148061128e57506001600160a01b03841615801561128e57506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611283604084016020850161354f565b6001600160a01b0316145b806112ec57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b03161480156112ec57505f6112e1604084016020850161354f565b6001600160a01b0316145b90508061130c5760405163c4c321d160e01b815260040160405180910390fd5b600261131b6020840184613534565b60ff16036116e6575f611334604084016020850161354f565b6001600160a01b0316148061136057505f611355606084016040850161354f565b6001600160a01b0316145b1561137e5760405163c4c321d160e01b815260040160405180910390fd5b5f61138f608084016060850161354f565b6001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113ca573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113ee91906136d4565b90505f611401608085016060860161354f565b6001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561143c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146091906136d4565b9050611472604085016020860161354f565b6001600160a01b0316826001600160a01b03161480156114b2575061149d606085016040860161354f565b6001600160a01b0316816001600160a01b0316145b8061150857506114c8606085016040860161354f565b6001600160a01b0316826001600160a01b031614801561150857506114f3604085016020860161354f565b6001600160a01b0316816001600160a01b0316145b6115255760405163c4c321d160e01b815260040160405180910390fd5b61153560a08501608086016136ef565b62ffffff1661154a608086016060870161354f565b6001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015611585573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115a9919061370a565b62ffffff16146115cc5760405163c4c321d160e01b815260040160405180910390fd5b6115dc608085016060860161354f565b6001600160a01b03908116907f000000000000000000000000000000000000000000000000000000000000000016631698ee8261161f604088016020890161354f565b61162f6060890160408a0161354f565b61163f60a08a0160808b016136ef565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015262ffffff166044820152606401602060405180830381865afa158015611694573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116b891906136d4565b6001600160a01b0316146116df5760405163c4c321d160e01b815260040160405180910390fd5b5050611a56565b60016116f56020840184613534565b60ff1603611935575f61170e604084016020850161354f565b6001600160a01b0316148061173a57505f61172f606084016040850161354f565b6001600160a01b0316145b156117585760405163c4c321d160e01b815260040160405180910390fd5b61271061176b60a08401608085016136ef565b62ffffff161061178e5760405163c4c321d160e01b815260040160405180910390fd5b5f61179f608084016060850161354f565b6001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117fe91906136d4565b90505f611811608085016060860161354f565b6001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561184c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187091906136d4565b9050611882604085016020860161354f565b6001600160a01b0316826001600160a01b03161480156118c257506118ad606085016040860161354f565b6001600160a01b0316816001600160a01b0316145b8061191857506118d8606085016040860161354f565b6001600160a01b0316826001600160a01b03161480156119185750611903604085016020860161354f565b6001600160a01b0316816001600160a01b0316145b6116df5760405163c4c321d160e01b815260040160405180910390fd5b60036119446020840184613534565b60ff1603611a3d575f61195d60c0840160a08501613725565b60020b1361197e5760405163c4c321d160e01b815260040160405180910390fd5b5f61198f604084016020850161354f565b6001600160a01b0316141580156119bd57506119b1604083016020840161354f565b6001600160a01b03163b155b156119db5760405163c4c321d160e01b815260040160405180910390fd5b5f6119ec606084016040850161354f565b6001600160a01b031614158015611a1a5750611a0e606083016040840161354f565b6001600160a01b03163b155b15611a385760405163c4c321d160e01b815260040160405180910390fd5b611a56565b60405163c4c321d160e01b815260040160405180910390fd5b611a66606083016040840161354f565b93505050600101611196565b50816001600160a01b0316816001600160a01b031614611aa55760405163c4c321d160e01b815260040160405180910390fd5b50505050565b5f805b82811015611af9576002848483818110611aca57611aca613512565b611ae092602060e0909202019081019150613534565b60ff1614611af1575f9150506109cd565b600101611aae565b50501515919050565b5f611b18611b108787612686565b838686612828565b9695505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f928392839291881691611b7f9190613740565b5f604051808303815f865af19150503d805f8114611bb8576040519150601f19603f3d011682016040523d82523d5f602084013e611bbd565b606091505b5091509150818015611b18575080511580611b18575080806020019051810190611b18919061376a565b5f826001600160a01b0316846001600160a01b031603611c08575080611161565b6001600160a01b038416158015611c5057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316145b15611ccd577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004015f604051808303818588803b158015611cae575f80fd5b505af1158015611cc0573d5f803e3d5ffd5b5050505050819050611161565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316148015611d1557506001600160a01b038316155b15611a3d57604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015611d79575f80fd5b505af1158015611d8b573d5f803e3d5ffd5b50505050819050611161565b5f80611db1611dac606086016040870161354f565b612908565b90506002611dc26020860186613534565b60ff1603611f3e57611e04611ddd604086016020870161354f565b7f00000000000000000000000000000000000000000000000000000000000000008561298a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b858183f6040518060800160405280876020016020810190611e51919061354f565b611e6160a08a0160808b016136ef565b611e7160608b0160408c0161354f565b604051606093841b6bffffffffffffffffffffffff19908116602083015260e89390931b6001600160e81b0319166034820152921b166037820152604b016040516020818303038152906040528152602001306001600160a01b031681526020018681526020015f8152506040518263ffffffff1660e01b8152600401611ef89190613783565b6020604051808303815f875af1158015611f14573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f389190613669565b506120a9565b6001611f4d6020860186613534565b60ff1603611f6457611f5f8484612af6565b6120a9565b6003611f736020860186613534565b60ff1603611a3d576001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166348c89491611fba604087016020880161354f565b611fca606088016040890161354f565b611fda60a0890160808a016136ef565b611fea60c08a0160a08b01613725565b611ffa60e08b0160c08c0161354f565b604080516001600160a01b0396871660208201529486169085015262ffffff909216606084015260020b60808301529190911660a082015260c0810186905260e0016040516020818303038152906040526040518263ffffffff1660e01b815260040161206791906133de565b5f604051808303815f875af1158015612082573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f389190810190613800565b5f6120bd611dac606087016040880161354f565b90508181116120f85760405162461bcd60e51b81526020600482015260076024820152666c65672064727960c81b60448201526064016106f7565b61210282826136ad565b95945050505050565b5f600261211b6020850185613534565b60ff160361220e575f612134608085016060860161354f565b6001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561216f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061219391906138a3565b50505050509150505f6121c982858760200160208101906121b4919061354f565b6121c460608a0160408b0161354f565b612828565b9050620f42406121df60a08701608088016136ef565b6121ec90620f424061392b565b6121fb9062ffffff1683613946565b6122059190613971565b925050506109cd565b600161221d6020850185613534565b60ff16036123ca575f612236608085016060860161354f565b90505f80826001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612276573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061229a919061399a565b50915091505f836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122dc573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061230091906136d4565b6001600160a01b03166123196040890160208a0161354f565b6001600160a01b03161490505f808261234557836001600160701b0316856001600160701b031661235a565b846001600160701b0316846001600160701b03165b91509150815f148061236a575080155b1561237d575f96505050505050506109cd565b6123bd61239060a08b0160808c016136ef565b61239c9061271061392b565b6123ab9062ffffff168a613946565b826123b885612710613946565b612ece565b96505050505050506109cd565b60036123d96020850185613534565b60ff160361267e575f6123f2606085016040860161354f565b6001600160a01b031661240b604086016020870161354f565b6001600160a01b03161090505f816124325761242d606086016040870161354f565b612442565b612442604086016020870161354f565b8261245c57612457604087016020880161354f565b61246c565b61246c606087016040880161354f565b61247c60a08801608089016136ef565b61248c60c0890160a08a01613725565b61249c60e08a0160c08b0161354f565b604080516001600160a01b0396871660208201529486169085015262ffffff909216606084015260020b60808301529190911660a082015260c0016040516020818303038152906040528051906020012090505f81600660405160200161250d929190918252602082015260400190565b60408051601f19818403018152908290528051602090910120631e2eaeaf60e01b82526004820181905291505f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631e2eaeaf90602401602060405180830381865afa15801561258a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125ae9190613669565b9050806001600160a01b0381165f036125ce575f955050505050506109cd565b60d082901c5f6125ec6001600160a01b03841680600160401b612ece565b90505f8761260857612603600160801b8b84612ece565b612617565b612617828b600160801b612ece565b905062ffffff8316158015906126345750620f42408362ffffff16105b1561266f57620f4240612647848261392b565b6126569062ffffff1683613946565b6126609190613971565b985050505050505050506109cd565b97506109cd9650505050505050565b505f92915050565b5f8163ffffffff165f036126ad57604051632a0c9bb560e11b815260040160405180910390fd5b6040805160028082526060820183525f9260208301908036833701905050905082815f815181106126e0576126e0613512565b602002602001019063ffffffff16908163ffffffff16815250505f8160018151811061270e5761270e613512565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81525f906001600160a01b0386169063883bdbfd906127519085906004016139d3565b5f60405180830381865afa15801561276b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526127929190810190613ab0565b5090505f815f815181106127a8576127a8613512565b6020026020010151826001815181106127c3576127c3613512565b60200260200101516127d59190613b7a565b90506127e763ffffffff861682613ba7565b93505f8160060b12801561280c575061280663ffffffff861682613be3565b60060b15155b1561281f578361281b81613c04565b9450505b50505092915050565b5f8061283386612f74565b90506001600160801b036001600160a01b038216116128a6575f6128606001600160a01b03831680613946565b9050836001600160a01b0316856001600160a01b03161061288f5761288a600160c01b8783612ece565b61289e565b61289e8187600160c01b612ece565b925050610446565b5f6128bf6001600160a01b03831680600160401b612ece565b9050836001600160a01b0316856001600160a01b0316106128ee576128e9600160801b8783612ece565b6128fd565b6128fd8187600160801b612ece565b979650505050505050565b5f6001600160a01b03821615612983576040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801561295a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061297e9190613669565b6109cd565b4792915050565b604080516001600160a01b0384811660248301525f604480840182905284518085039091018152606490930184526020830180516001600160e01b031663095ea7b360e01b1790529251908616916129e191613740565b5f604051808303815f865af19150503d805f8114612a1a576040519150601f19603f3d011682016040523d82523d5f602084013e612a1f565b606091505b5050604080516001600160a01b038681166024830152604480830187905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b179052915192935090861691612a7b9190613740565b5f604051808303815f865af19150503d805f8114612ab4576040519150601f19603f3d011682016040523d82523d5f602084013e612ab9565b606091505b50508091505080611aa55760405162461bcd60e51b8152602060048201526007602482015266617070726f766560c81b60448201526064016106f7565b5f612b07608084016060850161354f565b90505f816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b46573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b6a91906136d4565b6001600160a01b0316612b83604086016020870161354f565b6001600160a01b03161490505f80836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612bcd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bf1919061399a565b50915091505f8084612c1657826001600160701b0316846001600160701b0316612c2b565b836001600160701b0316836001600160701b03165b9092509050612c4a612c4360408a0160208b0161354f565b8789611b22565b612c805760405162461bcd60e51b81526020600482015260076024820152661d8c881cd95b9960ca1b60448201526064016106f7565b5f82612c9260408b0160208c0161354f565b6040516370a0823160e01b81526001600160a01b038a8116600483015291909116906370a0823190602401602060405180830381865afa158015612cd8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cfc9190613669565b612d0691906136ad565b90505f8111612d435760405162461bcd60e51b815260206004820152600960248201526876322061727269766560b81b60448201526064016106f7565b5f612d5460a08b0160808c016136ef565b612d609061271061392b565b612d6f9062ffffff1683613946565b90505f81612d7f86612710613946565b612d899190613c25565b612d938584613946565b612d9d9190613971565b90505f8111612dd75760405162461bcd60e51b81526020600482015260066024820152651d8c881bdd5d60d21b60448201526064016106f7565b8715612e515760405163022c0d9f60e01b81525f60048201819052602482018390523060448301526080606483015260848201526001600160a01b038a169063022c0d9f9060a4015f604051808303815f87803b158015612e36575f80fd5b505af1158015612e48573d5f803e3d5ffd5b50505050612ec1565b60405163022c0d9f60e01b8152600481018290525f602482018190523060448301526080606483015260848201526001600160a01b038a169063022c0d9f9060a4015f604051808303815f87803b158015612eaa575f80fd5b505af1158015612ebc573d5f803e3d5ffd5b505050505b5050505050505050505050565b5f80805f19858709858702925082811083820303915050805f03612f02575f8411612ef7575f80fd5b508290049050611161565b808411612f0d575f80fd5b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b5f805f8360020b12612f89578260020b612f90565b8260020b5f035b9050620d89e8811115612fb65760405163c7e13a0160e01b815260040160405180910390fd5b5f816001165f03612fcb57600160801b612fdd565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615613011576ffff97272373d413259a46990580e213a0260801c5b6004821615613030576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b600882161561304f576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b601082161561306e576fffcb9843d60f6159c9db58835c9266440260801c5b602082161561308d576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156130ac576fff2ea16466c96a3843ec78b326b528610260801c5b60808216156130cb576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156130eb576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b61020082161561310b576ff987a7253ac413176f2b074cf7815e540260801c5b61040082161561312b576ff3392b0822b70005940c7a398e4b70f30260801c5b61080082161561314b576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161561316b576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161561318b576fa9f746462d870fdf8a65dc1f90e061e50260801c5b6140008216156131ab576f70d869a156d2a1b890bb3df62baf32f70260801c5b6180008216156131cb576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156131ec576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b6202000082161561320c576e5d6af8dedb81196699c329225ee6040260801c5b6204000082161561322b576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615613248576b048a170391f7dc42444e8fa20260801c5b5f8460020b131561326757805f19816132635761326361395d565b0490505b64010000000081061561327b57600161327d565b5f5b60ff16602082901c0192505050919050565b5f8083601f84011261329f575f80fd5b5081356001600160401b038111156132b5575f80fd5b60208301915083602060e0830285010111156132cf575f80fd5b9250929050565b63ffffffff811681146132e7575f80fd5b50565b5f805f80606085870312156132fd575f80fd5b84356001600160401b03811115613312575f80fd5b61331e8782880161328f565b909550935050602085013591506040850135613339816132d6565b939692955090935050565b5f8060208385031215613355575f80fd5b82356001600160401b0381111561336a575f80fd5b8301601f8101851361337a575f80fd5b80356001600160401b0381111561338f575f80fd5b8560208284010111156133a0575f80fd5b6020919091019590945092505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61116160208301846133b0565b5f805f60408486031215613402575f80fd5b83356001600160401b03811115613417575f80fd5b6134238682870161328f565b909790965060209590950135949350505050565b6001600160a01b03811681146132e7575f80fd5b5f806040838503121561345c575f80fd5b823561346781613437565b9150602083013561347781613437565b809150509250929050565b5f805f60408486031215613494575f80fd5b83356001600160401b038111156134a9575f80fd5b6134b58682870161328f565b90945092505060208401356134c981613437565b809150509250925092565b5f80602083850312156134e5575f80fd5b82356001600160401b038111156134fa575f80fd5b6135068582860161328f565b90969095509350505050565b634e487b7160e01b5f52603260045260245ffd5b60ff811681146132e7575f80fd5b5f60208284031215613544575f80fd5b813561116181613526565b5f6020828403121561355f575f80fd5b813561116181613437565b62ffffff811681146132e7575f80fd5b8060020b81146132e7575f80fd5b5f805f805f8060c0878903121561359d575f80fd5b86356135a881613437565b955060208701356135b881613437565b945060408701356135c88161356a565b935060608701356135d88161357a565b925060808701356135e881613437565b9598949750929591949360a090920135925050565b634e487b7160e01b5f52601160045260245ffd5b5f600160ff1b8201613625576136256135fd565b505f0390565b6001600160a01b0382811682821603908111156109cd576109cd6135fd565b6001600160a01b0381811683821601908111156109cd576109cd6135fd565b5f60208284031215613679575f80fd5b5051919050565b5f81600f0b6f7fffffffffffffffffffffffffffffff1981036136a5576136a56135fd565b5f0392915050565b818103818111156109cd576109cd6135fd565b634e487b7160e01b5f52604160045260245ffd5b5f602082840312156136e4575f80fd5b815161116181613437565b5f602082840312156136ff575f80fd5b81356111618161356a565b5f6020828403121561371a575f80fd5b81516111618161356a565b5f60208284031215613735575f80fd5b81356111618161357a565b5f82518060208501845e5f920191825250919050565b80518015158114613765575f80fd5b919050565b5f6020828403121561377a575f80fd5b61116182613756565b602081525f82516080602084015261379e60a08401826133b0565b905060018060a01b03602085015116604084015260408401516060840152606084015160808401528091505092915050565b604051601f8201601f191681016001600160401b03811182821017156137f8576137f86136c0565b604052919050565b5f60208284031215613810575f80fd5b81516001600160401b03811115613825575f80fd5b8201601f81018413613835575f80fd5b80516001600160401b0381111561384e5761384e6136c0565b613861601f8201601f19166020016137d0565b818152856020838501011115613875575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b805161ffff81168114613765575f80fd5b5f805f805f805f60e0888a0312156138b9575f80fd5b87516138c481613437565b60208901519097506138d58161357a565b95506138e360408901613892565b94506138f160608901613892565b93506138ff60808901613892565b925060a088015161390f81613526565b915061391d60c08901613756565b905092959891949750929550565b62ffffff82811682821603908111156109cd576109cd6135fd565b80820281158282048414176109cd576109cd6135fd565b634e487b7160e01b5f52601260045260245ffd5b5f8261397f5761397f61395d565b500490565b80516001600160701b0381168114613765575f80fd5b5f805f606084860312156139ac575f80fd5b6139b584613984565b92506139c360208501613984565b915060408401516134c9816132d6565b602080825282518282018190525f918401906040840190835b81811015613a1057835163ffffffff168352602093840193909201916001016139ec565b509095945050505050565b5f6001600160401b03821115613a3357613a336136c0565b5060051b60200190565b5f82601f830112613a4c575f80fd5b8151613a5f613a5a82613a1b565b6137d0565b8082825260208201915060208360051b860101925085831115613a80575f80fd5b602085015b83811015613aa6578051613a9881613437565b835260209283019201613a85565b5095945050505050565b5f8060408385031215613ac1575f80fd5b82516001600160401b03811115613ad6575f80fd5b8301601f81018513613ae6575f80fd5b8051613af4613a5a82613a1b565b8082825260208201915060208360051b850101925087831115613b15575f80fd5b6020840193505b82841015613b455783518060060b8114613b34575f80fd5b825260209384019390910190613b1c565b8095505050505060208301516001600160401b03811115613b64575f80fd5b613b7085828601613a3d565b9150509250929050565b600682810b9082900b03667fffffffffffff198112667fffffffffffff821317156109cd576109cd6135fd565b5f8160060b8360060b80613bbd57613bbd61395d565b667fffffffffffff1982145f1982141615613bda57613bda6135fd565b90059392505050565b5f8260060b80613bf557613bf561395d565b808360060b0791505092915050565b5f8160020b627fffff198103613c1c57613c1c6135fd565b5f190192915050565b808201808211156109cd576109cd6135fd56fea26469706673582212200df498e8090dff1a2aa77f3ae3f867aea4f5279f73c21da7929296cceafdafbf64736f6c634300081a0033000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505070000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73000000000000000000000000caf681a66d020601342297493863e78c959e5cb20000000000000000000000001f7d7550b1b028f7571e69a784071f0205fd2efa0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951000000000000000000000000e6d3b1240334a8856686afc4754f51848453692a000000000000000000000000b0cc447d9ace8afb9ac4dae763afcf911c7e5cda
0x608060405260043610610344575f3560e01c80638a19c8bc116101bd578063cf35bdd0116100f2578063eb6e17b511610092578063fb6241c01161006d578063fb6241c014610b43578063fbfa77cf14610b62578063fe51b95514610b81578063fff2d49b14610b96575f80fd5b8063eb6e17b514610ad7578063ed26f2e814610b05578063f2fde38b14610b24575f80fd5b8063e5f04edb116100cd578063e5f04edb14610a6b578063e92d1f3a14610a80578063ea49c35e14610a9f578063eafe7a7414610abe575f80fd5b8063cf35bdd0146109c3578063d3dcde9a14610a2d578063e30c397814610a4c575f80fd5b8063a9e282b81161015d578063b24ae1f811610138578063b24ae1f814610951578063b3ab15fb14610966578063c1dbd1c314610985578063ccc73973146109a4575f80fd5b8063a9e282b8146108df578063aca4894c146108fe578063b10d9e421461091d575f80fd5b806395d8e5291161019857806395d8e529146107c557806396c82e57146107fb5780639745cc3d14610810578063a7345519146108c0575f80fd5b80638a19c8bc146107745780638da5cb5b146107885780638f45e94b146107a6575f80fd5b806351e42ab511610293578063705bc3c41161023357806379ba50971161020e57806379ba5097146106c75780637c242121146106db57806381236d1614610719578063861cf55414610747575f80fd5b8063705bc3c4146106435780637150d8ae1461066e57806376b1d08f146106a1575f80fd5b806359f026391161026e57806359f02639146105a7578063668318d5146105d25780636817031b146106055780636e3e495e14610624575f80fd5b806351e42ab51461055e578063570ca7351461057357806359cd903114610592575f80fd5b80631e134423116102fe5780634707d000116102d95780634707d000146104ba578063479c9254146104d957806347ccca021461050c5780634b7314e41461053f575f80fd5b80631e1344231461043b5780633b1ab44c146104505780633fc8cef31461046f575f80fd5b80630158a1fb1461037b578063065353961461039c57806306a72686146103d157806311da60b4146103f457806314fc78fc1461040857806317adc2111461041c575f80fd5b3661037757609a5460ff161561035657005b61035e610bb5565b3460935f82825461036f919061528d565b925050819055005b5f80fd5b348015610386575f80fd5b5061039a6103953660046152ee565b610c6b565b005b3480156103a7575f80fd5b506103bb6103b636600461533e565b610ce7565b6040516103c891906153f0565b60405180910390f35b3480156103dc575f80fd5b506103e6608d5481565b6040519081526020016103c8565b3480156103ff575f80fd5b5061039a610dc5565b348015610413575f80fd5b5061039a610dcf565b348015610427575f80fd5b5061039a6104363660046153fe565b610e21565b348015610446575f80fd5b506103e660935481565b34801561045b575f80fd5b5061039a61046a366004615445565b611037565b34801561047a575f80fd5b506104a27f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7381565b6040516001600160a01b0390911681526020016103c8565b3480156104c5575f80fd5b5061039a6104d4366004615460565b611117565b3480156104e4575f80fd5b506104a27f000000000000000000000000b0cc447d9ace8afb9ac4dae763afcf911c7e5cda81565b348015610517575f80fd5b506104a27f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a5050781565b34801561054a575f80fd5b5061039a6105593660046154cc565b61125a565b348015610569575f80fd5b506103e660925481565b34801561057e575f80fd5b506002546104a2906001600160a01b031681565b34801561059d575f80fd5b506103e660045481565b3480156105b2575f80fd5b506103e66105c136600461550a565b608b6020525f908152604090205481565b3480156105dd575f80fd5b506104a27f000000000000000000000000e6d3b1240334a8856686afc4754f51848453692a81565b348015610610575f80fd5b5061039a61061f366004615445565b6112a7565b34801561062f575f80fd5b506103e661063e366004615525565b611331565b34801561064e575f80fd5b506103e661065d366004615445565b60976020525f908152604090205481565b348015610679575f80fd5b506104a27f000000000000000000000000407b780b7760018083e51caf690b8618c63f70c881565b3480156106ac575f80fd5b506106b5604081565b60405160ff90911681526020016103c8565b3480156106d2575f80fd5b5061039a611414565b3480156106e6575f80fd5b506107096106f536600461554f565b608e6020525f908152604090205460ff1681565b60405190151581526020016103c8565b348015610724575f80fd5b5061070961073336600461554f565b60986020525f908152604090205460ff1681565b348015610752575f80fd5b5061076661076136600461550a565b6114a5565b6040516103c8929190615566565b34801561077f575f80fd5b506103e661156d565b348015610793575f80fd5b505f546104a2906001600160a01b031681565b3480156107b1575f80fd5b506103e66107c0366004615525565b61157f565b3480156107d0575f80fd5b506103e66107df3660046153fe565b609660209081525f928352604080842090915290825290205481565b348015610806575f80fd5b506103e660915481565b34801561081b575f80fd5b5061087b61082a36600461554f565b60906020525f90815260409020805460018201546002909201546001600160801b0380831693600160801b9093048116929160ff8116916001600160401b0361010083041691600160481b90041686565b604080516001600160801b039788168152958716602087015285019390935290151560608401526001600160401b0316608083015290911660a082015260c0016103c8565b3480156108cb575f80fd5b5061039a6108da3660046155d8565b611606565b3480156108ea575f80fd5b5061039a6108f936600461554f565b611746565b348015610909575f80fd5b5061039a610918366004615616565b611775565b348015610928575f80fd5b5061093c610937366004615525565b611b09565b604080519283526020830191909152016103c8565b34801561095c575f80fd5b506103e6610e1081565b348015610971575f80fd5b5061039a610980366004615445565b611b41565b348015610990575f80fd5b5061039a61099f36600461569a565b611bb4565b3480156109af575f80fd5b506103e66109be36600461554f565b611eae565b3480156109ce575f80fd5b506109e26109dd36600461554f565b611f28565b604080516001600160a01b03909816885295151560208801529315159486019490945260ff918216606086015216608084015261ffff90911660a083015260c082015260e0016103c8565b348015610a38575f80fd5b5061039a610a473660046154cc565b611f88565b348015610a57575f80fd5b506001546104a2906001600160a01b031681565b348015610a76575f80fd5b506103e660955481565b348015610a8b575f80fd5b506103e6610a9a366004615525565b612c2b565b348015610aaa575f80fd5b5061039a610ab93660046154cc565b612d6a565b348015610ac9575f80fd5b506086546106b59060ff1681565b348015610ae2575f80fd5b50610af6610af136600461554f565b612ece565b6040516103c89392919061572b565b348015610b10575f80fd5b5061039a610b1f366004615793565b612fa9565b348015610b2f575f80fd5b5061039a610b3e366004615445565b613078565b348015610b4e575f80fd5b5061039a610b5d3660046157b6565b6130eb565b348015610b6d575f80fd5b506003546104a2906001600160a01b031681565b348015610b8c575f80fd5b506103e660945481565b348015610ba1575f80fd5b5061039a610bb03660046157da565b6132e4565b5f610bbe61156d565b90506094548111610bcc5750565b5f609154118015610bde57505f609354115b15610c6657609154609354610bfb90670de0b6b3a7640000615814565b610c05919061583f565b60925f828254610c15919061528d565b909155505060935460915460405183927f866f813a2289b14a1e94be9b6a7db4b5ad759df3fb1466245f650642f3cc7a5692610c5992918252602082015260400190565b60405180910390a25f6093555b609455565b5f546001600160a01b03163314610c955760405163ea8e4eb560e01b815260040160405180910390fd5b60058360ff1660408110610cab57610cab615852565b6002020154600160a81b900460ff16610cd757604051633640530560e01b815260040160405180910390fd5b610ce2838383613811565b505050565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915260ff8084165f90815260856020526040902090831660048110610d4457610d44615852565b6040805160e08101825260049290920292909201805460ff811683526001600160a01b03610100909104811660208401526001820154811693830193909352600280820154808516606085015262ffffff600160a01b8204166080850152600160b81b9004900b60a08301526003015490911660c082015290505b92915050565b610dcd610bb5565b565b610dd7610bb5565b610ddf613d39565b610dfc5760405163ea8e4eb560e01b815260040160405180910390fd5b610e0461156d565b608d556094546095541015610dcd57609454609555610dcd613d5f565b609954600114610e445760405163769dd35360e11b815260040160405180910390fd5b60026099555f82815260966020908152604080832060ff8516845290915281205490819003610e86576040516301f30c8760e21b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018490525f907f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b031690636352211e90602401602060405180830381865afa158015610eeb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0f9190615866565b5f85815260966020908152604080832060ff881680855292528083208390559293509091600591908110610f4557610f45615852565b60020201546001600160a01b03165f81815260976020526040812080549293508592909190610f75908490615881565b90915550610f86905081838561402a565b610feb575f85815260966020908152604080832060ff8816845282528083208690556001600160a01b0384168352609790915281208054859290610fcb90849061528d565b925050819055506040516301f30c8760e21b815260040160405180910390fd5b604080515f81526020810185905260ff86169187917f8110a247e3bf84088ca20c991ad431b68293ca3bdfe626df91b9744bf4d7b9ce910160405180910390a350506001609955505050565b5f546001600160a01b031633146110615760405163ea8e4eb560e01b815260040160405180910390fd5b60405147905f906001600160a01b0384169083908381818185875af1925050503d805f81146110ab576040519150601f19603f3d011682016040523d82523d5f602084013e6110b0565b606091505b50509050806110d2576040516381063e5160e01b815260040160405180910390fd5b6040518281526001600160a01b038416905f907f3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc9060200160405180910390a3505050565b5f546001600160a01b031633146111415760405163ea8e4eb560e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611185573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111a99190615894565b6001600160a01b0384165f90815260976020526040902054909150818110156111db576111d68183615881565b6111dd565b5f5b91506111ea84848461402a565b611207576040516381063e5160e01b815260040160405180910390fd5b826001600160a01b0316846001600160a01b03167f3af790fafda720819b2fc6e15090606e81154e0ac9a92d38ecad006d99d20ecc8460405161124c91815260200190565b60405180910390a350505050565b611262610dc5565b5f61126b61156d565b90505f5b828110156112a15761129984848381811061128c5761128c615852565b90506020020135836140f9565b60010161126f565b50505050565b5f546001600160a01b031633146112d15760405163ea8e4eb560e01b815260040160405180910390fd5b6003546001600160a01b03161515806112f157506001600160a01b038116155b1561130f576040516301f30c8760e21b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b5f60058360ff166040811061134857611348615852565b6002020154600160a81b900460ff1661137457604051633640530560e01b815260040160405180910390fd5b7f000000000000000000000000407b780b7760018083e51caf690b8618c63f70c86001600160a01b0316632a8504676113ac85614559565b846107086040518463ffffffff1660e01b81526004016113ce939291906158f0565b602060405180830381865afa1580156113e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061140d9190615894565b9392505050565b6001546001600160a01b03163314158061143757506001546001600160a01b0316155b156114555760405163ea8e4eb560e01b815260040160405180910390fd5b600180545f80546001600160a01b0383166001600160a01b031991821681178355921690925560405190917fdc3c82f4776932041f15a08f769aadd6ed44c2a975e64bbf0fde8cf812f8b6b891a2565b6114ad615115565b6114b5615115565b60ff83165f90815260876020908152604080832060889092529182902082516060810190935290918260038282826020028201915b8154815260200190600101908083116114ea575050604080516060810191829052949650859350600392509050825f855b82829054906101000a90046001600160401b03166001600160401b03168152602001906008019060208260070104928301926001038202915080841161151b5790505050505050905091509150915091565b5f61157a610e104261583f565b905090565b5f60058360ff166040811061159657611596615852565b6002020154600160a81b900460ff166115b057505f610dbf565b7f000000000000000000000000407b780b7760018083e51caf690b8618c63f70c86001600160a01b031663c55cd26b6115e885614559565b846040518363ffffffff1660e01b81526004016113ce92919061591e565b5f546001600160a01b031633146116305760405163ea8e4eb560e01b815260040160405180910390fd5b60058360ff166040811061164657611646615852565b6002020154600160a81b900460ff1661167257604051633640530560e01b815260040160405180910390fd5b61ffff8216158061168857506103e861ffff8316115b156116a6576040516301f30c8760e21b815260040160405180910390fd5b8160058460ff16604081106116bd576116bd615852565b60020201805461ffff92909216600160c01b0261ffff60c01b1990921691909117905580600560ff8516604081106116f7576116f7615852565b60020201600101556040805161ffff841681526020810183905260ff8516917f21d534072f91477f5fe629b59c0768b993e0a19aae8b98a464910bee3803f095910160405180910390a2505050565b5f546001600160a01b031633146117705760405163ea8e4eb560e01b815260040160405180910390fd5b600455565b6040516331a9108f60e11b81526004810186905233906001600160a01b037f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505071690636352211e90602401602060405180830381865afa1580156117da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117fe9190615866565b6001600160a01b0316146118255760405163ea8e4eb560e01b815260040160405180910390fd5b8215806118325750600383115b8061183d5750828114155b1561185b576040516301f30c8760e21b815260040160405180910390fd5b5f858152608f60205260408120815b85811015611a935760865460ff1687878381811061188a5761188a615852565b905060200201602081019061189f919061550a565b60ff161015806118f7575060058787838181106118be576118be615852565b90506020020160208101906118d3919061550a565b60ff16604081106118e6576118e6615852565b6002020154600160a81b900460ff16155b1561191557604051633640530560e01b815260040160405180910390fd5b5f5b818110156119995787878381811061193157611931615852565b9050602002016020810190611946919061550a565b60ff1688888381811061195b5761195b615852565b9050602002016020810190611970919061550a565b60ff1603611991576040516301f30c8760e21b815260040160405180910390fd5b600101611917565b508686828181106119ac576119ac615852565b90506020020160208101906119c1919061550a565b8282600381106119d3576119d3615852565b602091828204019190066101000a81548160ff021916908360ff160217905550848482818110611a0557611a05615852565b9050602002016020810190611a1a919061593f565b826001018260038110611a2f57611a2f615852565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550848482818110611a6657611a66615852565b9050602002016020810190611a7b919061593f565b611a899061ffff168461528d565b925060010161186a565b508161271014611ab6576040516301f30c8760e21b815260040160405180910390fd5b60028101805460ff191660ff871690811790915560405190815287907f9289c2bdf2133c72d7dccab03946c733038fb8d5b7e24787b0afbd7a77aad935906020015b60405180910390a250505050505050565b5f80333014611b2b5760405163ea8e4eb560e01b815260040160405180910390fd5b611b3584846146e3565b915091505b9250929050565b5f546001600160a01b03163314611b6b5760405163ea8e4eb560e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f99d737e0adf2c449d71890b86772885ec7959b152ddb265f76325b6e68e105d3905f90a250565b5f546001600160a01b03163314611bde5760405163ea8e4eb560e01b815260040160405180910390fd5b608654604060ff90911610611c06576040516301f30c8760e21b815260040160405180910390fd5b6001600160a01b038716611c2d576040516301f30c8760e21b815260040160405180910390fd5b5f5b60865460ff9081169082161015611c9457876001600160a01b031660058260ff1660408110611c6057611c60615852565b60020201546001600160a01b031603611c8c576040516301f30c8760e21b815260040160405180910390fd5b600101611c2f565b5060ff8516600114801590611cad575060ff8516600214155b15611ccb576040516301f30c8760e21b815260040160405180910390fd5b8361ffff165f03611cdc5761012c93505b6103e861ffff85161115611d03576040516301f30c8760e21b815260040160405180910390fd5b6086546040805160e0810182526001600160a01b038a168152881515602082015260018183015260ff88811660608301525f608083015261ffff881660a083015260c08201879052909216919060059083908110611d6357611d63615852565b8251600291909102919091018054602084015160408501516060860151608087015160a088015161ffff16600160c01b0261ffff60c01b1960ff928316600160b81b021662ffffff60b81b19938316600160b01b0260ff60b01b19951515600160a81b029590951661ffff60a81b19961515600160a01b026001600160a81b03199098166001600160a01b03909a169990991796909617949094169690961791909117169190911717815560c09092015160019092019190915560868054909116905f611e2f8361595a565b91906101000a81548160ff021916908360ff16021790555050611e53818484613811565b604080516001600160a01b038a168152881515602082015260ff888116828401529151918316917f0e6b0001da0748dd2bd3e559964cc3186cda6147278313f57e20122694649b5d9181900360600190a25050505050505050565b5f81815260906020526040812080546002820154600160801b9091046001600160801b03169060ff161561140d57670de0b6b3a76400008260010154609254611ef79190615881565b8354611f0c91906001600160801b0316615814565b611f16919061583f565b611f20908261528d565b949350505050565b60058160408110611f37575f80fd5b6002020180546001909101546001600160a01b038216925060ff600160a01b8304811692600160a81b8104821692600160b01b8204831692600160b81b8304169161ffff600160c01b909104169087565b609954600114611fab5760405163769dd35360e11b815260040160405180910390fd5b6002609955611fb8614922565b611fd55760405163ea8e4eb560e01b815260040160405180910390fd5b611fdd610bb5565b5f611fe661156d565b9050611ff0613d39565b15611ffb57608d8190555b81612004615133565b5f826001600160401b0381111561201d5761201d615978565b60405190808252806020026020018201604052801561205657816020015b612043615115565b81526020019060019003908161203b5790505b5090505f836001600160401b0381111561207257612072615978565b6040519080825280602002602001820160405280156120ab57816020015b612098615115565b8152602001906001900390816120905790505b5090505f846001600160401b038111156120c7576120c7615978565b6040519080825280602002602001820160405280156120f0578160200160208202803683370190505b5090505f5b858110156124c5575f89898381811061211057612110615852565b602090810292909201355f8181526090909352604090922060028101549293509160ff16905080156121c657506040516382afd23b60e01b8152600481018390527f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b0316906382afd23b90602401602060405180830381865afa1580156121a0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121c4919061598c565b155b156121d5576121d5828a6140f9565b80546002820154600160801b9091046001600160801b03169060ff161561224557670de0b6b3a764000082600101546092546122119190615881565b835461222691906001600160801b0316615814565b612230919061583f565b61223a908261528d565b609254600184015590505b805f03612254575050506124bd565b5f838152608f60205260409020600281015460ff16612271615115565b612279615115565b8260ff165f0361229e576001925061228f614953565b60ff1682526127108152612343565b604080516060810191829052908590600390825f855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116122b457505060408051606081019182905295975060018a0194506003935091508390505f855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411612303579050505050505090505b85546001600160801b03168655885183908a908a90811061236657612366615852565b60ff909216602092830291909101909101525f805b8460ff168110156124b3575f60ff861661239683600161528d565b146123d2576127108483600381106123b0576123b0615852565b60200201516123c39061ffff168a615814565b6123cd919061583f565b6123dc565b6123dc8389615881565b90506123e8818461528d565b9250808e8c815181106123fd576123fd615852565b6020026020010151836003811061241657612416615852565b602002015284826003811061242d5761242d615852565b60200201518d8c8151811061244457612444615852565b6020026020010151836003811061245d5761245d615852565b60ff9092166020929092020152808f86846003811061247e5761247e615852565b602002015160ff166040811061249657612496615852565b602002018181516124a7919061528d565b9052505060010161237b565b5050505050505050505b6001016120f5565b506124ce615133565b6124d6615133565b5f5b60865460ff90811690821610156126f8575f878260ff16604081106124ff576124ff615852565b60200201519050801580612514575060045481105b1561251f57506126f0565b5f60058360ff166040811061253657612536615852565b600202016001015490505f829050815f146125cd5760ff84165f908152608c60205260409020548c146125835760ff84165f908152608c602090815260408083208f9055608b9091528120555b60ff84165f908152608b602052604081205483116125a1575f6125bd565b60ff85165f908152608b60205260409020546125bd9084615881565b9050808211156125cb578091505b505b6004548110156125df575050506126f0565b604051635886cf2160e11b815260ff8516600482015260248101829052309063b10d9e429060440160408051808303815f875af1925050508015612640575060408051601f3d908101601f1916820190925261263d918101906159a7565b60015b612686578360ff167f658935f8cd82af21d125a8f1e19e9e8b5b1137a405b0218bc5ee4b3ddac76cc28260405161267991815260200190565b60405180910390a26126ec565b81888760ff166040811061269c5761269c615852565b6020020152808760ff8816604081106126b7576126b7615852565b602002015283156126e95760ff86165f908152608b6020526040812080548392906126e390849061528d565b90915550505b50505b5050505b6001016124d8565b505f5b87811015612c19575f8b8b8381811061271657612716615852565b9050602002013590505f5b85838151811061273357612733615852565b602002602001015160ff16811015612c0f575f88848151811061275857612758615852565b6020026020010151826003811061277157612771615852565b60200201519050805f036127855750612c07565b5f88858151811061279857612798615852565b602002602001015183600381106127b1576127b1615852565b60200201519050858160ff16604081106127cd576127cd615852565b60200201515f03612871575f8481526090602052604090208054839190601090612808908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508060ff16847fc2cda032f63ebe7629abecffad35589c71515edfd5b2c2048e340b3033a536e48460405161286291815260200190565b60405180910390a35050612c07565b5f8b8260ff166040811061288757612887615852565b6020020151878360ff16604081106128a1576128a1615852565b60200201518d8460ff16604081106128bb576128bb615852565b60200201516128ca9190615881565b6128d49085615814565b6128de919061583f565b90505f6128eb8285615881565b90505f8d8460ff166040811061290357612903615852565b6020020151858b8660ff166040811061291e5761291e615852565b602002015161292d9190615814565b612937919061583f565b905082156129d2575f878152609060205260409020805484919060109061296f908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508360ff16877fc2cda032f63ebe7629abecffad35589c71515edfd5b2c2048e340b3033a536e4856040516129c991815260200190565b60405180910390a35b805f036129e3575050505050612c07565b5f8781526098602052604081205460ff1680612a0857506003546001600160a01b0316155b15612acf576040516331a9108f60e11b8152600481018990527f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b031690636352211e90602401602060405180830381865afa925050508015612a8e575060408051601f3d908101601f19168201909252612a8b91810190615866565b60015b612a9957505f612b35565b612ac760058760ff1660408110612ab257612ab2615852565b60020201546001600160a01b0316828561402a565b915050612b35565b6040516303ed890760e61b81526004810189905260ff8616602482015260448101839052309063fb6241c0906064015f604051808303815f87803b158015612b15575f80fd5b505af1925050508015612b26575060015b612b3157505f612b35565b5060015b8015612b8057604080518481526020810184905260ff8716918a917f8110a247e3bf84088ca20c991ad431b68293ca3bdfe626df91b9744bf4d7b9ce910160405180910390a3612c00565b5f88815260966020908152604080832060ff8916845290915281208054849290612bab90849061528d565b9091555082905060975f600560ff891660408110612bcb57612bcb615852565b60020201546001600160a01b0316815260208101919091526040015f9081208054909190612bfa90849061528d565b90915550505b5050505050505b600101612721565b50506001016126fb565b50506001609955505050505050505050565b5f8060058460ff1660408110612c4357612c43615852565b600202018054909150600160a81b900460ff16612c63575f915050610dbf565b80545f905f19600160b01b90910460ff1601612cef5760405163371f24af60e11b815260ff86166004820152602481018590523090636e3e495e90604401602060405180830381865afa925050508015612cda575060408051601f3d908101601f19168201909252612cd791810190615894565b60015b612ce8575f92505050610dbf565b9050612d2e565b5f612cf9866149d3565b9050805f03612d0d575f9350505050610dbf565b670de0b6b3a7640000612d208683615814565b612d2a919061583f565b9150505b815461271090612d4990600160c01b900461ffff16826159e8565b612d579061ffff1683615814565b612d61919061583f565b95945050505050565b5f546001600160a01b03163314612d945760405163ea8e4eb560e01b815260040160405180910390fd5b612d9c610dc5565b5f5b81811015610ce2575f838383818110612db957612db9615852565b9050602002013590505f60905f8381526020019081526020015f209050612ddf82614aec565b600281015460ff1615612df3575050612ec6565b5f612dfd83614ded565b9050805f03612e0e57505050612ec6565b81546001600160801b0319166001600160801b03821617825560925460018084019190915560028301805460ff19169091179055612e4a61156d565b8260020160016101000a8154816001600160401b0302191690836001600160401b031602179055508060915f828254612e83919061528d565b90915550506002820154604080518381526101009092046001600160401b0316602083015284915f80516020615e61833981519152910160405180910390a25050505b600101612d9e565b612ed6615115565b612ede615115565b5f838152608f602052604080822060028101548251606081019384905291928392600184019260ff169184906003908289855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612f115750506040805160608101918290529598508794506003935091508390505f855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411612f5d5750979d949c50949a509298505050505050505050565b6040516331a9108f60e11b81526004810183905233906001600160a01b037f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505071690636352211e90602401602060405180830381865afa15801561300e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130329190615866565b6001600160a01b0316146130595760405163ea8e4eb560e01b815260040160405180910390fd5b5f91825260986020526040909120805460ff1916911515919091179055565b5f546001600160a01b031633146130a25760405163ea8e4eb560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f239a2ddded15777fa246aed5f7e1a9bc69a39d4eb4a397034d1d85766cca7d4c905f90a250565b33301461310b5760405163ea8e4eb560e01b815260040160405180910390fd5b5f60058360ff166040811061312257613122615852565b60020201546003546040516370a0823160e01b81526001600160a01b039182166004820152911691505f9082906370a0823190602401602060405180830381865afa158015613173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131979190615894565b6003549091506131b29083906001600160a01b03168561402a565b6131cf576040516301f30c8760e21b815260040160405180910390fd5b6003546040516370a0823160e01b81526001600160a01b0391821660048201525f918391908516906370a0823190602401602060405180830381865afa15801561321b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061323f9190615894565b6132499190615881565b9050805f0361326b576040516301f30c8760e21b815260040160405180910390fd5b6003546040516307e0ace760e21b81526004810188905260ff871660248201526001600160a01b0385811660448301526064820184905290911690631f82b39c906084015f604051808303815f87803b1580156132c6575f80fd5b505af11580156132d8573d5f803e3d5ffd5b50505050505050505050565b6099546001146133075760405163769dd35360e11b815260040160405180910390fd5b6002609955613314614922565b6133315760405163ea8e4eb560e01b815260040160405180910390fd5b613339610dc5565b5f838152609060205260408120905b82811015613805575f84848381811061336357613363615852565b90506020020135905085810361338c576040516301f30c8760e21b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018290527f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b031690636352211e90602401602060405180830381865afa92505050801561340d575060408051601f3d908101601f1916820190925261340a91810190615866565b60015b1561342b57604051636f5888a160e11b815260040160405180910390fd5b60405163ac36e81560e01b8152600481018790525f907f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b03169063ac36e81590602401602060405180830381865afa158015613490573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134b49190615a02565b604051638cfd9b5b60e01b8152600481018490529091505f906001600160a01b037f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505071690638cfd9b5b90602401602060405180830381865afa15801561351c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135409190615894565b905061ffff8116158061357857508061ffff168261ffff161415801561357857508061ffff1660108363ffffffff16901c61ffff1614155b1561359657604051631b81740360e11b815260040160405180910390fd5b5f83815260906020526040902080546002820154600160801b9091046001600160801b03169060ff161561363c57670de0b6b3a764000082600101546092546135df9190615881565b83546135f491906001600160801b0316615814565b6135fe919061583f565b613608908261528d565b8254609180549293506001600160801b03909116915f9061362a908490615881565b909155505060028201805460ff191690555b5f8255600282018054610100600160c81b0319169055609254600183015586548190889060109061367e908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505f5b60865460ff9081169082161015613746575f86815260966020908152604080832060ff85168452909152902054801561373d575f60965f8981526020019081526020015f205f8460ff1660ff1681526020019081526020015f20819055508060965f8e81526020019081526020015f205f8460ff1660ff1681526020019081526020015f205f828254613737919061528d565b90915550505b506001016136a4565b506003546001600160a01b0316156137b95760035460405163d1c2babb60e01b8152600481018c9052602481018790526001600160a01b039091169063d1c2babb906044015f604051808303815f87803b1580156137a2575f80fd5b505af11580156137b4573d5f803e3d5ffd5b505050505b848a7faf5c71ea635d254063d323b6a94cb2a66d3b966e1de036d93ec664e3991b01fe836040516137ec91815260200190565b60405180910390a3505060019093019250613348915050565b50506001609955505050565b5f60058460ff166040811061382857613828615852565b600202018054604051631a860ecf60e31b81529192506001600160a01b037f000000000000000000000000407b780b7760018083e51caf690b8618c63f70c881169263d430767892613884928892889290911690600401615b2f565b5f6040518083038186803b15801561389a575f80fd5b505afa1580156138ac573d5f803e3d5ffd5b50508254600160b01b900460ff1660011491505080156139565750604051633cda067560e21b81526001600160a01b037f000000000000000000000000407b780b7760018083e51caf690b8618c63f70c8169063f36819d4906139159086908690600401615b5a565b602060405180830381865afa158015613930573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613954919061598c565b155b156139745760405163c4c321d160e01b815260040160405180910390fd5b8054600160b81b900460ff16156139d85761398d61156d565b60ff85165f908152608a6020526040902054036139bd5760405163c4c321d160e01b815260040160405180910390fd5b6139c561156d565b60ff85165f908152608a60205260409020555b80545f908190600160b81b900460ff1615613ab0575f613a0087670de0b6b3a7640000612c2b565b90508015613a3e578354613a2190600160c01b900461ffff166127106159e8565b61ffff16613a3182612710615814565b613a3b919061583f565b92505b604051638f45e94b60e01b815260ff88166004820152670de0b6b3a764000060248201523090638f45e94b90604401602060405180830381865afa925050508015613aa6575060408051601f3d908101601f19168201909252613aa391810190615894565b60015b15613aae5791505b505b5f5b600460ff82161015613b985760ff8116851115613b255785858260ff16818110613ade57613ade615852565b905060e0020160855f8960ff1660ff1681526020019081526020015f208260ff1660048110613b0f57613b0f615852565b60040201613b1d8282615bb1565b905050613b90565b60ff8088165f90815260856020526040902090821660048110613b4a57613b4a615852565b6004020180546001600160a81b03191681556001810180546001600160a01b03199081169091556002820180546001600160d01b03191690556003909101805490911690555b600101613ab2565b50825460ff60b81b1916600160b81b60ff8616021783555f613bc287670de0b6b3a764000061157f565b9050805f03613be45760405163c4c321d160e01b815260040160405180910390fd5b82151580613bf157508115155b15613c51575f8315801590613c0b5750613c0b82856150ba565b90505f8315801590613c225750613c2283856150ba565b905081158015613c30575080155b15613c4e5760405163c4c321d160e01b815260040160405180910390fd5b50505b60ff8781165f908152608760209081526040808320838155600181018490556002018390556088825280832083905560899091529020805460ff191690558454600160b01b90041660011901613d025760ff87165f908152608760205260409020819055613cbd61156d565b60ff88165f908152608860209081526040808320805467ffffffffffffffff19166001600160401b0395909516949094179093556089905220805460ff191660011790555b60405160ff86811682528816907f9ec53258cd9bc0432e41797e0a280c6bf75cc16ae1e1e19d4228e521c4e7566590602001611af8565b5f80546001600160a01b031633148061157a5750506002546001600160a01b0316331490565b5f613d6861156d565b90505f5b60865460ff90811690821610156140265760058160ff1660408110613d9357613d93615852565b6002020154600160a81b900460ff161580613dd357506002600560ff831660408110613dc157613dc1615852565b6002020154600160b01b900460ff1614155b61401e57604051638f45e94b60e01b815260ff82166004820152670de0b6b3a764000060248201525f903090638f45e94b90604401602060405180830381865afa925050508015613e41575060408051601f3d908101601f19168201909252613e3e91810190615894565b60015b613e4b575061401e565b9050805f03613e5a575061401e565b60ff8083165f90815260896020526040812054909116908115613e8757613e82600183615ca2565b613e93565b613e9360016003615ca2565b60ff8086165f908152608760205260409020919250821660038110613eba57613eba615852565b015415801590613f1e575060ff8085165f9081526088602052604090206001600160401b03871691831660038110613ef457613ef4615852565b600491828204019190066008029054906101000a90046001600160401b03166001600160401b0316145b15613f2b5750505061401e565b60ff8085165f9081526087602052604090208491841660038110613f5157613f51615852565b015560ff8085165f9081526088602052604090208691841660038110613f7957613f79615852565b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055506003826001613fb79190615cbb565b613fc19190615cd4565b60ff8581165f81815260896020908152604091829020805460ff19169590941694909417909255905185815290917ff3e2eaa484b746f047e870b63f6a8b13f6540040c3e1e2c1efa26ce7fd24f687910160405180910390a25050505b600101613d6c565b5050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f9283928392918816916140879190615cf5565b5f604051808303815f865af19150503d805f81146140c0576040519150601f19603f3d011682016040523d82523d5f602084013e6140c5565b606091505b50915091508180156140ef5750805115806140ef5750808060200190518101906140ef919061598c565b9695505050505050565b5f828152609060205260409020600281015460ff161561419457670de0b6b3a7640000816001015460925461412e9190615881565b825461414391906001600160801b0316615814565b61414d919061583f565b8154829060109061416f908490600160801b90046001600160801b03166159c9565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b6092546001820155600281015460ff1680156141c357506002810154600160481b90046001600160801b031615155b80156141e15750600281015461010090046001600160401b03168210155b1561425057600281015481546091546001600160801b03600160481b90930483169261420e921690615881565b614218919061528d565b60915560028101805482546001600160801b0319166001600160801b03600160481b830416178355600160481b600160c81b03191690555b5f61425a84614ded565b9050805f036142ef57600282015460ff16156142a1578154609180546001600160801b03909216915f9061428f908490615881565b909155505060028201805460ff191690555b81546001600160801b0319168255600282018054610100600160c81b0319169055604080515f808252602082015285915f80516020615e61833981519152910160405180910390a250505050565b600282015460ff166143b35781546001600160801b0319166001600160801b038216178255600282018054600160481b600160c81b0319169081905561010090046001600160401b03165f036143735761434a83600161528d565b8260020160016101000a8154816001600160401b0302191690836001600160401b031602179055505b6002820154604080518381526101009092046001600160401b0316602083015285915f80516020615e6183398151915291015b60405180910390a26144d7565b81546001600160801b031681101561444157815460915482916143e1916001600160801b0390911690615881565b6143eb919061528d565b60915581546001600160801b0319166001600160801b038216178255600282018054600160481b600160c81b0319169055604080518281526020810185905285915f80516020615e6183398151915291016143a6565b81546001600160801b03168111156144a75760028201546001600160801b03828116600160481b90920416146144a257600282018054600160481b600160c81b031916600160481b6001600160801b0384160217905561434a83600161528d565b6144d7565b6002820154600160481b90046001600160801b0316156144d757600282018054600160481b600160c81b03191690555b600282015460ff161580156144fd5750600282015461010090046001600160401b031615155b801561451b5750600282015461010090046001600160401b03168310155b156112a15760028201805460ff191660011790558154609180546001600160801b03909216915f9061454e90849061528d565b909155505050505050565b60605f60058360ff166040811061457257614572615852565b6002020154600160b81b900460ff169050806001600160401b0381111561459b5761459b615978565b60405190808252806020026020018201604052801561460057816020015b6040805160e0810182525f8082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282525f199092019101816145b95790505b5091505f5b8160ff168160ff1610156146dc5760ff8085165f9081526085602052604090209082166004811061463857614638615852565b6040805160e08101825260049290920292909201805460ff80821684526001600160a01b03610100909204821660208501526001830154821694840194909452600280830154808316606086015262ffffff600160a01b8204166080860152600160b81b9004900b60a08401526003909101541660c08201528451909185919084169081106146c9576146c9615852565b6020908102919091010152600101614605565b5050919050565b5f805f60058560ff16604081106146fc576146fc615852565b600202018054909150600160a81b900460ff1661472c57604051633640530560e01b815260040160405180910390fd5b5f6147378686612c2b565b9050805f0361475957604051631368280d60e31b815260040160405180910390fd5b81546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa15801561479e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906147c29190615894565b609a805460ff1916600117905590506001600160a01b037f000000000000000000000000407b780b7760018083e51caf690b8618c63f70c81663b253b1fc8761480a8a614559565b856040518463ffffffff1660e01b815260040161482892919061591e565b604080518083038185885af1158015614843573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061486891906159a7565b609a805460ff1916905584546040516370a0823160e01b81523060048201529196508392506001600160a01b0316906370a0823190602401602060405180830381865afa1580156148bb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906148df9190615894565b6148e99190615881565b94508185101561490c5760405163273f148b60e11b815260040160405180910390fd5b85841115614918578593505b5050509250929050565b5f61492b613d39565b156149365750600190565b6004608d54614945919061528d565b61494d61156d565b11905090565b5f805b60865460ff90811690821610156149cc5760058160ff166040811061497d5761497d615852565b6002020154600160a81b900460ff1680156149ba575060058160ff16604081106149a9576149a9615852565b6002020154600160a01b900460ff16155b156149c457919050565b600101614956565b505f905090565b60ff8082165f90815260896020526040812054909116818115614a00576149fb600183615ca2565b614a0c565b614a0c60016003615ca2565b60ff8086165f9081526087602052604081209293509190831660038110614a3557614a35615852565b015460ff8087165f9081526088602052604081209293509190841660038110614a6057614a60615852565b600491828204019190066008029054906101000a90046001600160401b031690505f614a8a61156d565b9050821580614aaa5750806001600160401b0316826001600160401b0316115b80614ad057506001600160401b038116614ac5600184615d0b565b6001600160401b0316105b15614ae157505f9695505050505050565b509095945050505050565b7f000000000000000000000000b0cc447d9ace8afb9ac4dae763afcf911c7e5cda6001600160a01b03161580614b2f57505f818152608e602052604090205460ff165b15614b375750565b5f818152608e60209081526040808320805460ff19166001179055608f90915281206002015460ff169003614d445760405163eb6e17b560e01b8152600481018290527f000000000000000000000000b0cc447d9ace8afb9ac4dae763afcf911c7e5cda6001600160a01b03169063eb6e17b59060240160e060405180830381865afa925050508015614be7575060408051601f3d908101601f19168201909252614be491810190615d71565b60015b15614d44575f8160ff16118015614c02575060038160ff1611155b15614d405760015f805b8360ff16811015614cb45760865460ff16868260038110614c2f57614c2f615852565b602002015160ff16101580614c7c57506005868260038110614c5357614c53615852565b602002015160ff1660408110614c6b57614c6b615852565b6002020154600160a81b900460ff16155b15614c85575f92505b848160038110614c9757614c97615852565b6020020151614caa9061ffff168361528d565b9150600101614c0c565b50818015614cc3575080612710145b15614d3d575f868152608f60205260409020614ce181876003615152565b50614cf1600182018660036151e2565b5060028101805460ff191660ff861690811790915560405190815287907f9289c2bdf2133c72d7dccab03946c733038fb8d5b7e24787b0afbd7a77aad9359060200160405180910390a2505b50505b5050505b604051634091b68b60e11b8152600481018290527f000000000000000000000000b0cc447d9ace8afb9ac4dae763afcf911c7e5cda6001600160a01b0316906381236d1690602401602060405180830381865afa925050508015614dc5575060408051601f3d908101601f19168201909252614dc29181019061598c565b60015b15614dea578015614026575f828152609860205260409020805460ff19166001179055505b50565b6040516382afd23b60e01b8152600481018290525f907f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b0316906382afd23b90602401602060405180830381865afa158015614e52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614e76919061598c565b614e8157505f919050565b60405162ecfa2f60e31b8152600481018390527f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b031690630767d17890602401602060405180830381865afa158015614ee3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614f079190615894565b9050801580614f3d57507f000000000000000000000000e6d3b1240334a8856686afc4754f51848453692a6001600160a01b0316155b15614f4757919050565b6040516364f5a33160e11b8152600481018390525f907f000000000000000000000000968c5f0b6fe2f77b221f5e015c955f32f9a505076001600160a01b03169063c9eb466290602401602060405180830381865afa158015614fac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614fd09190615e45565b905060028160ff161015614fe45750919050565b604051636f2641e160e01b8152600481018490525f907f000000000000000000000000e6d3b1240334a8856686afc4754f51848453692a6001600160a01b031690636f2641e190602401602060405180830381865afa158015615049573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061506d9190615894565b9050805f0361507d575050919050565b61271060038360ff16101561509457612ee0615098565b6132c85b6150a69061ffff1683615814565b6150b0919061583f565b611f20908461528d565b5f6127106150ca6105dc82615881565b6150d49084615814565b6150de919061583f565b831015801561140d57506127106150f76105dc8261528d565b6151019084615814565b61510b919061583f565b9092111592915050565b60405180606001604052806003906020820280368337509192915050565b6040518061080001604052806040906020820280368337509192915050565b6001830191839082156151d2579160200282015f5b838211156151a457835183826101000a81548160ff021916908360ff16021790555092602001926001016020815f01049283019260010302615167565b80156151d05782816101000a81549060ff02191690556001016020815f010492830192600103026151a4565b505b506151de929150615265565b5090565b6001830191839082156151d2579160200282015f5b8382111561523757835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026151f7565b80156151d05782816101000a81549061ffff0219169055600201602081600101049283019260010302615237565b5b808211156151de575f8155600101615266565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610dbf57610dbf615279565b60ff81168114614dea575f80fd5b5f8083601f8401126152be575f80fd5b5081356001600160401b038111156152d4575f80fd5b60208301915083602060e083028501011115611b3a575f80fd5b5f805f60408486031215615300575f80fd5b833561530b816152a0565b925060208401356001600160401b03811115615325575f80fd5b615331868287016152ae565b9497909650939450505050565b5f806040838503121561534f575f80fd5b823561535a816152a0565b9150602083013561536a816152a0565b809150509250929050565b60ff815116825260018060a01b03602082015116602083015260018060a01b03604082015116604083015260018060a01b03606082015116606083015262ffffff608082015116608083015260a08101516153d560a084018260020b9052565b5060c0810151610ce260c08401826001600160a01b03169052565b60e08101610dbf8284615375565b5f806040838503121561540f575f80fd5b82359150602083013561536a816152a0565b6001600160a01b0381168114614dea575f80fd5b803561544081615421565b919050565b5f60208284031215615455575f80fd5b813561140d81615421565b5f8060408385031215615471575f80fd5b823561547c81615421565b9150602083013561536a81615421565b5f8083601f84011261549c575f80fd5b5081356001600160401b038111156154b2575f80fd5b6020830191508360208260051b8501011115611b3a575f80fd5b5f80602083850312156154dd575f80fd5b82356001600160401b038111156154f2575f80fd5b6154fe8582860161548c565b90969095509350505050565b5f6020828403121561551a575f80fd5b813561140d816152a0565b5f8060408385031215615536575f80fd5b8235615541816152a0565b946020939093013593505050565b5f6020828403121561555f575f80fd5b5035919050565b60c0810181845f5b600381101561558d57815183526020928301929091019060010161556e565b50505060608201835f5b60038110156155bf5781516001600160401b0316835260209283019290910190600101615597565b5050509392505050565b61ffff81168114614dea575f80fd5b5f805f606084860312156155ea575f80fd5b83356155f5816152a0565b92506020840135615605816155c9565b929592945050506040919091013590565b5f805f805f6060868803121561562a575f80fd5b8535945060208601356001600160401b03811115615646575f80fd5b6156528882890161548c565b90955093505060408601356001600160401b03811115615670575f80fd5b61567c8882890161548c565b969995985093965092949392505050565b8015158114614dea575f80fd5b5f805f805f805f60c0888a0312156156b0575f80fd5b87356156bb81615421565b965060208801356156cb8161568d565b955060408801356156db816152a0565b945060608801356156eb816155c9565b93506080880135925060a08801356001600160401b0381111561570c575f80fd5b6157188a828b016152ae565b989b979a50959850939692959293505050565b60e0810181855f5b600381101561575557815160ff16835260209283019290910190600101615733565b50505060608201845f5b600381101561578257815161ffff1683526020928301929091019060010161575f565b50505060ff831660c0830152611f20565b5f80604083850312156157a4575f80fd5b82359150602083013561536a8161568d565b5f805f606084860312156157c8575f80fd5b833592506020840135615605816152a0565b5f805f604084860312156157ec575f80fd5b8335925060208401356001600160401b03811115615808575f80fd5b6153318682870161548c565b8082028115828204841417610dbf57610dbf615279565b634e487b7160e01b5f52601260045260245ffd5b5f8261584d5761584d61582b565b500490565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215615876575f80fd5b815161140d81615421565b81810381811115610dbf57610dbf615279565b5f602082840312156158a4575f80fd5b5051919050565b5f8151808452602084019350602083015f5b828110156158e6576158d0868351615375565b60e09590950194602091909101906001016158bd565b5093949350505050565b606081525f61590260608301866158ab565b905083602083015263ffffffff83166040830152949350505050565b604081525f61593060408301856158ab565b90508260208301529392505050565b5f6020828403121561594f575f80fd5b813561140d816155c9565b5f60ff821660ff810361596f5761596f615279565b60010192915050565b634e487b7160e01b5f52604160045260245ffd5b5f6020828403121561599c575f80fd5b815161140d8161568d565b5f80604083850312156159b8575f80fd5b505080516020909101519092909150565b6001600160801b038181168382160190811115610dbf57610dbf615279565b61ffff8281168282160390811115610dbf57610dbf615279565b5f60208284031215615a12575f80fd5b815163ffffffff8116811461140d575f80fd5b62ffffff81168114614dea575f80fd5b803561544081615a25565b8060020b8114614dea575f80fd5b803561544081615a40565b8183526020830192505f815f5b848110156158e6578135615a79816152a0565b60ff1686526020820135615a8c81615421565b6001600160a01b031660208701526040820135615aa881615421565b6001600160a01b03166040870152615ac260608301615435565b6001600160a01b03166060870152615adc60808301615a35565b62ffffff166080870152615af260a08301615a4e565b615b0160a088018260020b9052565b50615b0e60c08301615435565b6001600160a01b031660c087015260e0958601959190910190600101615a66565b604081525f615b42604083018587615a59565b905060018060a01b0383166020830152949350505050565b602081525f611f20602083018486615a59565b5f8135610dbf81615421565b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f8135610dbf81615a25565b5f8135610dbf81615a40565b8135615bbc816152a0565b60ff811660ff19835416178255506020820135615bd881615421565b8154610100600160a81b03191660089190911b610100600160a81b0316178155615c10615c0760408401615b6d565b60018301615b79565b60028101615c29615c2360608501615b6d565b82615b79565b615c5a615c3860808501615b99565b82805462ffffff60a01b191660a09290921b62ffffff60a01b16919091179055565b615c89615c6960a08501615ba5565b825460b89190911b62ffffff60b81b1662ffffff60b81b19909116178255565b50614026615c9960c08401615b6d565b60038301615b79565b60ff8281168282160390811115610dbf57610dbf615279565b60ff8181168382160190811115610dbf57610dbf615279565b5f60ff831680615ce657615ce661582b565b8060ff84160691505092915050565b5f82518060208501845e5f920191825250919050565b6001600160401b038181168382160190811115610dbf57610dbf615279565b604051601f8201601f191681016001600160401b0381118282101715615d5e57634e487b7160e01b5f52604160045260245ffd5b604052919050565b8051615440816152a0565b5f805f60e08486031215615d83575f80fd5b84601f850112615d91575f80fd5b6060615d9c81615d2a565b8082870188811115615dac575f80fd5b875b81811015615dcf578051615dc1816152a0565b845260209384019301615dae565b508196505f925088601f820112615de4575f80fd5b839150615df082615d2a565b9381019391508189851115615e03575f80fd5b84821015615e28578151615e16816155c9565b83526020928301929190910190615e03565b9550615e3c9350505060c086019050615d66565b90509250925092565b5f60208284031215615e55575f80fd5b815161140d816152a056fe9aa1a56064c83c34d45ce0f34a60a04b6c6fd4bf28b61a19c16235ebedb30b19a26469706673582212203ea97dc94c537a8fbcf65d7dd46a27e5e1f946684c017ac2bc1221ac9e510a6464736f6c634300081a0033
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x500e55…145058 | 47 secs agoTue, 18 Aug 2026 07:43:55 UTC | 0x9289c2…d935 | [0] 0x000000000000…00000867 data: 0x000000000000000000…00000001 |
| 0xd67b3f…347f1a | 1 min agoTue, 18 Aug 2026 07:42:49 UTC | 0x9289c2…d935 | [0] 0x000000000000…0000033b data: 0x000000000000000000…00000001 |
| 0xfb2598…b3b09b | 3 mins agoTue, 18 Aug 2026 07:41:42 UTC | 0x9289c2…d935 | [0] 0x000000000000…0000016b data: 0x000000000000000000…00000001 |
| 0x9f93fe…5f9409 | 5 mins agoTue, 18 Aug 2026 07:38:50 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…0000081e data: 0x000000000000000000…00000000 |
| 0x9f93fe…5f9409 | 5 mins agoTue, 18 Aug 2026 07:38:50 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…00000740 data: 0x000000000000000000…00079310 |
| 0x9f93fe…5f9409 | 5 mins agoTue, 18 Aug 2026 07:38:50 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…000006c3 data: 0x000000000000000000…00000000 |
| 0x3f9101…61b416 | 10 mins agoTue, 18 Aug 2026 07:33:49 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…00000740 data: 0x000000000000000000…00000000 |
| 0x3f9101…61b416 | 10 mins agoTue, 18 Aug 2026 07:33:49 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…000005ab data: 0x000000000000000000…00000000 |
| 0x05f339…f4a317 | 16 mins agoTue, 18 Aug 2026 07:28:10 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…0000075e data: 0x000000000000000000…00079310 |
| 0x8e1a96…557a2e | 34 mins agoTue, 18 Aug 2026 07:10:09 UTC | 0x9289c2…d935 | [0] 0x000000000000…0000075e data: 0x000000000000000000…00000001 |
| 0xb99e21…f8b602 | 41 mins agoTue, 18 Aug 2026 07:03:04 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…00000846 data: 0x000000000000000000…0007930f |
| 0xb99e21…f8b602 | 41 mins agoTue, 18 Aug 2026 07:03:04 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…0000079e data: 0x000000000000000000…0007930f |
| 0xb99e21…f8b602 | 41 mins agoTue, 18 Aug 2026 07:03:04 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…00000506 data: 0x000000000000000000…0007930f |
| 0xb99e21…f8b602 | 41 mins agoTue, 18 Aug 2026 07:03:04 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…00000329 data: 0x000000000000000000…0007930f |
| 0xb99e21…f8b602 | 41 mins agoTue, 18 Aug 2026 07:03:04 UTC | 0x9aa1a5…0b19 | [0] 0x000000000000…00000283 data: 0x000000000000000000…0007930f |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000bb8 [1] 0x000000000000…0000000b data: 0x000000000000000000…000339d8 |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000bb6 [1] 0x000000000000…0000000c data: 0x000000000000000000…afa1b949 |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000bb6 [1] 0x000000000000…0000000d data: 0x000000000000000000…7cc0e6ff |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000bb2 [1] 0x000000000000…0000000c data: 0x000000000000000000…9ee912ac |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000bae [1] 0x000000000000…0000000d data: 0x000000000000000000…c7c0023d |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000ba8 [1] 0x000000000000…0000000b data: 0x000000000000000000…0001b2a7 |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000ba7 [1] 0x000000000000…0000000d data: 0x000000000000000000…20de9154 |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000ba7 [1] 0x000000000000…0000000c data: 0x000000000000000000…3086d5b9 |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000ba7 [1] 0x000000000000…0000000b data: 0x000000000000000000…000090e9 |
| 0x8d646e…aae01e | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8110a2…b9ce | [0] 0x000000000000…00000ba4 [1] 0x000000000000…00000006 data: 0x000000000000000000…3119f3ab |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x500e55…145058 | setSplit | 39,528,114 | 47 secs agoTue, 18 Aug 2026 07:43:55 UTC | 0x5011…e456 | IN | StackRoundsV3 | $0.000 ETH | 0.00000091 | |
| 0xd67b3f…347f1a | setSplit | 39,527,463 | 1 min agoTue, 18 Aug 2026 07:42:49 UTC | 0x5011…e456 | IN | StackRoundsV3 | $0.000 ETH | 0.00000091 | |
| 0xfb2598…b3b09b | setSplit | 39,526,795 | 3 mins agoTue, 18 Aug 2026 07:41:42 UTC | 0x5011…e456 | IN | StackRoundsV3 | $0.000 ETH | 0.00000091 | |
| 0x18ab88…c96161 | Transfer | 39,525,273 | 5 mins agoTue, 18 Aug 2026 07:39:09 UTC | 0xf84f…448b | IN | StackRoundsV3 | $1.880.00098 ETH | 0.00000061 | |
| 0x9f93fe…5f9409 | sync | 39,525,086 | 5 mins agoTue, 18 Aug 2026 07:38:50 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00000266 | |
| 0x3f9101…61b416 | sync | 39,522,084 | 10 mins agoTue, 18 Aug 2026 07:33:49 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00000120 | |
| 0x48485f…d80794 | Transfer | 39,519,983 | 14 mins agoTue, 18 Aug 2026 07:30:19 UTC | 0xf84f…448b | IN | StackRoundsV3 | $34.560.01819 ETH | 0.00000095 | |
| 0x05f339…f4a317 | sync | 39,518,702 | 16 mins agoTue, 18 Aug 2026 07:28:10 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00000220 | |
| 0x8e1a96…557a2e | setSplit | 39,507,932 | 34 mins agoTue, 18 Aug 2026 07:10:09 UTC | 0xa8b4…66c3 | IN | StackRoundsV3 | $0.000 ETH | 0.00000090 | |
| 0xb99e21…f8b602 | sync | 39,503,696 | 41 mins agoTue, 18 Aug 2026 07:03:04 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00000488 | |
| 0x8d646e…aae01e | deliver | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00008992 | |
| 0x14ba44…a00e3a | deliver | 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00016837 | |
| 0x92904c…0a01d2 | deliver | 39,503,079 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00015615 | |
| 0xfc7253…68a5fe | deliver | 39,503,074 | 42 mins agoTue, 18 Aug 2026 07:02:01 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00016567 | |
| 0xf5bc71…3d8450 | deliver | 39,503,070 | 42 mins agoTue, 18 Aug 2026 07:02:01 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00014511 | |
| 0x1d2552…ecf293 | deliver | 39,503,065 | 42 mins agoTue, 18 Aug 2026 07:02:00 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00015294 | |
| 0xaca197…061709 | deliver | 39,503,059 | 42 mins agoTue, 18 Aug 2026 07:02:00 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00017133 | |
| 0xb5da7c…053788 | deliver | 39,503,054 | 42 mins agoTue, 18 Aug 2026 07:01:59 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00013294 | |
| 0x3b58ba…35169f | deliver | 39,503,048 | 42 mins agoTue, 18 Aug 2026 07:01:59 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00013763 | |
| 0x88e750…8b90ae | deliver | 39,503,042 | 42 mins agoTue, 18 Aug 2026 07:01:58 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00015972 | |
| 0xe1de64…dbca9a | deliver | 39,503,036 | 42 mins agoTue, 18 Aug 2026 07:01:57 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00015053 | |
| 0x687c9e…fd6252 | deliver | 39,503,031 | 42 mins agoTue, 18 Aug 2026 07:01:57 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00016751 | |
| 0x5fb040…70632c | deliver | 39,503,025 | 42 mins agoTue, 18 Aug 2026 07:01:56 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00014855 | |
| 0x902160…c59a05 | deliver | 39,503,019 | 42 mins agoTue, 18 Aug 2026 07:01:56 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00017436 | |
| 0xa42604…642d68 | deliver | 39,503,013 | 42 mins agoTue, 18 Aug 2026 07:01:55 UTC | 0x3952…9bc9 | IN | StackRoundsV3 | $0.000 ETH | 0.00018577 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00065 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00034 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00086 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00020 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00003 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00016 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00019 ETH |
| 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0x8d646e…aae01e | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00005 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00005 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00036 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00078 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00261 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00024 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00003 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00006 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00009 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00016 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| 39,503,085 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x14ba44…a00e3a | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00011 ETH |
| 39,503,079 | 42 mins agoTue, 18 Aug 2026 07:02:02 UTC | 0x92904c…0a01d2 | CALL | deliver | 0xca32…364a | OUT | 0x407b…70c8 | 0.00002 ETH |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x35440d2b…4c4510 | Transfer | 39,520,594 | 13 mins agoTue, 18 Aug 2026 07:31:20 UTC | 0x1673…13db | IN | 0xca32…364a | 15 HMM | Thinking Cat (HMM) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.210.211416 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.217.389236 PONS | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.57645.350107 STACK | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0x4737…979b | $0.155.305093 PONS | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.0782.737193 STACK | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xee75…82ba | $0.110.111271 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.0227.576306 STACK | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.041.262991 PONS | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.040.037097 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.070.000214 TSLA | Tesla • Robinhood Token (TSLA) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | 0.000499 SPCX | Space Exploration Technologies Corp. Class A Common Stock • Robinhood Token (SPCX) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.060.055635 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.051.894676 PONS | ||
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.360.361632 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0x81cc…61a6 | $0.110.111271 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | 0.000149 AMZN | Amazon • Robinhood Token (AMZN) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.040.000174 NVDA | NVIDIA • Robinhood Token (NVDA) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.030.000109 AAPL | Apple • Robinhood Token (AAPL) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.110.111271 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | 0.000149 AMZN | Amazon • Robinhood Token (AMZN) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.040.000174 NVDA | NVIDIA • Robinhood Token (NVDA) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.030.000109 AAPL | Apple • Robinhood Token (AAPL) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | $0.110.111271 USDG | Global Dollar (USDG) | |
| 0x8d646e26…aae01e | Transfer | 39,503,089 | 42 mins agoTue, 18 Aug 2026 07:02:03 UTC | 0xca32…364a | OUT | 0xba5d…aa48 | 0.001679 SPCX | Space Exploration Technologies Corp. Class A Common Stock • Robinhood Token (SPCX) |