// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {INonfungiblePositionManager} from "./interfaces/INonfungiblePositionManager.sol";
import {IWETH9} from "./interfaces/IWETH9.sol";
import {IAllowanceTransfer} from "./interfaces/IAllowanceTransfer.sol";
import {ISwapRouter02} from "./interfaces/ISwapRouter02.sol";
import {Actions, Currency, PoolKey} from "./interfaces/v4/V4Types.sol";
import {IPositionManager} from "./interfaces/v4/IPositionManager.sol";
/// @title FeeRouter — non-custodial deposit router for Uniswap v3/v4 LP mints on Robinhood Chain.
/// @notice Pulls deposit tokens, skims a small fee (bps) to the treasury, forwards the rest to
/// Uniswap, and mints the position NFT DIRECTLY to the user. Never holds funds between txs.
/// Exits never touch this contract.
contract FeeRouter is Ownable2Step, ReentrancyGuard {
using SafeERC20 for IERC20;
uint16 public constant MAX_FEE_BPS = 50; // hard cap: 0.5%
address public immutable npm; // Uniswap v3 NonfungiblePositionManager
address public immutable v4PositionManager;
address public immutable permit2;
address public immutable weth;
address public immutable swapRouter02;
address public treasury;
uint16 public defaultFeeBps;
mapping(address => uint16) public feeBpsOverride;
mapping(address => bool) public hasFeeOverride;
/// @notice Holder perk: any account holding >= exemptMinHold[token] of ANY listed exempt
/// token pays 0 fee. The list is owner-editable and hard-capped so the fee check's
/// gas stays small and predictable on every deposit.
/// @dev KNOWN & ACCEPTED: the check is a call-time snapshot of balanceOf(msg.sender), so the
/// perk can be obtained by a just-in-time / flash-loaned balance, or proxied to others
/// via a wrapper contract that holds the minimum. This is an intentional simplicity
/// tradeoff — the only thing at stake is deposit-fee revenue (never user funds), and the
/// exempt tokens are partner/protocol tokens. To harden, gate the perk to direct EOAs
/// (msg.sender == tx.origin) or require a time-locked stake. Owner can also disable the
/// perk at any time and grant precise per-user waivers via setFeeOverride.
address[] public exemptTokens;
mapping(address => uint256) public exemptMinHold;
uint256 public constant MAX_EXEMPT_TOKENS = 8;
event FeeCharged(address indexed user, address indexed token, uint256 amount);
event RouterMint(address indexed user, uint8 protocol, uint256 indexed tokenId); // protocol: 3 or 4
event RouterSwap(
address indexed user, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut
);
event DefaultFeeBpsSet(uint16 bps);
event FeeOverrideSet(address indexed user, uint16 bps);
event FeeOverrideCleared(address indexed user);
event TreasurySet(address treasury);
event ExemptTokenSet(address indexed token, uint256 minHold);
error FeeTooHigh();
error ZeroAddress();
error ZapBadInput();
error ExemptListFull();
constructor(
address npm_,
address v4PositionManager_,
address permit2_,
address weth9_,
address swapRouter02_,
address treasury_,
uint16 defaultFeeBps_,
address owner_
) Ownable(owner_) {
if (
npm_ == address(0) || v4PositionManager_ == address(0) || permit2_ == address(0)
|| weth9_ == address(0) || swapRouter02_ == address(0) || treasury_ == address(0)
) revert ZeroAddress();
if (defaultFeeBps_ > MAX_FEE_BPS) revert FeeTooHigh();
npm = npm_;
v4PositionManager = v4PositionManager_;
permit2 = permit2_;
weth = weth9_;
swapRouter02 = swapRouter02_;
treasury = treasury_;
defaultFeeBps = defaultFeeBps_;
}
/// @notice Effective fee for a user. Explicit beats implicit: a per-user override (0 is a
/// valid free tier) wins over everything; otherwise holding the minimum of ANY
/// listed exempt token waives the fee entirely; otherwise the default applies.
function feeBpsFor(address user) public view returns (uint16) {
if (hasFeeOverride[user]) return feeBpsOverride[user];
if (_holdsExemptToken(user)) return 0;
return defaultFeeBps;
}
/// @notice Number of tokens currently in the holder-perk list.
function exemptTokensCount() external view returns (uint256) {
return exemptTokens.length;
}
/// @dev True when `user` meets the minimum on any listed exempt token. Uses raw staticcalls
/// so a broken, reverting, or codeless token can NEVER brick the deposit path — any
/// failure just means that token doesn't grant the perk.
function _holdsExemptToken(address user) internal view returns (bool) {
uint256 n = exemptTokens.length;
for (uint256 i = 0; i < n; i++) {
address t = exemptTokens[i];
(bool ok, bytes memory data) =
t.staticcall(abi.encodeWithSelector(IERC20.balanceOf.selector, user));
if (ok && data.length >= 32 && abi.decode(data, (uint256)) >= exemptMinHold[t]) {
return true;
}
}
return false;
}
struct V3MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
/// @notice Pull tokens, skim fee to treasury, mint a v3 position NFT directly to p.recipient,
/// refund unspent dust to msg.sender.
function mintV3(V3MintParams calldata p)
external
payable
nonReentrant
returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)
{
_wrapIfNative(p.token0, p.token1);
uint16 bps = feeBpsFor(msg.sender);
uint256 net0 = _acquire(p.token0, p.amount0Desired, bps);
uint256 net1 = _acquire(p.token1, p.amount1Desired, bps);
(tokenId, liquidity, amount0, amount1) = _mintNPM(p, net0, net1);
emit RouterMint(msg.sender, 3, tokenId);
_refund(p.token0);
_refund(p.token1);
}
struct ZapV3Params {
address token0; // sorted pool token0
address token1; // sorted pool token1
uint24 fee;
int24 tickLower;
int24 tickUpper;
address inputToken; // MUST be token0 or token1 (or WETH when ETH sent)
uint256 inputAmount; // total input the user provides (msg.value when native ETH)
uint256 swapAmountIn; // how much of inputToken to swap into the OTHER token (frontend-computed)
uint256 swapAmountOutMin; // min output of the swap (slippage on the swap leg)
uint8 swapVenue; // 0 = Uniswap v3 (swapFee tier), 1 = Uniswap v2 — best price picked off-chain
uint24 swapFee; // v3 fee tier for the swap leg (may differ from the pool's `fee`); 0 = use `fee`
uint256 amount0Min; // slippage floor on the mint leg
uint256 amount1Min;
address recipient;
uint256 deadline;
}
uint8 internal constant VENUE_V3 = 0;
uint8 internal constant VENUE_V2 = 1;
/// @notice LP into a v3 pool with a single input token: skim the fee, swap the
/// frontend-computed optimal portion into the pool's other token, then mint —
/// atomically, in one tx, with on-chain slippage protection on BOTH the swap leg
/// (swapAmountOutMin) and the mint leg (amount0Min/amount1Min). All leftover
/// token0/token1/ETH dust is refunded to msg.sender; the position NFT mints
/// directly to p.recipient. Reverts ZapBadInput if inputToken isn't token0 or
/// token1, or if ETH is sent but inputToken isn't WETH.
function zapMintV3(ZapV3Params calldata p)
external
payable
nonReentrant
returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)
{
if (p.inputToken != p.token0 && p.inputToken != p.token1) revert ZapBadInput();
if (msg.value > 0 && p.inputToken != weth) revert ZapBadInput();
_wrapIfNative(p.token0, p.token1);
uint16 bps = feeBpsFor(msg.sender);
uint256 net = _acquire(p.inputToken, p.inputAmount, bps);
if (p.swapAmountIn > net) revert ZapBadInput(); // can't swap more than the net (post-fee) input
uint256 amountOut = _zapSwap(p);
(tokenId, liquidity, amount0, amount1) = _zapMintNPM(p, net, amountOut);
emit RouterMint(msg.sender, 3, tokenId);
_refund(p.token0);
_refund(p.token1);
}
/// @dev Swap swapAmountIn of p.inputToken into the pool's other token via SwapRouter02,
/// landing the output directly in this router (fed straight into the mint below).
/// Same fee tier as the pool — simplest, and documented in the zap spec. Returns the
/// EXACT amount received so the mint below is bounded to it, never to balanceOf (a
/// raw-balance mint would happily sweep pre-funded/over-sent dust into the position
/// fee-free — see the zap fee-bypass fix).
function _zapSwap(ZapV3Params calldata p) internal returns (uint256 amountOut) {
if (p.swapAmountIn == 0) return 0;
address outputToken = p.inputToken == p.token0 ? p.token1 : p.token0;
// Route the swap through whichever venue the frontend priced best. Both v2 and v3 go
// through the same SwapRouter02 (verified: it pulls via plain allowance for both), and
// the v3 tier is decoupled from the pool's own `fee` so a deeper pool for the same pair
// can be used for the swap. Output lands here, fed straight into the mint (bounded to the
// EXACT amountOut, never balanceOf — see the zap fee-bypass fix).
amountOut = _routeSwap(
p.inputToken, outputToken, p.swapAmountIn, p.swapAmountOutMin, p.swapVenue, p.swapFee == 0 ? p.fee : p.swapFee, address(this)
);
}
/// @dev Execute a single-hop swap of `amountIn` inputToken -> outputToken through SwapRouter02,
/// via v2 or v3 per `venue`, delivering the output to `to`. Approves exactly amountIn.
function _routeSwap(
address inputToken,
address outputToken,
uint256 amountIn,
uint256 amountOutMin,
uint8 venue,
uint24 v3Fee,
address to
) internal returns (uint256 amountOut) {
IERC20(inputToken).forceApprove(swapRouter02, amountIn);
if (venue == VENUE_V2) {
address[] memory path = new address[](2);
path[0] = inputToken;
path[1] = outputToken;
amountOut = ISwapRouter02(swapRouter02).swapExactTokensForTokens(amountIn, amountOutMin, path, to);
} else {
amountOut = ISwapRouter02(swapRouter02).exactInputSingle(
ISwapRouter02.ExactInputSingleParams({
tokenIn: inputToken,
tokenOut: outputToken,
fee: v3Fee,
recipient: to,
amountIn: amountIn,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: 0
})
);
}
}
/// @dev Mint against the EXACT tracked post-swap amounts — the kept (unswapped) portion of
/// the net input, and the swap's actual output — never against balanceOf. Bounding the
/// mint (and its NPM approval) to these tracked amounts means any router balance beyond
/// them (over-sent ETH, pre-funded dust, an under-declared inputAmount) simply cannot be
/// pulled into the mint; it flows back to msg.sender via the _refund calls after this.
function _zapMintNPM(ZapV3Params calldata p, uint256 net, uint256 amountOut)
internal
returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)
{
uint256 kept = net - p.swapAmountIn; // unswapped remainder of the input token
uint256 amount0Desired;
uint256 amount1Desired;
if (p.inputToken == p.token0) {
amount0Desired = kept;
amount1Desired = amountOut;
} else {
amount1Desired = kept;
amount0Desired = amountOut;
}
if (amount0Desired > 0) IERC20(p.token0).forceApprove(npm, amount0Desired);
if (amount1Desired > 0) IERC20(p.token1).forceApprove(npm, amount1Desired);
return INonfungiblePositionManager(npm).mint(
INonfungiblePositionManager.MintParams({
token0: p.token0,
token1: p.token1,
fee: p.fee,
tickLower: p.tickLower,
tickUpper: p.tickUpper,
amount0Desired: amount0Desired,
amount1Desired: amount1Desired,
amount0Min: p.amount0Min,
amount1Min: p.amount1Min,
recipient: p.recipient,
deadline: p.deadline
})
);
}
struct SwapParams {
address tokenIn; // token sold (WETH when native ETH is sent)
address tokenOut; // token bought
uint256 amountIn; // total input (msg.value when native ETH in)
uint256 amountOutMin; // slippage floor on the output
uint8 venue; // 0 = Uniswap v3 (v3Fee tier), 1 = Uniswap v2 — best price picked off-chain
uint24 v3Fee; // v3 fee tier when venue == 0
address recipient; // receives tokenOut (or native ETH when unwrapEth)
uint256 deadline;
bool unwrapEth; // when tokenOut == WETH, deliver native ETH to recipient instead of WETH
}
/// @notice Best-price token swap: skim the platform fee on the input, route the rest through
/// SwapRouter02 via the v2/v3 venue the frontend priced best, and deliver the output
/// straight to `recipient`. Supports native ETH in (send msg.value with tokenIn == WETH)
/// and native ETH out (unwrapEth with tokenOut == WETH). Reentrancy-guarded; refunds any
/// input dust. This contract never custodies funds between txs.
function swap(SwapParams calldata p) external payable nonReentrant returns (uint256 amountOut) {
if (p.tokenIn == p.tokenOut) revert ZapBadInput();
require(block.timestamp <= p.deadline, "FeeRouter: expired");
// Acquire the input (native ETH -> WETH), then skim the fee on the gross input.
if (msg.value > 0) {
if (p.tokenIn != weth) revert ZapBadInput();
require(msg.value == p.amountIn, "FeeRouter: value mismatch");
IWETH9(weth).deposit{value: msg.value}();
} else {
IERC20(p.tokenIn).safeTransferFrom(msg.sender, address(this), p.amountIn);
}
uint16 bps = feeBpsFor(msg.sender);
uint256 fee = (p.amountIn * bps) / 10_000;
if (fee > 0) {
IERC20(p.tokenIn).safeTransfer(treasury, fee);
emit FeeCharged(msg.sender, p.tokenIn, fee);
}
uint256 net = p.amountIn - fee;
// Native ETH out: swap to this contract, unwrap, forward ETH. Otherwise straight to user.
bool unwrap = p.unwrapEth && p.tokenOut == weth;
address to = unwrap ? address(this) : p.recipient;
amountOut = _routeSwap(p.tokenIn, p.tokenOut, net, p.amountOutMin, p.venue, p.v3Fee, to);
if (unwrap) {
IWETH9(weth).withdraw(amountOut);
(bool ok,) = p.recipient.call{value: amountOut}("");
require(ok, "FeeRouter: ETH out failed");
}
emit RouterSwap(msg.sender, p.tokenIn, p.tokenOut, p.amountIn, amountOut);
_refund(p.tokenIn); // exact-input swaps consume it all, but refund any dust to be safe
}
/// @notice Mint several v3 positions (a liquidity ladder) in one tx. Fee is skimmed per item;
/// each NFT goes straight to its item's recipient; all dust refunds happen once at the end.
/// With msg.value > 0, the full value is wrapped once and shared across the WETH sides.
function mintV3Batch(V3MintParams[] calldata ps)
external
payable
nonReentrant
returns (uint256[] memory tokenIds)
{
require(ps.length > 0, "FeeRouter: empty batch");
if (msg.value > 0) {
bool hasWethSide;
for (uint256 i = 0; i < ps.length; i++) {
if (ps[i].token0 == weth || ps[i].token1 == weth) {
hasWethSide = true;
break;
}
}
require(hasWethSide, "FeeRouter: ETH sent but no WETH side");
IWETH9(weth).deposit{value: msg.value}();
}
uint16 bps = feeBpsFor(msg.sender);
tokenIds = new uint256[](ps.length);
for (uint256 i = 0; i < ps.length; i++) {
uint256 net0 = _acquire(ps[i].token0, ps[i].amount0Desired, bps);
uint256 net1 = _acquire(ps[i].token1, ps[i].amount1Desired, bps);
(uint256 tokenId,,,) = _mintNPM(ps[i], net0, net1);
tokenIds[i] = tokenId;
emit RouterMint(msg.sender, 3, tokenId);
}
// refund once per token at the end (idempotent — second refund of same token sees 0)
for (uint256 i = 0; i < ps.length; i++) {
_refund(ps[i].token0);
_refund(ps[i].token1);
}
}
/// @notice Mint a v4 position via PositionManager.modifyLiquidities. Fee is skimmed on
/// amount0Max/amount1Max (the amounts pulled); the NET amounts become the mint's
/// slippage maxes. currency0 == address(0) means native ETH (fee paid in ETH,
/// excess swept back to the caller). The NFT mints directly to `recipient`.
function mintV4(
PoolKey calldata key,
int24 tickLower,
int24 tickUpper,
uint256 liquidity,
uint128 amount0Max,
uint128 amount1Max,
address recipient,
bytes calldata hookData,
uint256 deadline
) external payable nonReentrant returns (uint256 tokenId) {
uint16 bps = feeBpsFor(msg.sender);
uint256 net0 = _acquireV4(key.currency0, amount0Max, bps);
uint256 net1 = _acquireV4(key.currency1, amount1Max, bps);
_permit2Approve(key.currency0, net0, deadline);
_permit2Approve(key.currency1, net1, deadline);
// Deviation from brief: the brief's Step 3 code inlines the modifyLiquidities encoding
// directly in mintV4, which hits solc "Stack too deep" (9 external params + several
// locals live at once, same class of issue Task 5 hit with _increaseNPM). Fixed the same
// way: pack the mint-shape inputs into a memory struct and delegate the encode+call to an
// internal helper so mintV4 itself only carries bps/net0/net1/tokenId live at once.
V4MintParams memory p;
p.key = key;
p.tickLower = tickLower;
p.tickUpper = tickUpper;
p.liquidity = liquidity;
p.recipient = recipient;
p.hookData = hookData;
p.deadline = deadline;
tokenId = _mintV4NPM(p, net0, net1);
emit RouterMint(msg.sender, 4, tokenId);
_refundV4(key.currency0);
_refundV4(key.currency1);
}
struct V4MintParams {
PoolKey key;
int24 tickLower;
int24 tickUpper;
uint256 liquidity;
address recipient;
bytes hookData;
uint256 deadline;
}
/// @dev Encode the MINT_POSITION(+SWEEP)/SETTLE_PAIR action list and call modifyLiquidities.
function _mintV4NPM(V4MintParams memory p, uint256 net0, uint256 net1)
internal
returns (uint256 tokenId)
{
bool native = Currency.unwrap(p.key.currency0) == address(0);
tokenId = IPositionManager(v4PositionManager).nextTokenId(); // sequential mint ids
bytes memory actions;
bytes[] memory params;
if (native) {
actions =
abi.encodePacked(Actions.MINT_POSITION, Actions.SETTLE_PAIR, Actions.SWEEP);
params = new bytes[](3);
// sweep unused ETH sitting in the PositionManager straight back to the user
params[2] = abi.encode(p.key.currency0, msg.sender);
} else {
actions = abi.encodePacked(Actions.MINT_POSITION, Actions.SETTLE_PAIR);
params = new bytes[](2);
}
params[0] = abi.encode(
p.key,
p.tickLower,
p.tickUpper,
p.liquidity,
uint128(net0),
uint128(net1),
p.recipient,
p.hookData
);
params[1] = abi.encode(p.key.currency0, p.key.currency1);
IPositionManager(v4PositionManager).modifyLiquidities{value: native ? net0 : 0}(
abi.encode(actions, params), p.deadline
);
// belt-and-braces vs hostile hook behavior: the NFT must have landed with the recipient
require(
IPositionManager(v4PositionManager).ownerOf(tokenId) == p.recipient,
"FeeRouter: v4 mint mismatch"
);
}
/// @dev Pull `amount` of a v4 currency (native ETH via msg.value, else transferFrom),
/// skim the fee cut to treasury, return the net.
function _acquireV4(Currency c, uint256 amount, uint16 bps) internal returns (uint256 net) {
if (amount == 0) return 0;
address t = Currency.unwrap(c);
uint256 fee = (amount * bps) / 10_000;
if (t == address(0)) {
require(msg.value >= amount, "FeeRouter: insufficient ETH");
if (fee > 0) {
(bool ok,) = treasury.call{value: fee}("");
require(ok, "FeeRouter: fee transfer failed");
emit FeeCharged(msg.sender, address(0), fee);
}
} else {
IERC20(t).safeTransferFrom(msg.sender, address(this), amount);
if (fee > 0) {
IERC20(t).safeTransfer(treasury, fee);
emit FeeCharged(msg.sender, t, fee);
}
}
return amount - fee;
}
/// @dev SETTLE_PAIR pulls ERC20s from this router through Permit2:
/// token -> approve Permit2, then Permit2 allowance for the v4 PositionManager.
function _permit2Approve(Currency c, uint256 net, uint256 deadline) internal {
address t = Currency.unwrap(c);
if (t == address(0) || net == 0) return;
IERC20(t).forceApprove(permit2, net);
uint48 expiration =
deadline >= type(uint48).max ? type(uint48).max : uint48(deadline);
IAllowanceTransfer(permit2).approve(t, v4PositionManager, uint160(net), expiration);
}
/// @dev Return any leftover currency to msg.sender (settle used less than the net max).
function _refundV4(Currency c) internal {
address t = Currency.unwrap(c);
if (t == address(0)) {
uint256 ethBal = address(this).balance;
if (ethBal > 0) {
(bool ok,) = msg.sender.call{value: ethBal}("");
require(ok, "FeeRouter: ETH refund failed");
}
} else {
uint256 bal = IERC20(t).balanceOf(address(this));
if (bal > 0) IERC20(t).safeTransfer(msg.sender, bal);
}
}
/// @notice Add liquidity to an existing v3 position. Fee is skimmed on the increase amounts.
/// NPM's increaseLiquidity has no owner check, so anyone can top up any tokenId —
/// the added liquidity always accrues to the NFT's current owner.
function increaseV3(
uint256 tokenId,
uint256 amount0Desired,
uint256 amount1Desired,
uint256 amount0Min,
uint256 amount1Min,
uint256 deadline
) external payable nonReentrant returns (uint128 liquidity, uint256 amount0, uint256 amount1) {
(,, address token0_, address token1_,,,,,,,,) =
INonfungiblePositionManager(npm).positions(tokenId);
_wrapIfNative(token0_, token1_);
uint16 bps = feeBpsFor(msg.sender);
uint256 net0 = _acquire(token0_, amount0Desired, bps);
uint256 net1 = _acquire(token1_, amount1Desired, bps);
IncreaseParams memory ip;
ip.tokenId = tokenId;
ip.token0 = token0_;
ip.token1 = token1_;
ip.net0 = net0;
ip.net1 = net1;
ip.amount0Min = amount0Min;
ip.amount1Min = amount1Min;
ip.deadline = deadline;
(liquidity, amount0, amount1) = _increaseNPM(ip);
_refund(token0_);
_refund(token1_);
}
struct IncreaseParams {
uint256 tokenId;
address token0;
address token1;
uint256 net0;
uint256 net1;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
/// @dev Approve net amounts to the NPM and increase the existing position's liquidity.
function _increaseNPM(IncreaseParams memory p)
internal
returns (uint128 liquidity, uint256 amount0, uint256 amount1)
{
if (p.net0 > 0) IERC20(p.token0).forceApprove(npm, p.net0);
if (p.net1 > 0) IERC20(p.token1).forceApprove(npm, p.net1);
return INonfungiblePositionManager(npm).increaseLiquidity(
INonfungiblePositionManager.IncreaseLiquidityParams({
tokenId: p.tokenId,
amount0Desired: p.net0,
amount1Desired: p.net1,
amount0Min: p.amount0Min,
amount1Min: p.amount1Min,
deadline: p.deadline
})
);
}
/// @dev If the caller sent ETH, one side must be WETH; wrap the full msg.value up front.
function _wrapIfNative(address token0_, address token1_) internal {
if (msg.value == 0) return;
require(token0_ == weth || token1_ == weth, "FeeRouter: ETH sent but no WETH side");
IWETH9(weth).deposit{value: msg.value}();
}
/// @dev Fund `amount` of `token`: from the pre-wrapped msg.value when it is the WETH side of a
/// native deposit, otherwise via transferFrom. Skim the fee cut to treasury; return the net.
function _acquire(address token, uint256 amount, uint16 bps) internal returns (uint256 net) {
if (amount == 0) return 0;
if (msg.value > 0 && token == weth) {
// already wrapped by _wrapIfNative; make sure enough ETH was actually sent
require(
IERC20(weth).balanceOf(address(this)) >= amount, "FeeRouter: insufficient ETH"
);
} else {
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
}
uint256 fee = (amount * bps) / 10_000;
if (fee > 0) {
IERC20(token).safeTransfer(treasury, fee);
emit FeeCharged(msg.sender, token, fee);
}
return amount - fee;
}
/// @dev Approve net amounts to the NPM and mint; the NFT goes straight to p.recipient.
function _mintNPM(V3MintParams calldata p, uint256 net0, uint256 net1)
internal
returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)
{
if (net0 > 0) IERC20(p.token0).forceApprove(npm, net0);
if (net1 > 0) IERC20(p.token1).forceApprove(npm, net1);
return INonfungiblePositionManager(npm).mint(
INonfungiblePositionManager.MintParams({
token0: p.token0,
token1: p.token1,
fee: p.fee,
tickLower: p.tickLower,
tickUpper: p.tickUpper,
amount0Desired: net0,
amount1Desired: net1,
amount0Min: p.amount0Min,
amount1Min: p.amount1Min,
recipient: p.recipient,
deadline: p.deadline
})
);
}
/// @dev Return leftovers to msg.sender. WETH dust from a native deposit goes back as ETH.
function _refund(address token) internal {
uint256 bal = IERC20(token).balanceOf(address(this));
if (bal == 0) return;
if (msg.value > 0 && token == weth) {
IWETH9(weth).withdraw(bal); // triggers receive(); guarded to msg.sender == weth
(bool ok,) = msg.sender.call{value: bal}("");
require(ok, "FeeRouter: ETH refund failed");
} else {
IERC20(token).safeTransfer(msg.sender, bal);
}
}
function setDefaultFeeBps(uint16 bps) external onlyOwner {
if (bps > MAX_FEE_BPS) revert FeeTooHigh();
defaultFeeBps = bps;
emit DefaultFeeBpsSet(bps);
}
function setFeeOverride(address user, uint16 bps) external onlyOwner {
if (bps > MAX_FEE_BPS) revert FeeTooHigh();
feeBpsOverride[user] = bps;
hasFeeOverride[user] = true;
emit FeeOverrideSet(user, bps);
}
function clearFeeOverride(address user) external onlyOwner {
delete feeBpsOverride[user];
delete hasFeeOverride[user];
emit FeeOverrideCleared(user);
}
/// @notice Add or update (minHold > 0) or remove (minHold == 0) a holder-perk token: hold
/// >= minHold of any listed token and pay 0 fee. minHold 0 as "remove" also means a
/// live token can never be listed with a 0 minimum (which would exempt everyone).
/// The list is capped at MAX_EXEMPT_TOKENS to keep feeBpsFor gas bounded.
function setExemptToken(address token, uint256 minHold) external onlyOwner {
if (token == address(0)) revert ZeroAddress();
if (minHold == 0) {
// remove: swap-pop from the list; no-op if the token was never listed
uint256 n = exemptTokens.length;
for (uint256 i = 0; i < n; i++) {
if (exemptTokens[i] == token) {
exemptTokens[i] = exemptTokens[n - 1];
exemptTokens.pop();
break;
}
}
delete exemptMinHold[token];
} else {
if (exemptMinHold[token] == 0) {
if (exemptTokens.length >= MAX_EXEMPT_TOKENS) revert ExemptListFull();
exemptTokens.push(token);
}
exemptMinHold[token] = minHold;
}
emit ExemptTokenSet(token, minHold);
}
function setTreasury(address treasury_) external onlyOwner {
if (treasury_ == address(0)) revert ZeroAddress();
treasury = treasury_;
emit TreasurySet(treasury_);
}
/// @notice Rescue tokens/ETH accidentally sent here. The router never holds funds by design.
function sweep(address token, address to, uint256 amount) external onlyOwner {
if (to == address(0)) revert ZeroAddress();
if (token == address(0)) {
(bool ok,) = to.call{value: amount}("");
require(ok, "FeeRouter: sweep failed");
} else {
IERC20(token).safeTransfer(to, amount);
}
}
/// @dev Only WETH may push ETH here (unwrap during dust refunds).
receive() external payable {
require(msg.sender == weth, "FeeRouter: no direct ETH");
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "npm_",
"type": "address",
"internalType": "address"
},
{
"name": "v4PositionManager_",
"type": "address",
"internalType": "address"
},
{
"name": "permit2_",
"type": "address",
"internalType": "address"
},
{
"name": "weth9_",
"type": "address",
"internalType": "address"
},
{
"name": "swapRouter02_",
"type": "address",
"internalType": "address"
},
{
"name": "treasury_",
"type": "address",
"internalType": "address"
},
{
"name": "defaultFeeBps_",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "owner_",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AddressEmptyCode",
"type": "error",
"inputs": [
{
"name": "target",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "AddressInsufficientBalance",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ExemptListFull",
"type": "error",
"inputs": []
},
{
"name": "FailedInnerCall",
"type": "error",
"inputs": []
},
{
"name": "FeeTooHigh",
"type": "error",
"inputs": []
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "SafeERC20FailedOperation",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ZapBadInput",
"type": "error",
"inputs": []
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "DefaultFeeBpsSet",
"type": "event",
"inputs": [
{
"name": "bps",
"type": "uint16",
"indexed": false,
"internalType": "uint16"
}
],
"anonymous": false
},
{
"name": "ExemptTokenSet",
"type": "event",
"inputs": [
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "minHold",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FeeCharged",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FeeOverrideCleared",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "FeeOverrideSet",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "bps",
"type": "uint16",
"indexed": false,
"internalType": "uint16"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferStarted",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RouterMint",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "protocol",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "RouterSwap",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokenIn",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amountIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "amountOut",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "TreasurySet",
"type": "event",
"inputs": [
{
"name": "treasury",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "MAX_EXEMPT_TOKENS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_FEE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "clearFeeOverride",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "defaultFeeBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "exemptMinHold",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "exemptTokens",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "exemptTokensCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "feeBpsFor",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "feeBpsOverride",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "hasFeeOverride",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "increaseV3",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount0Desired",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Desired",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount0Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "liquidity",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "amount0",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "mintV3",
"type": "function",
"inputs": [
{
"name": "p",
"type": "tuple",
"components": [
{
"name": "token0",
"type": "address",
"internalType": "address"
},
{
"name": "token1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "amount0Desired",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Desired",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount0Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct FeeRouter.V3MintParams"
}
],
"outputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "liquidity",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "amount0",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "mintV3Batch",
"type": "function",
"inputs": [
{
"name": "ps",
"type": "tuple[]",
"components": [
{
"name": "token0",
"type": "address",
"internalType": "address"
},
{
"name": "token1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "amount0Desired",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Desired",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount0Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct FeeRouter.V3MintParams[]"
}
],
"outputs": [
{
"name": "tokenIds",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "payable"
},
{
"name": "mintV4",
"type": "function",
"inputs": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "liquidity",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount0Max",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "amount1Max",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "hookData",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "npm",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingOwner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "permit2",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setDefaultFeeBps",
"type": "function",
"inputs": [
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setExemptToken",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "minHold",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFeeOverride",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setTreasury",
"type": "function",
"inputs": [
{
"name": "treasury_",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "swap",
"type": "function",
"inputs": [
{
"name": "p",
"type": "tuple",
"components": [
{
"name": "tokenIn",
"type": "address",
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"internalType": "address"
},
{
"name": "amountIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountOutMin",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "venue",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "v3Fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "unwrapEth",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct FeeRouter.SwapParams"
}
],
"outputs": [
{
"name": "amountOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "swapRouter02",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "sweep",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "treasury",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "v4PositionManager",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "weth",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "zapMintV3",
"type": "function",
"inputs": [
{
"name": "p",
"type": "tuple",
"components": [
{
"name": "token0",
"type": "address",
"internalType": "address"
},
{
"name": "token1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "inputToken",
"type": "address",
"internalType": "address"
},
{
"name": "inputAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "swapAmountIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "swapAmountOutMin",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "swapVenue",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "swapFee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "amount0Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1Min",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct FeeRouter.ZapV3Params"
}
],
"outputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "liquidity",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "amount0",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amount1",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x610120604052348015610010575f80fd5b5060405161464d38038061464d83398101604081905261002f916101eb565b806001600160a01b03811661005d57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006681610165565b5060016002556001600160a01b038816158061008957506001600160a01b038716155b8061009b57506001600160a01b038616155b806100ad57506001600160a01b038516155b806100bf57506001600160a01b038416155b806100d157506001600160a01b038316155b156100ef5760405163d92e233d60e01b815260040160405180910390fd5b603261ffff831611156101155760405163cd4e616760e01b815260040160405180910390fd5b506001600160a01b0396871660805294861660a05292851660c05290841660e0528316610100526003805461ffff909316600160a01b026001600160b01b03199093169190931617179055610285565b600180546001600160a01b031916905561017e81610181565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146101e6575f80fd5b919050565b5f805f805f805f80610100898b031215610203575f80fd5b61020c896101d0565b975061021a60208a016101d0565b965061022860408a016101d0565b955061023660608a016101d0565b945061024460808a016101d0565b935061025260a08a016101d0565b925060c089015161ffff81168114610268575f80fd5b915061027660e08a016101d0565b90509295985092959890939650565b60805160a05160c05160e051610100516142966103b75f395f818161051c01528181613106015281816131c201526132dd01525f81816101ee015281816103e8015281816107ca015281816112f9015281816113a20152818161151b015281816115e1015281816117f80152818161185b015281816118ef01528181611cff01528181611d3a01528181611d8c01528181611e1901528181611e690152818161239201526123e101525f81816102b301528181612a7b0152612b1d01525f818161066701528181612adc01528181612b9e01528181612de50152612ea301525f818161054f015281816109fe0152818161210f015281816121570152818161219d0152818161252d0152818161257d01528181612646015281816133660152818161339e01526133e401526142965ff3fe6080604052600436106101de575f3560e01c806379ba5097116100fd578063bcae25a411610092578063e30c397811610062578063e30c397814610689578063f0f44260146106a6578063f2fde38b146106c5578063fd8e077d146106e4575f80fd5b8063bcae25a414610601578063d3b9568e14610622578063d55be8c614610642578063e2f4dd4314610656575f80fd5b80638f6e9dd6116100cd5780638f6e9dd61461058d5780639f43c63f146105a0578063a89bf3f3146105bf578063a8f95ac4146105ee575f80fd5b806379ba5097146104f75780637eaf11161461050b5780637f1e9ef61461053e5780638da5cb5b14610571575f80fd5b80634488b6521161017357806361d027b31161014357806361d027b31461049157806362c06767146104b057806364573aaa146104cf578063715018a6146104e3575f80fd5b80634488b6521461040a57806351102ee014610429578063576a29b6146104485780635e97aece14610466575f80fd5b806328e5e84e116101ae57806328e5e84e1461034e5780632b94b1f31461036d5780632fc1c400146103a55780633fc8cef3146103d7575f80fd5b80630a335b731461026657806312261ee7146102a25780632049f71f146102d5578063273c71aa14610313575f80fd5b3661026257336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102605760405162461bcd60e51b815260206004820152601860248201527f466565526f757465723a206e6f2064697265637420455448000000000000000060448201526064015b60405180910390fd5b005b5f80fd5b348015610271575f80fd5b5061028561028036600461381a565b6106f7565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102ad575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e0575f80fd5b506103036102ef366004613850565b60056020525f908152604090205460ff1681565b6040519015158152602001610299565b61032661032136600461386b565b61071f565b604080519485526001600160801b039093166020850152918301526060820152608001610299565b348015610359575f80fd5b50610260610368366004613896565b610930565b61038061037b3660046138c9565b6109d1565b604080516001600160801b039094168452602084019290925290820152606001610299565b3480156103b0575f80fd5b506103c46103bf366004613850565b610b75565b60405161ffff9091168152602001610299565b3480156103e2575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b348015610415575f80fd5b50610260610424366004613908565b610bdc565b348015610434575f80fd5b50610260610443366004613921565b610c61565b348015610453575f80fd5b506006545b604051908152602001610299565b348015610471575f80fd5b50610458610480366004613850565b60076020525f908152604090205481565b34801561049c575f80fd5b50600354610285906001600160a01b031681565b3480156104bb575f80fd5b506102606104ca36600461394b565b610e8c565b3480156104da575f80fd5b50610458600881565b3480156104ee575f80fd5b50610260610f87565b348015610502575f80fd5b50610260610f9a565b348015610516575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b348015610549575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b34801561057c575f80fd5b505f546001600160a01b0316610285565b61045861059b366004613a06565b610fde565b3480156105ab575f80fd5b506102606105ba366004613850565b6111e7565b3480156105ca575f80fd5b506103c46105d9366004613850565b60046020525f908152604090205461ffff1681565b6104586105fc366004613acf565b61124a565b34801561060c575f80fd5b506003546103c490600160a01b900461ffff1681565b610635610630366004613ae1565b611795565b6040516102999190613b53565b34801561064d575f80fd5b506103c4603281565b348015610661575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b348015610694575f80fd5b506001546001600160a01b0316610285565b3480156106b1575f80fd5b506102606106c0366004613850565b611b6b565b3480156106d0575f80fd5b506102606106df366004613850565b611be8565b6103266106f2366004613b95565b611c58565b60068181548110610706575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f805f8061072b611cca565b6107386020860186613850565b6001600160a01b031661075160c0870160a08801613850565b6001600160a01b03161415801561079857506107736040860160208701613850565b6001600160a01b031661078c60c0870160a08801613850565b6001600160a01b031614155b156107b65760405163fecc1dd160e01b815260040160405180910390fd5b5f3411801561080657506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166107fa60c0870160a08801613850565b6001600160a01b031614155b156108245760405163fecc1dd160e01b815260040160405180910390fd5b6108496108346020870187613850565b6108446040880160208901613850565b611cf2565b5f61085333610b75565b90505f61087461086960c0890160a08a01613850565b8860c0013584611dfe565b9050808760e00135111561089b5760405163fecc1dd160e01b815260040160405180910390fd5b5f6108a588611fc3565b90506108b28883836120a9565b60405160038152939a5091985096509450879033907fb1caa07eec0f7a1ac7fc98946e0cce23de64e71dcb0bd9b55f96418b6268b51c9060200160405180910390a361090961090460208a018a613850565b612311565b61091c61090460408a0160208b01613850565b5050506109296001600255565b9193509193565b6109386124ed565b603261ffff8216111561095e5760405163cd4e616760e01b815260040160405180910390fd5b6001600160a01b0382165f818152600460209081526040808320805461ffff191661ffff87169081179091556005835292819020805460ff19166001179055519182527f5b6047fd6ec2078f028645fe3b1300c6036ce040cea980959e5165728982ad5191015b60405180910390a25050565b5f805f6109dc611cca565b60405163133f757160e31b8152600481018a90525f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906399fbab889060240161018060405180830381865afa158015610a44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a689190613be3565b5050505050505050935093505050610a808282611cf2565b5f610a8a33610b75565b90505f610a98848d84611dfe565b90505f610aa6848d85611dfe565b9050610afa6040518061010001604052805f81526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81525090565b8e81526001600160a01b03808716602083015285166040820152606081018390526080810182905260a081018c905260c081018b905260e081018a9052610b4081612519565b919a5098509650610b5086612311565b610b5985612311565b505050505050610b696001600255565b96509650969350505050565b6001600160a01b0381165f9081526005602052604081205460ff1615610bb457506001600160a01b03165f9081526004602052604090205461ffff1690565b610bbd826126bd565b15610bc957505f919050565b5050600354600160a01b900461ffff1690565b610be46124ed565b603261ffff82161115610c0a5760405163cd4e616760e01b815260040160405180910390fd5b6003805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f9283ddc0c2b59320e00b0ae4a992b110df098c38e3b6ea1d92fe7a6d3504be9b906020015b60405180910390a150565b610c696124ed565b6001600160a01b038216610c905760405163d92e233d60e01b815260040160405180910390fd5b805f03610daa576006545f5b81811015610d8b57836001600160a01b031660068281548110610cc157610cc1613cbd565b5f918252602090912001546001600160a01b031603610d83576006610ce7600184613ce5565b81548110610cf757610cf7613cbd565b5f91825260209091200154600680546001600160a01b039092169183908110610d2257610d22613cbd565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506006805480610d5e57610d5e613cf8565b5f8281526020902081015f1990810180546001600160a01b0319169055019055610d8b565b600101610c9c565b50506001600160a01b0382165f90815260076020526040812055610e51565b6001600160a01b0382165f908152600760205260408120549003610e3657600654600811610deb57604051630245631d60e01b815260040160405180910390fd5b600680546001810182555f919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b0382165f9081526007602052604090208190555b816001600160a01b03167f21b13fe69ef64f77a4e3dd6bd9d883f4c1b6c8b41eb681307c3c194058e3bd09826040516109c591815260200190565b610e946124ed565b6001600160a01b038216610ebb5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038316610f6e575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610f12576040519150601f19603f3d011682016040523d82523d5f602084013e610f17565b606091505b5050905080610f685760405162461bcd60e51b815260206004820152601760248201527f466565526f757465723a207377656570206661696c65640000000000000000006044820152606401610257565b50505050565b610f826001600160a01b0384168383612800565b505050565b610f8f6124ed565b610f985f61285f565b565b60015433906001600160a01b03168114610fd25760405163118cdaa760e01b81526001600160a01b0382166004820152602401610257565b610fdb8161285f565b50565b5f610fe7611cca565b5f610ff133610b75565b90505f61101461100460208f018f613850565b8a6001600160801b031684612878565b90505f61103d8e602001602081019061102d9190613850565b8a6001600160801b031685612878565b905061105b8e5f0160208101906110549190613850565b8387612a4c565b6110788e60200160208101906110719190613850565b8287612a4c565b60408051610180810182525f60e08201818152610100830182905261012083018290526101408301829052610160830182905282526020820181905291810182905260608082018390526080820183905260a082015260c08101919091528e8036038101906110e79190613d2b565b815260028e810b602080840191909152908e900b604080840191909152606083018e90526001600160a01b038b1660808401528051601f8a018390048302810183019091528881529089908990819084018382808284375f9201919091525050505060a082015260c08101869052611160818484612b7d565b60405160048152909550859033907fb1caa07eec0f7a1ac7fc98946e0cce23de64e71dcb0bd9b55f96418b6268b51c9060200160405180910390a36111b58f5f0160208101906111b09190613850565b612f8e565b6111cb8f60200160208101906111b09190613850565b505050506111d96001600255565b9a9950505050505050505050565b6111ef6124ed565b6001600160a01b0381165f818152600460209081526040808320805461ffff191690556005909152808220805460ff19169055517fb73e0bc3bac79206ed7d70a7f92040859a1d8409a7fa5ce35ae23a142be5e6769190a250565b5f611253611cca565b6112636040830160208401613850565b6001600160a01b03166112796020840184613850565b6001600160a01b0316036112a05760405163fecc1dd160e01b815260040160405180910390fd5b8160e001354211156112e95760405162461bcd60e51b8152602060048201526012602482015271119959549bdd5d195c8e88195e1c1a5c995960721b6044820152606401610257565b3415611415576001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166113266020840184613850565b6001600160a01b03161461134d5760405163fecc1dd160e01b815260040160405180910390fd5b816040013534146113a05760405162461bcd60e51b815260206004820152601960248201527f466565526f757465723a2076616c7565206d69736d61746368000000000000006044820152606401610257565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b1580156113f9575f80fd5b505af115801561140b573d5f803e3d5ffd5b505050505061143d565b61143d3330604085013561142c6020870187613850565b6001600160a01b03169291906130bd565b5f61144733610b75565b90505f61271061145f61ffff84166040870135613dc5565b6114699190613ddc565b905080156114e65760035461149f906001600160a01b03168261148f6020880188613850565b6001600160a01b03169190612800565b6114ac6020850185613850565b6001600160a01b0316336001600160a01b03165f80516020614241833981519152836040516114dd91815260200190565b60405180910390a35b5f6114f5826040870135613ce5565b90505f61150a61012087016101008801613e08565b801561155657506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661154b6040880160208901613850565b6001600160a01b0316145b90505f816115735761156e60e0880160c08901613850565b611575565b305b90506115c36115876020890189613850565b61159760408a0160208b01613850565b8560608b01356115ad60a08d0160808e01613e23565b6115bd60c08e0160a08f01613e43565b876130f6565b955081156116f257604051632e1a7d4d60e01b8152600481018790527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b15801561162a575f80fd5b505af115801561163c573d5f803e3d5ffd5b505f925061165391505060e0890160c08a01613850565b6001600160a01b0316876040515f6040518083038185875af1925050503d805f811461169a576040519150601f19603f3d011682016040523d82523d5f602084013e61169f565b606091505b50509050806116f05760405162461bcd60e51b815260206004820152601960248201527f466565526f757465723a20455448206f7574206661696c6564000000000000006044820152606401610257565b505b6117026040880160208901613850565b6001600160a01b03166117186020890189613850565b6001600160a01b0316336001600160a01b03167fc09a87fef55a1b0b52660066191b17f8a775ce5c903bf7cee9b7b778f84b48848a604001358a604051611769929190918252602082015260400190565b60405180910390a46117816109046020890189613850565b50505050506117906001600255565b919050565b606061179f611cca565b816117e55760405162461bcd60e51b815260206004820152601660248201527508ccacaa4deeae8cae47440cadae0e8f240c4c2e8c6d60531b6044820152606401610257565b341561195f575f805b838110156118cf577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685858381811061183257611832613cbd565b611849926020610160909202019081019150613850565b6001600160a01b031614806118b957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685858381811061189557611895613cbd565b9050610160020160200160208101906118ae9190613850565b6001600160a01b0316145b156118c757600191506118cf565b6001016117ee565b50806118ed5760405162461bcd60e51b815260040161025790613e5e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015611946575f80fd5b505af1158015611958573d5f803e3d5ffd5b5050505050505b5f61196933610b75565b90508267ffffffffffffffff81111561198457611984613d0c565b6040519080825280602002602001820160405280156119ad578160200160208202803683370190505b5091505f5b83811015611aec575f611a0a8686848181106119d0576119d0613cbd565b6119e7926020610160909202019081019150613850565b8787858181106119f9576119f9613cbd565b9050610160020160a0013585611dfe565b90505f611a5e878785818110611a2257611a22613cbd565b905061016002016020016020810190611a3b9190613850565b888886818110611a4d57611a4d613cbd565b9050610160020160c0013586611dfe565b90505f611a84888886818110611a7657611a76613cbd565b905061016002018484613357565b505050905080868581518110611a9c57611a9c613cbd565b60209081029190910181019190915260405160038152829133917fb1caa07eec0f7a1ac7fc98946e0cce23de64e71dcb0bd9b55f96418b6268b51c910160405180910390a35050506001016119b2565b505f5b83811015611b5957611b23858583818110611b0c57611b0c613cbd565b610904926020610160909202019081019150613850565b611b51858583818110611b3857611b38613cbd565b9050610160020160200160208101906109049190613850565b600101611aef565b5050611b656001600255565b92915050565b611b736124ed565b6001600160a01b038116611b9a5760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f90602001610c56565b611bf06124ed565b600180546001600160a01b0383166001600160a01b03199091168117909155611c205f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f805f80611c64611cca565b611c746108346020870187613850565b5f611c7e33610b75565b90505f611c9c611c916020890189613850565b8860a0013584611dfe565b90505f611cbd611cb260408a0160208b01613850565b8960c0013585611dfe565b90506108b2888383613357565b6002805403611cec57604051633ee5aeb560e01b815260040160405180910390fd5b60028055565b345f03611cfd575050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480611d6e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316145b611d8a5760405162461bcd60e51b815260040161025790613e5e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015611de3575f80fd5b505af1158015611df5573d5f803e3d5ffd5b50505050505050565b5f825f03611e0d57505f611fbc565b5f34118015611e4d57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316145b15611f2d576040516370a0823160e01b815230600482015283907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611eb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eda9190613ea2565b1015611f285760405162461bcd60e51b815260206004820152601b60248201527f466565526f757465723a20696e73756666696369656e742045544800000000006044820152606401610257565b611f42565b611f426001600160a01b0385163330866130bd565b5f612710611f5461ffff851686613dc5565b611f5e9190613ddc565b90508015611fae57600354611f80906001600160a01b03878116911683612800565b6040518181526001600160a01b0386169033905f805160206142418339815191529060200160405180910390a35b611fb88185613ce5565b9150505b9392505050565b5f8160e001355f03611fd657505f919050565b5f611fe46020840184613850565b6001600160a01b0316611ffd60c0850160a08601613850565b6001600160a01b03161461201d576120186020840184613850565b61202d565b61202d6040840160208501613850565b9050611fbc61204260c0850160a08601613850565b8260e086013561010087013561206061014089016101208a01613e23565b6120726101608a016101408b01613e43565b62ffffff16156120935761208e6101608a016101408b01613e43565b6120a3565b6120a360608a0160408b01613e43565b306130f6565b5f808080806120bc60e089013588613ce5565b90505f806120cd60208b018b613850565b6001600160a01b03166120e660c08c0160a08d01613850565b6001600160a01b0316036120fe575081905086612104565b50869050815b811561214c5761214c7f00000000000000000000000000000000000000000000000000000000000000008361213c60208e018e613850565b6001600160a01b0316919061354b565b8015612187576121877f00000000000000000000000000000000000000000000000000000000000000008261213c60408e0160208f01613850565b6040805161016081019091526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638831645690806121d260208f018f613850565b6001600160a01b031681526020018d60200160208101906121f39190613850565b6001600160a01b031681526020018d60400160208101906122149190613e43565b62ffffff1681526020018d60600160208101906122319190613eb9565b60020b81526020018d608001602081019061224c9190613eb9565b60020b81526020018581526020018481526020018d610160013581526020018d610180013581526020018d6101a001602081019061228a9190613850565b6001600160a01b031681526020018d6101c001358152506040518263ffffffff1660e01b81526004016122bd9190613ed4565b6080604051808303815f875af11580156122d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122fd9190613f98565b965096509650965050505093509350935093565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015612355573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123799190613ea2565b9050805f03612386575050565b5f341180156123c657507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316145b156124d557604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b15801561242a575f80fd5b505af115801561243c573d5f803e3d5ffd5b50506040515f925033915083908381818185875af1925050503d805f811461247f576040519150601f19603f3d011682016040523d82523d5f602084013e612484565b606091505b5050905080610f825760405162461bcd60e51b815260206004820152601c60248201527f466565526f757465723a2045544820726566756e64206661696c6564000000006044820152606401610257565b6124e96001600160a01b0383163383612800565b5050565b5f546001600160a01b03163314610f985760405163118cdaa760e01b8152336004820152602401610257565b5f805f808460600151111561256e5761256e7f0000000000000000000000000000000000000000000000000000000000000000856060015186602001516001600160a01b031661354b9092919063ffffffff16565b6080840151156125be576125be7f0000000000000000000000000000000000000000000000000000000000000000856080015186604001516001600160a01b031661354b9092919063ffffffff16565b6040805160c0808201835286518252606080880151602084019081526080808a015185870190815260a0808c0151948701948552948b015191860191825260e08b0151948601948552955163219f5d1760e01b815294516004860152905160248501529351604484015251606483015291516084820152905160a48201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063219f5d179060c4016060604051808303815f875af115801561268c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126b09190613fd4565b9250925092509193909250565b6006545f90815b818110156127f7575f600682815481106126e0576126e0613cbd565b5f9182526020822001546040516001600160a01b0388811660248301529091169250819083906370a0823160e01b9060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516127509190614008565b5f60405180830381855afa9150503d805f8114612788576040519150601f19603f3d011682016040523d82523d5f602084013e61278d565b606091505b50915091508180156127a157506020815110155b80156127da57506001600160a01b0383165f90815260076020908152604090912054825190916127d79184018101908401613ea2565b10155b156127ec575060019695505050505050565b5050506001016126c4565b505f9392505050565b6040516001600160a01b03838116602483015260448201839052610f8291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506135d6565b600180546001600160a01b0319169055610fdb81613637565b5f825f0361288757505f611fbc565b835f61271061289a61ffff861687613dc5565b6128a49190613ddc565b90506001600160a01b0382166129d557843410156129045760405162461bcd60e51b815260206004820152601b60248201527f466565526f757465723a20696e73756666696369656e742045544800000000006044820152606401610257565b80156129d0576003546040515f916001600160a01b03169083908381818185875af1925050503d805f8114612954576040519150601f19603f3d011682016040523d82523d5f602084013e612959565b606091505b50509050806129aa5760405162461bcd60e51b815260206004820152601e60248201527f466565526f757465723a20666565207472616e73666572206661696c656400006044820152606401610257565b6040518281525f9033905f805160206142418339815191529060200160405180910390a3505b612a38565b6129ea6001600160a01b0383163330886130bd565b8015612a3857600354612a0a906001600160a01b03848116911683612800565b6040518181526001600160a01b0383169033905f805160206142418339815191529060200160405180910390a35b612a428186613ce5565b9695505050505050565b826001600160a01b0381161580612a61575082155b15612a6c5750505050565b612aa06001600160a01b0382167f00000000000000000000000000000000000000000000000000000000000000008561354b565b5f65ffffffffffff831015612ab55782612abd565b65ffffffffffff5b6040516387517c4560e01b81526001600160a01b0384811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152868116604483015265ffffffffffff831660648301529192507f0000000000000000000000000000000000000000000000000000000000000000909116906387517c45906084015f604051808303815f87803b158015612b60575f80fd5b505af1158015612b72573d5f803e3d5ffd5b505050505050505050565b5f805f6001600160a01b0316855f01515f01516001600160a01b03161490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bf8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c1c9190613ea2565b91506060808215612cd457604051600160f91b6020820152600d60f81b6021820152600560fa1b602282015260230160408051808303601f190181526003808452608084019092529350816020015b6060815260200190600190039081612c6b57905050875151604080516001600160a01b039092166020830152339082015290915060600160405160208183030381529060405281600281518110612cc457612cc4613cbd565b6020026020010181905250612d26565b604051600160f91b6020820152600d60f81b602182015260220160408051808303601f190181526002808452606084019092529350816020015b6060815260200190600190039081612d0e5790505090505b865f015187602001518860400151896060015189898c608001518d60a00151604051602001612d5c98979695949392919061404c565b604051602081830303815290604052815f81518110612d7d57612d7d613cbd565b6020908102919091018101919091528751805190820151604051612db693016001600160a01b0392831681529116602082015260400190565b60405160208183030381529060405281600181518110612dd857612dd8613cbd565b60200260200101819052507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663dd46508f84612e1d575f612e1f565b875b8484604051602001612e32929190614102565b60408051601f198184030181529082905260c08c01516001600160e01b031960e086901b168352612e6592600401614177565b5f604051808303818588803b158015612e7c575f80fd5b505af1158015612e8e573d5f803e3d5ffd5b505050505086608001516001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e866040518263ffffffff1660e01b8152600401612eef91815260200190565b602060405180830381865afa158015612f0a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f2e9190614198565b6001600160a01b031614612f845760405162461bcd60e51b815260206004820152601b60248201527f466565526f757465723a207634206d696e74206d69736d6174636800000000006044820152606401610257565b5050509392505050565b806001600160a01b03811661303957478015610f82576040515f90339083908381818185875af1925050503d805f8114612fe3576040519150601f19603f3d011682016040523d82523d5f602084013e612fe8565b606091505b5050905080610f685760405162461bcd60e51b815260206004820152601c60248201527f466565526f757465723a2045544820726566756e64206661696c6564000000006044820152606401610257565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa15801561307d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a19190613ea2565b90508015610f8257610f826001600160a01b0383163383612800565b6040516001600160a01b038481166024830152838116604483015260648201839052610f689186918216906323b872dd9060840161282d565b5f61312b6001600160a01b0389167f00000000000000000000000000000000000000000000000000000000000000008861354b565b5f1960ff851601613247576040805160028082526060820183525f9260208301908036833701905050905088815f8151811061316957613169613cbd565b60200260200101906001600160a01b031690816001600160a01b031681525050878160018151811061319d5761319d613cbd565b6001600160a01b03928316602091820292909201015260405163472b43f360e01b81527f00000000000000000000000000000000000000000000000000000000000000009091169063472b43f3906131ff908a908a90869089906004016141b3565b6020604051808303815f875af115801561321b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061323f9190613ea2565b91505061334c565b6040805160e0810182526001600160a01b038a811682528981166020830190815262ffffff87811684860190815287841660608601908152608086018d815260a087018d81525f60c0890190815298516304e45aaf60e01b8152975187166004890152945186166024880152915190921660448601529051831660648501525160848401525160a48301529151821660c48201527f0000000000000000000000000000000000000000000000000000000000000000909116906304e45aaf9060e4016020604051808303815f875af1158015613325573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133499190613ea2565b90505b979650505050505050565b5f8080808515613393576133937f00000000000000000000000000000000000000000000000000000000000000008761213c60208b018b613850565b84156133ce576133ce7f00000000000000000000000000000000000000000000000000000000000000008661213c60408b0160208c01613850565b6040805161016081019091526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906388316456908061341960208c018c613850565b6001600160a01b031681526020018a602001602081019061343a9190613850565b6001600160a01b0316815260200161345860608c0160408d01613e43565b62ffffff16815260200161347260808c0160608d01613eb9565b60020b815260200161348a60a08c0160808d01613eb9565b60020b8152602081018a90526040810189905260e08b013560608201526101008b0135608082015260a0016134c76101408c016101208d01613850565b6001600160a01b031681526020018a61014001358152506040518263ffffffff1660e01b81526004016134fa9190613ed4565b6080604051808303815f875af1158015613516573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061353a9190613f98565b935093509350935093509350935093565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261359c8482613686565b610f68576040516001600160a01b0384811660248301525f60448301526135d091869182169063095ea7b39060640161282d565b610f6884825b5f6135ea6001600160a01b03841683613727565b905080515f1415801561360e57508080602001905181019061360c9190614225565b155b15610f8257604051635274afe760e01b81526001600160a01b0384166004820152602401610257565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f805f846001600160a01b0316846040516136a19190614008565b5f604051808303815f865af19150503d805f81146136da576040519150601f19603f3d011682016040523d82523d5f602084013e6136df565b606091505b50915091508180156137095750805115806137095750808060200190518101906137099190614225565b801561371e57505f856001600160a01b03163b115b95945050505050565b6060611fbc83835f845f80856001600160a01b0316848660405161374b9190614008565b5f6040518083038185875af1925050503d805f8114613785576040519150601f19603f3d011682016040523d82523d5f602084013e61378a565b606091505b5091509150612a428683836060826137aa576137a5826137f1565b611fbc565b81511580156137c157506001600160a01b0384163b155b156137ea57604051639996b31560e01b81526001600160a01b0385166004820152602401610257565b5080611fbc565b8051156138015780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f6020828403121561382a575f80fd5b5035919050565b6001600160a01b0381168114610fdb575f80fd5b803561179081613831565b5f60208284031215613860575f80fd5b8135611fbc81613831565b5f6101e082840312801561387d575f80fd5b509092915050565b803561ffff81168114611790575f80fd5b5f80604083850312156138a7575f80fd5b82356138b281613831565b91506138c060208401613885565b90509250929050565b5f805f805f8060c087890312156138de575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b5f60208284031215613918575f80fd5b611fbc82613885565b5f8060408385031215613932575f80fd5b823561393d81613831565b946020939093013593505050565b5f805f6060848603121561395d575f80fd5b833561396881613831565b9250602084013561397881613831565b929592945050506040919091013590565b8060020b8114610fdb575f80fd5b803561179081613989565b6001600160801b0381168114610fdb575f80fd5b8035611790816139a2565b5f8083601f8401126139d1575f80fd5b50813567ffffffffffffffff8111156139e8575f80fd5b6020830191508360208285010111156139ff575f80fd5b9250929050565b5f805f805f805f805f808a8c036101a0811215613a21575f80fd5b60a0811215613a2e575f80fd5b508a995060a08b0135613a4081613989565b985060c08b0135613a5081613989565b975060e08b013596506101008b0135613a68816139a2565b9550613a776101208c016139b6565b9450613a866101408c01613845565b93506101608b013567ffffffffffffffff811115613aa2575f80fd5b613aae8d828e016139c1565b9b9e9a9d50989b979a96999598949794969561018090950135949350505050565b5f61012082840312801561387d575f80fd5b5f8060208385031215613af2575f80fd5b823567ffffffffffffffff811115613b08575f80fd5b8301601f81018513613b18575f80fd5b803567ffffffffffffffff811115613b2e575f80fd5b85602061016083028401011115613b43575f80fd5b6020919091019590945092505050565b602080825282518282018190525f918401906040840190835b81811015613b8a578351835260209384019390920191600101613b6c565b509095945050505050565b5f61016082840312801561387d575f80fd5b805161179081613831565b62ffffff81168114610fdb575f80fd5b805161179081613bb2565b805161179081613989565b8051611790816139a2565b5f805f805f805f805f805f806101808d8f031215613bff575f80fd5b8c516bffffffffffffffffffffffff81168114613c1a575f80fd5b9b50613c2860208e01613ba7565b9a50613c3660408e01613ba7565b9950613c4460608e01613ba7565b9850613c5260808e01613bc2565b9750613c6060a08e01613bcd565b9650613c6e60c08e01613bcd565b9550613c7c60e08e01613bd8565b6101008e01516101208f015191965094509250613c9c6101408e01613bd8565b9150613cab6101608e01613bd8565b90509295989b509295989b509295989b565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611b6557611b65613cd1565b634e487b7160e01b5f52603160045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b803561179081613bb2565b5f60a0828403128015613d3c575f80fd5b5060405160a0810167ffffffffffffffff81118282101715613d6c57634e487b7160e01b5f52604160045260245ffd5b604052613d7883613845565b8152613d8660208401613845565b6020820152613d9760408401613d20565b6040820152613da860608401613997565b6060820152613db960808401613845565b60808201529392505050565b8082028115828204841417611b6557611b65613cd1565b5f82613df657634e487b7160e01b5f52601260045260245ffd5b500490565b8015158114610fdb575f80fd5b5f60208284031215613e18575f80fd5b8135611fbc81613dfb565b5f60208284031215613e33575f80fd5b813560ff81168114611fbc575f80fd5b5f60208284031215613e53575f80fd5b8135611fbc81613bb2565b60208082526024908201527f466565526f757465723a204554482073656e7420627574206e6f2057455448206040820152637369646560e01b606082015260800190565b5f60208284031215613eb2575f80fd5b5051919050565b5f60208284031215613ec9575f80fd5b8135611fbc81613989565b81516001600160a01b0316815261016081016020830151613f0060208401826001600160a01b03169052565b506040830151613f17604084018262ffffff169052565b506060830151613f2c606084018260020b9052565b506080830151613f41608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e0830152610100830151610100830152610120830151613f886101208401826001600160a01b03169052565b5061014092830151919092015290565b5f805f8060808587031215613fab575f80fd5b84516020860151909450613fbe816139a2565b6040860151606090960151949790965092505050565b5f805f60608486031215613fe6575f80fd5b8351613ff1816139a2565b602085015160409095015190969495509392505050565b5f82518060208501845e5f920191825250919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b88516001600160a01b0390811682526020808b01518216908301526040808b015162ffffff16908301526060808b015160020b908301526080808b01519091169082015261409f60a082018960020b9052565b6140ae60c082018860020b9052565b8560e08201526140ca6101008201866001600160801b03169052565b6001600160801b0384166101208201526001600160a01b0383166101408201526101806101608201525f6111d961018083018461401e565b604081525f614114604083018561401e565b828103602084015280845180835260208301915060208160051b840101602087015f5b8381101561416957601f1986840301855261415383835161401e565b6020958601959093509190910190600101614137565b509098975050505050505050565b604081525f614189604083018561401e565b90508260208301529392505050565b5f602082840312156141a8575f80fd5b8151611fbc81613831565b5f608082018683528560208401526080604084015280855180835260a0850191506020870192505f5b818110156142035783516001600160a01b03168352602093840193909201916001016141dc565b50506001600160a01b0394909416606093909301929092525090949350505050565b5f60208284031215614235575f80fd5b8151611fbc81613dfb56fe945458c62aa39df7a4d87d6c4dbaaab7de5d870c9a1fe40e2b7571d84f158a8da2646970667358221220ea9daff9b187127e739696df1f34fed2f555c7ad437231e03c00c63157fc840c64736f6c634300081a003300000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d300000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa7000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba30000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73000000000000000000000000caf681a66d020601342297493863e78c959e5cb200000000000000000000000082cb8311eb8d212919f5606fd17d8eda8c321974000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000082cb8311eb8d212919f5606fd17d8eda8c321974
0x6080604052600436106101de575f3560e01c806379ba5097116100fd578063bcae25a411610092578063e30c397811610062578063e30c397814610689578063f0f44260146106a6578063f2fde38b146106c5578063fd8e077d146106e4575f80fd5b8063bcae25a414610601578063d3b9568e14610622578063d55be8c614610642578063e2f4dd4314610656575f80fd5b80638f6e9dd6116100cd5780638f6e9dd61461058d5780639f43c63f146105a0578063a89bf3f3146105bf578063a8f95ac4146105ee575f80fd5b806379ba5097146104f75780637eaf11161461050b5780637f1e9ef61461053e5780638da5cb5b14610571575f80fd5b80634488b6521161017357806361d027b31161014357806361d027b31461049157806362c06767146104b057806364573aaa146104cf578063715018a6146104e3575f80fd5b80634488b6521461040a57806351102ee014610429578063576a29b6146104485780635e97aece14610466575f80fd5b806328e5e84e116101ae57806328e5e84e1461034e5780632b94b1f31461036d5780632fc1c400146103a55780633fc8cef3146103d7575f80fd5b80630a335b731461026657806312261ee7146102a25780632049f71f146102d5578063273c71aa14610313575f80fd5b3661026257336001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7316146102605760405162461bcd60e51b815260206004820152601860248201527f466565526f757465723a206e6f2064697265637420455448000000000000000060448201526064015b60405180910390fd5b005b5f80fd5b348015610271575f80fd5b5061028561028036600461381a565b6106f7565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102ad575f80fd5b506102857f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba381565b3480156102e0575f80fd5b506103036102ef366004613850565b60056020525f908152604090205460ff1681565b6040519015158152602001610299565b61032661032136600461386b565b61071f565b604080519485526001600160801b039093166020850152918301526060820152608001610299565b348015610359575f80fd5b50610260610368366004613896565b610930565b61038061037b3660046138c9565b6109d1565b604080516001600160801b039094168452602084019290925290820152606001610299565b3480156103b0575f80fd5b506103c46103bf366004613850565b610b75565b60405161ffff9091168152602001610299565b3480156103e2575f80fd5b506102857f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7381565b348015610415575f80fd5b50610260610424366004613908565b610bdc565b348015610434575f80fd5b50610260610443366004613921565b610c61565b348015610453575f80fd5b506006545b604051908152602001610299565b348015610471575f80fd5b50610458610480366004613850565b60076020525f908152604090205481565b34801561049c575f80fd5b50600354610285906001600160a01b031681565b3480156104bb575f80fd5b506102606104ca36600461394b565b610e8c565b3480156104da575f80fd5b50610458600881565b3480156104ee575f80fd5b50610260610f87565b348015610502575f80fd5b50610260610f9a565b348015610516575f80fd5b506102857f000000000000000000000000caf681a66d020601342297493863e78c959e5cb281565b348015610549575f80fd5b506102857f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d381565b34801561057c575f80fd5b505f546001600160a01b0316610285565b61045861059b366004613a06565b610fde565b3480156105ab575f80fd5b506102606105ba366004613850565b6111e7565b3480156105ca575f80fd5b506103c46105d9366004613850565b60046020525f908152604090205461ffff1681565b6104586105fc366004613acf565b61124a565b34801561060c575f80fd5b506003546103c490600160a01b900461ffff1681565b610635610630366004613ae1565b611795565b6040516102999190613b53565b34801561064d575f80fd5b506103c4603281565b348015610661575f80fd5b506102857f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa781565b348015610694575f80fd5b506001546001600160a01b0316610285565b3480156106b1575f80fd5b506102606106c0366004613850565b611b6b565b3480156106d0575f80fd5b506102606106df366004613850565b611be8565b6103266106f2366004613b95565b611c58565b60068181548110610706575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f805f8061072b611cca565b6107386020860186613850565b6001600160a01b031661075160c0870160a08801613850565b6001600160a01b03161415801561079857506107736040860160208701613850565b6001600160a01b031661078c60c0870160a08801613850565b6001600160a01b031614155b156107b65760405163fecc1dd160e01b815260040160405180910390fd5b5f3411801561080657506001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73166107fa60c0870160a08801613850565b6001600160a01b031614155b156108245760405163fecc1dd160e01b815260040160405180910390fd5b6108496108346020870187613850565b6108446040880160208901613850565b611cf2565b5f61085333610b75565b90505f61087461086960c0890160a08a01613850565b8860c0013584611dfe565b9050808760e00135111561089b5760405163fecc1dd160e01b815260040160405180910390fd5b5f6108a588611fc3565b90506108b28883836120a9565b60405160038152939a5091985096509450879033907fb1caa07eec0f7a1ac7fc98946e0cce23de64e71dcb0bd9b55f96418b6268b51c9060200160405180910390a361090961090460208a018a613850565b612311565b61091c61090460408a0160208b01613850565b5050506109296001600255565b9193509193565b6109386124ed565b603261ffff8216111561095e5760405163cd4e616760e01b815260040160405180910390fd5b6001600160a01b0382165f818152600460209081526040808320805461ffff191661ffff87169081179091556005835292819020805460ff19166001179055519182527f5b6047fd6ec2078f028645fe3b1300c6036ce040cea980959e5165728982ad5191015b60405180910390a25050565b5f805f6109dc611cca565b60405163133f757160e31b8152600481018a90525f9081906001600160a01b037f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d316906399fbab889060240161018060405180830381865afa158015610a44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a689190613be3565b5050505050505050935093505050610a808282611cf2565b5f610a8a33610b75565b90505f610a98848d84611dfe565b90505f610aa6848d85611dfe565b9050610afa6040518061010001604052805f81526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81525090565b8e81526001600160a01b03808716602083015285166040820152606081018390526080810182905260a081018c905260c081018b905260e081018a9052610b4081612519565b919a5098509650610b5086612311565b610b5985612311565b505050505050610b696001600255565b96509650969350505050565b6001600160a01b0381165f9081526005602052604081205460ff1615610bb457506001600160a01b03165f9081526004602052604090205461ffff1690565b610bbd826126bd565b15610bc957505f919050565b5050600354600160a01b900461ffff1690565b610be46124ed565b603261ffff82161115610c0a5760405163cd4e616760e01b815260040160405180910390fd5b6003805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f9283ddc0c2b59320e00b0ae4a992b110df098c38e3b6ea1d92fe7a6d3504be9b906020015b60405180910390a150565b610c696124ed565b6001600160a01b038216610c905760405163d92e233d60e01b815260040160405180910390fd5b805f03610daa576006545f5b81811015610d8b57836001600160a01b031660068281548110610cc157610cc1613cbd565b5f918252602090912001546001600160a01b031603610d83576006610ce7600184613ce5565b81548110610cf757610cf7613cbd565b5f91825260209091200154600680546001600160a01b039092169183908110610d2257610d22613cbd565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506006805480610d5e57610d5e613cf8565b5f8281526020902081015f1990810180546001600160a01b0319169055019055610d8b565b600101610c9c565b50506001600160a01b0382165f90815260076020526040812055610e51565b6001600160a01b0382165f908152600760205260408120549003610e3657600654600811610deb57604051630245631d60e01b815260040160405180910390fd5b600680546001810182555f919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b0382165f9081526007602052604090208190555b816001600160a01b03167f21b13fe69ef64f77a4e3dd6bd9d883f4c1b6c8b41eb681307c3c194058e3bd09826040516109c591815260200190565b610e946124ed565b6001600160a01b038216610ebb5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038316610f6e575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610f12576040519150601f19603f3d011682016040523d82523d5f602084013e610f17565b606091505b5050905080610f685760405162461bcd60e51b815260206004820152601760248201527f466565526f757465723a207377656570206661696c65640000000000000000006044820152606401610257565b50505050565b610f826001600160a01b0384168383612800565b505050565b610f8f6124ed565b610f985f61285f565b565b60015433906001600160a01b03168114610fd25760405163118cdaa760e01b81526001600160a01b0382166004820152602401610257565b610fdb8161285f565b50565b5f610fe7611cca565b5f610ff133610b75565b90505f61101461100460208f018f613850565b8a6001600160801b031684612878565b90505f61103d8e602001602081019061102d9190613850565b8a6001600160801b031685612878565b905061105b8e5f0160208101906110549190613850565b8387612a4c565b6110788e60200160208101906110719190613850565b8287612a4c565b60408051610180810182525f60e08201818152610100830182905261012083018290526101408301829052610160830182905282526020820181905291810182905260608082018390526080820183905260a082015260c08101919091528e8036038101906110e79190613d2b565b815260028e810b602080840191909152908e900b604080840191909152606083018e90526001600160a01b038b1660808401528051601f8a018390048302810183019091528881529089908990819084018382808284375f9201919091525050505060a082015260c08101869052611160818484612b7d565b60405160048152909550859033907fb1caa07eec0f7a1ac7fc98946e0cce23de64e71dcb0bd9b55f96418b6268b51c9060200160405180910390a36111b58f5f0160208101906111b09190613850565b612f8e565b6111cb8f60200160208101906111b09190613850565b505050506111d96001600255565b9a9950505050505050505050565b6111ef6124ed565b6001600160a01b0381165f818152600460209081526040808320805461ffff191690556005909152808220805460ff19169055517fb73e0bc3bac79206ed7d70a7f92040859a1d8409a7fa5ce35ae23a142be5e6769190a250565b5f611253611cca565b6112636040830160208401613850565b6001600160a01b03166112796020840184613850565b6001600160a01b0316036112a05760405163fecc1dd160e01b815260040160405180910390fd5b8160e001354211156112e95760405162461bcd60e51b8152602060048201526012602482015271119959549bdd5d195c8e88195e1c1a5c995960721b6044820152606401610257565b3415611415576001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73166113266020840184613850565b6001600160a01b03161461134d5760405163fecc1dd160e01b815260040160405180910390fd5b816040013534146113a05760405162461bcd60e51b815260206004820152601960248201527f466565526f757465723a2076616c7565206d69736d61746368000000000000006044820152606401610257565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b1580156113f9575f80fd5b505af115801561140b573d5f803e3d5ffd5b505050505061143d565b61143d3330604085013561142c6020870187613850565b6001600160a01b03169291906130bd565b5f61144733610b75565b90505f61271061145f61ffff84166040870135613dc5565b6114699190613ddc565b905080156114e65760035461149f906001600160a01b03168261148f6020880188613850565b6001600160a01b03169190612800565b6114ac6020850185613850565b6001600160a01b0316336001600160a01b03165f80516020614241833981519152836040516114dd91815260200190565b60405180910390a35b5f6114f5826040870135613ce5565b90505f61150a61012087016101008801613e08565b801561155657506001600160a01b037f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad731661154b6040880160208901613850565b6001600160a01b0316145b90505f816115735761156e60e0880160c08901613850565b611575565b305b90506115c36115876020890189613850565b61159760408a0160208b01613850565b8560608b01356115ad60a08d0160808e01613e23565b6115bd60c08e0160a08f01613e43565b876130f6565b955081156116f257604051632e1a7d4d60e01b8152600481018790527f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031690632e1a7d4d906024015f604051808303815f87803b15801561162a575f80fd5b505af115801561163c573d5f803e3d5ffd5b505f925061165391505060e0890160c08a01613850565b6001600160a01b0316876040515f6040518083038185875af1925050503d805f811461169a576040519150601f19603f3d011682016040523d82523d5f602084013e61169f565b606091505b50509050806116f05760405162461bcd60e51b815260206004820152601960248201527f466565526f757465723a20455448206f7574206661696c6564000000000000006044820152606401610257565b505b6117026040880160208901613850565b6001600160a01b03166117186020890189613850565b6001600160a01b0316336001600160a01b03167fc09a87fef55a1b0b52660066191b17f8a775ce5c903bf7cee9b7b778f84b48848a604001358a604051611769929190918252602082015260400190565b60405180910390a46117816109046020890189613850565b50505050506117906001600255565b919050565b606061179f611cca565b816117e55760405162461bcd60e51b815260206004820152601660248201527508ccacaa4deeae8cae47440cadae0e8f240c4c2e8c6d60531b6044820152606401610257565b341561195f575f805b838110156118cf577f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031685858381811061183257611832613cbd565b611849926020610160909202019081019150613850565b6001600160a01b031614806118b957507f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031685858381811061189557611895613cbd565b9050610160020160200160208101906118ae9190613850565b6001600160a01b0316145b156118c757600191506118cf565b6001016117ee565b50806118ed5760405162461bcd60e51b815260040161025790613e5e565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015611946575f80fd5b505af1158015611958573d5f803e3d5ffd5b5050505050505b5f61196933610b75565b90508267ffffffffffffffff81111561198457611984613d0c565b6040519080825280602002602001820160405280156119ad578160200160208202803683370190505b5091505f5b83811015611aec575f611a0a8686848181106119d0576119d0613cbd565b6119e7926020610160909202019081019150613850565b8787858181106119f9576119f9613cbd565b9050610160020160a0013585611dfe565b90505f611a5e878785818110611a2257611a22613cbd565b905061016002016020016020810190611a3b9190613850565b888886818110611a4d57611a4d613cbd565b9050610160020160c0013586611dfe565b90505f611a84888886818110611a7657611a76613cbd565b905061016002018484613357565b505050905080868581518110611a9c57611a9c613cbd565b60209081029190910181019190915260405160038152829133917fb1caa07eec0f7a1ac7fc98946e0cce23de64e71dcb0bd9b55f96418b6268b51c910160405180910390a35050506001016119b2565b505f5b83811015611b5957611b23858583818110611b0c57611b0c613cbd565b610904926020610160909202019081019150613850565b611b51858583818110611b3857611b38613cbd565b9050610160020160200160208101906109049190613850565b600101611aef565b5050611b656001600255565b92915050565b611b736124ed565b6001600160a01b038116611b9a5760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f90602001610c56565b611bf06124ed565b600180546001600160a01b0383166001600160a01b03199091168117909155611c205f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f805f80611c64611cca565b611c746108346020870187613850565b5f611c7e33610b75565b90505f611c9c611c916020890189613850565b8860a0013584611dfe565b90505f611cbd611cb260408a0160208b01613850565b8960c0013585611dfe565b90506108b2888383613357565b6002805403611cec57604051633ee5aeb560e01b815260040160405180910390fd5b60028055565b345f03611cfd575050565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b0316826001600160a01b03161480611d6e57507f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b0316816001600160a01b0316145b611d8a5760405162461bcd60e51b815260040161025790613e5e565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015611de3575f80fd5b505af1158015611df5573d5f803e3d5ffd5b50505050505050565b5f825f03611e0d57505f611fbc565b5f34118015611e4d57507f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b0316846001600160a01b0316145b15611f2d576040516370a0823160e01b815230600482015283907f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b0316906370a0823190602401602060405180830381865afa158015611eb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eda9190613ea2565b1015611f285760405162461bcd60e51b815260206004820152601b60248201527f466565526f757465723a20696e73756666696369656e742045544800000000006044820152606401610257565b611f42565b611f426001600160a01b0385163330866130bd565b5f612710611f5461ffff851686613dc5565b611f5e9190613ddc565b90508015611fae57600354611f80906001600160a01b03878116911683612800565b6040518181526001600160a01b0386169033905f805160206142418339815191529060200160405180910390a35b611fb88185613ce5565b9150505b9392505050565b5f8160e001355f03611fd657505f919050565b5f611fe46020840184613850565b6001600160a01b0316611ffd60c0850160a08601613850565b6001600160a01b03161461201d576120186020840184613850565b61202d565b61202d6040840160208501613850565b9050611fbc61204260c0850160a08601613850565b8260e086013561010087013561206061014089016101208a01613e23565b6120726101608a016101408b01613e43565b62ffffff16156120935761208e6101608a016101408b01613e43565b6120a3565b6120a360608a0160408b01613e43565b306130f6565b5f808080806120bc60e089013588613ce5565b90505f806120cd60208b018b613850565b6001600160a01b03166120e660c08c0160a08d01613850565b6001600160a01b0316036120fe575081905086612104565b50869050815b811561214c5761214c7f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d38361213c60208e018e613850565b6001600160a01b0316919061354b565b8015612187576121877f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d38261213c60408e0160208f01613850565b6040805161016081019091526001600160a01b037f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d31690638831645690806121d260208f018f613850565b6001600160a01b031681526020018d60200160208101906121f39190613850565b6001600160a01b031681526020018d60400160208101906122149190613e43565b62ffffff1681526020018d60600160208101906122319190613eb9565b60020b81526020018d608001602081019061224c9190613eb9565b60020b81526020018581526020018481526020018d610160013581526020018d610180013581526020018d6101a001602081019061228a9190613850565b6001600160a01b031681526020018d6101c001358152506040518263ffffffff1660e01b81526004016122bd9190613ed4565b6080604051808303815f875af11580156122d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122fd9190613f98565b965096509650965050505093509350935093565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015612355573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123799190613ea2565b9050805f03612386575050565b5f341180156123c657507f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b0316826001600160a01b0316145b156124d557604051632e1a7d4d60e01b8152600481018290527f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031690632e1a7d4d906024015f604051808303815f87803b15801561242a575f80fd5b505af115801561243c573d5f803e3d5ffd5b50506040515f925033915083908381818185875af1925050503d805f811461247f576040519150601f19603f3d011682016040523d82523d5f602084013e612484565b606091505b5050905080610f825760405162461bcd60e51b815260206004820152601c60248201527f466565526f757465723a2045544820726566756e64206661696c6564000000006044820152606401610257565b6124e96001600160a01b0383163383612800565b5050565b5f546001600160a01b03163314610f985760405163118cdaa760e01b8152336004820152602401610257565b5f805f808460600151111561256e5761256e7f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d3856060015186602001516001600160a01b031661354b9092919063ffffffff16565b6080840151156125be576125be7f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d3856080015186604001516001600160a01b031661354b9092919063ffffffff16565b6040805160c0808201835286518252606080880151602084019081526080808a015185870190815260a0808c0151948701948552948b015191860191825260e08b0151948601948552955163219f5d1760e01b815294516004860152905160248501529351604484015251606483015291516084820152905160a48201526001600160a01b037f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d3169063219f5d179060c4016060604051808303815f875af115801561268c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126b09190613fd4565b9250925092509193909250565b6006545f90815b818110156127f7575f600682815481106126e0576126e0613cbd565b5f9182526020822001546040516001600160a01b0388811660248301529091169250819083906370a0823160e01b9060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516127509190614008565b5f60405180830381855afa9150503d805f8114612788576040519150601f19603f3d011682016040523d82523d5f602084013e61278d565b606091505b50915091508180156127a157506020815110155b80156127da57506001600160a01b0383165f90815260076020908152604090912054825190916127d79184018101908401613ea2565b10155b156127ec575060019695505050505050565b5050506001016126c4565b505f9392505050565b6040516001600160a01b03838116602483015260448201839052610f8291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506135d6565b600180546001600160a01b0319169055610fdb81613637565b5f825f0361288757505f611fbc565b835f61271061289a61ffff861687613dc5565b6128a49190613ddc565b90506001600160a01b0382166129d557843410156129045760405162461bcd60e51b815260206004820152601b60248201527f466565526f757465723a20696e73756666696369656e742045544800000000006044820152606401610257565b80156129d0576003546040515f916001600160a01b03169083908381818185875af1925050503d805f8114612954576040519150601f19603f3d011682016040523d82523d5f602084013e612959565b606091505b50509050806129aa5760405162461bcd60e51b815260206004820152601e60248201527f466565526f757465723a20666565207472616e73666572206661696c656400006044820152606401610257565b6040518281525f9033905f805160206142418339815191529060200160405180910390a3505b612a38565b6129ea6001600160a01b0383163330886130bd565b8015612a3857600354612a0a906001600160a01b03848116911683612800565b6040518181526001600160a01b0383169033905f805160206142418339815191529060200160405180910390a35b612a428186613ce5565b9695505050505050565b826001600160a01b0381161580612a61575082155b15612a6c5750505050565b612aa06001600160a01b0382167f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba38561354b565b5f65ffffffffffff831015612ab55782612abd565b65ffffffffffff5b6040516387517c4560e01b81526001600160a01b0384811660048301527f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa781166024830152868116604483015265ffffffffffff831660648301529192507f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3909116906387517c45906084015f604051808303815f87803b158015612b60575f80fd5b505af1158015612b72573d5f803e3d5ffd5b505050505050505050565b5f805f6001600160a01b0316855f01515f01516001600160a01b03161490507f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa76001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bf8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c1c9190613ea2565b91506060808215612cd457604051600160f91b6020820152600d60f81b6021820152600560fa1b602282015260230160408051808303601f190181526003808452608084019092529350816020015b6060815260200190600190039081612c6b57905050875151604080516001600160a01b039092166020830152339082015290915060600160405160208183030381529060405281600281518110612cc457612cc4613cbd565b6020026020010181905250612d26565b604051600160f91b6020820152600d60f81b602182015260220160408051808303601f190181526002808452606084019092529350816020015b6060815260200190600190039081612d0e5790505090505b865f015187602001518860400151896060015189898c608001518d60a00151604051602001612d5c98979695949392919061404c565b604051602081830303815290604052815f81518110612d7d57612d7d613cbd565b6020908102919091018101919091528751805190820151604051612db693016001600160a01b0392831681529116602082015260400190565b60405160208183030381529060405281600181518110612dd857612dd8613cbd565b60200260200101819052507f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa76001600160a01b031663dd46508f84612e1d575f612e1f565b875b8484604051602001612e32929190614102565b60408051601f198184030181529082905260c08c01516001600160e01b031960e086901b168352612e6592600401614177565b5f604051808303818588803b158015612e7c575f80fd5b505af1158015612e8e573d5f803e3d5ffd5b505050505086608001516001600160a01b03167f00000000000000000000000058daec3116aae6d93017baaea7749052e8a04fa76001600160a01b0316636352211e866040518263ffffffff1660e01b8152600401612eef91815260200190565b602060405180830381865afa158015612f0a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f2e9190614198565b6001600160a01b031614612f845760405162461bcd60e51b815260206004820152601b60248201527f466565526f757465723a207634206d696e74206d69736d6174636800000000006044820152606401610257565b5050509392505050565b806001600160a01b03811661303957478015610f82576040515f90339083908381818185875af1925050503d805f8114612fe3576040519150601f19603f3d011682016040523d82523d5f602084013e612fe8565b606091505b5050905080610f685760405162461bcd60e51b815260206004820152601c60248201527f466565526f757465723a2045544820726566756e64206661696c6564000000006044820152606401610257565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa15801561307d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a19190613ea2565b90508015610f8257610f826001600160a01b0383163383612800565b6040516001600160a01b038481166024830152838116604483015260648201839052610f689186918216906323b872dd9060840161282d565b5f61312b6001600160a01b0389167f000000000000000000000000caf681a66d020601342297493863e78c959e5cb28861354b565b5f1960ff851601613247576040805160028082526060820183525f9260208301908036833701905050905088815f8151811061316957613169613cbd565b60200260200101906001600160a01b031690816001600160a01b031681525050878160018151811061319d5761319d613cbd565b6001600160a01b03928316602091820292909201015260405163472b43f360e01b81527f000000000000000000000000caf681a66d020601342297493863e78c959e5cb29091169063472b43f3906131ff908a908a90869089906004016141b3565b6020604051808303815f875af115801561321b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061323f9190613ea2565b91505061334c565b6040805160e0810182526001600160a01b038a811682528981166020830190815262ffffff87811684860190815287841660608601908152608086018d815260a087018d81525f60c0890190815298516304e45aaf60e01b8152975187166004890152945186166024880152915190921660448601529051831660648501525160848401525160a48301529151821660c48201527f000000000000000000000000caf681a66d020601342297493863e78c959e5cb2909116906304e45aaf9060e4016020604051808303815f875af1158015613325573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133499190613ea2565b90505b979650505050505050565b5f8080808515613393576133937f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d38761213c60208b018b613850565b84156133ce576133ce7f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d38661213c60408b0160208c01613850565b6040805161016081019091526001600160a01b037f00000000000000000000000073991a25c818bf1f1128deaab1492d45638de0d316906388316456908061341960208c018c613850565b6001600160a01b031681526020018a602001602081019061343a9190613850565b6001600160a01b0316815260200161345860608c0160408d01613e43565b62ffffff16815260200161347260808c0160608d01613eb9565b60020b815260200161348a60a08c0160808d01613eb9565b60020b8152602081018a90526040810189905260e08b013560608201526101008b0135608082015260a0016134c76101408c016101208d01613850565b6001600160a01b031681526020018a61014001358152506040518263ffffffff1660e01b81526004016134fa9190613ed4565b6080604051808303815f875af1158015613516573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061353a9190613f98565b935093509350935093509350935093565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261359c8482613686565b610f68576040516001600160a01b0384811660248301525f60448301526135d091869182169063095ea7b39060640161282d565b610f6884825b5f6135ea6001600160a01b03841683613727565b905080515f1415801561360e57508080602001905181019061360c9190614225565b155b15610f8257604051635274afe760e01b81526001600160a01b0384166004820152602401610257565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f805f846001600160a01b0316846040516136a19190614008565b5f604051808303815f865af19150503d805f81146136da576040519150601f19603f3d011682016040523d82523d5f602084013e6136df565b606091505b50915091508180156137095750805115806137095750808060200190518101906137099190614225565b801561371e57505f856001600160a01b03163b115b95945050505050565b6060611fbc83835f845f80856001600160a01b0316848660405161374b9190614008565b5f6040518083038185875af1925050503d805f8114613785576040519150601f19603f3d011682016040523d82523d5f602084013e61378a565b606091505b5091509150612a428683836060826137aa576137a5826137f1565b611fbc565b81511580156137c157506001600160a01b0384163b155b156137ea57604051639996b31560e01b81526001600160a01b0385166004820152602401610257565b5080611fbc565b8051156138015780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f6020828403121561382a575f80fd5b5035919050565b6001600160a01b0381168114610fdb575f80fd5b803561179081613831565b5f60208284031215613860575f80fd5b8135611fbc81613831565b5f6101e082840312801561387d575f80fd5b509092915050565b803561ffff81168114611790575f80fd5b5f80604083850312156138a7575f80fd5b82356138b281613831565b91506138c060208401613885565b90509250929050565b5f805f805f8060c087890312156138de575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b5f60208284031215613918575f80fd5b611fbc82613885565b5f8060408385031215613932575f80fd5b823561393d81613831565b946020939093013593505050565b5f805f6060848603121561395d575f80fd5b833561396881613831565b9250602084013561397881613831565b929592945050506040919091013590565b8060020b8114610fdb575f80fd5b803561179081613989565b6001600160801b0381168114610fdb575f80fd5b8035611790816139a2565b5f8083601f8401126139d1575f80fd5b50813567ffffffffffffffff8111156139e8575f80fd5b6020830191508360208285010111156139ff575f80fd5b9250929050565b5f805f805f805f805f808a8c036101a0811215613a21575f80fd5b60a0811215613a2e575f80fd5b508a995060a08b0135613a4081613989565b985060c08b0135613a5081613989565b975060e08b013596506101008b0135613a68816139a2565b9550613a776101208c016139b6565b9450613a866101408c01613845565b93506101608b013567ffffffffffffffff811115613aa2575f80fd5b613aae8d828e016139c1565b9b9e9a9d50989b979a96999598949794969561018090950135949350505050565b5f61012082840312801561387d575f80fd5b5f8060208385031215613af2575f80fd5b823567ffffffffffffffff811115613b08575f80fd5b8301601f81018513613b18575f80fd5b803567ffffffffffffffff811115613b2e575f80fd5b85602061016083028401011115613b43575f80fd5b6020919091019590945092505050565b602080825282518282018190525f918401906040840190835b81811015613b8a578351835260209384019390920191600101613b6c565b509095945050505050565b5f61016082840312801561387d575f80fd5b805161179081613831565b62ffffff81168114610fdb575f80fd5b805161179081613bb2565b805161179081613989565b8051611790816139a2565b5f805f805f805f805f805f806101808d8f031215613bff575f80fd5b8c516bffffffffffffffffffffffff81168114613c1a575f80fd5b9b50613c2860208e01613ba7565b9a50613c3660408e01613ba7565b9950613c4460608e01613ba7565b9850613c5260808e01613bc2565b9750613c6060a08e01613bcd565b9650613c6e60c08e01613bcd565b9550613c7c60e08e01613bd8565b6101008e01516101208f015191965094509250613c9c6101408e01613bd8565b9150613cab6101608e01613bd8565b90509295989b509295989b509295989b565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611b6557611b65613cd1565b634e487b7160e01b5f52603160045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b803561179081613bb2565b5f60a0828403128015613d3c575f80fd5b5060405160a0810167ffffffffffffffff81118282101715613d6c57634e487b7160e01b5f52604160045260245ffd5b604052613d7883613845565b8152613d8660208401613845565b6020820152613d9760408401613d20565b6040820152613da860608401613997565b6060820152613db960808401613845565b60808201529392505050565b8082028115828204841417611b6557611b65613cd1565b5f82613df657634e487b7160e01b5f52601260045260245ffd5b500490565b8015158114610fdb575f80fd5b5f60208284031215613e18575f80fd5b8135611fbc81613dfb565b5f60208284031215613e33575f80fd5b813560ff81168114611fbc575f80fd5b5f60208284031215613e53575f80fd5b8135611fbc81613bb2565b60208082526024908201527f466565526f757465723a204554482073656e7420627574206e6f2057455448206040820152637369646560e01b606082015260800190565b5f60208284031215613eb2575f80fd5b5051919050565b5f60208284031215613ec9575f80fd5b8135611fbc81613989565b81516001600160a01b0316815261016081016020830151613f0060208401826001600160a01b03169052565b506040830151613f17604084018262ffffff169052565b506060830151613f2c606084018260020b9052565b506080830151613f41608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e0830152610100830151610100830152610120830151613f886101208401826001600160a01b03169052565b5061014092830151919092015290565b5f805f8060808587031215613fab575f80fd5b84516020860151909450613fbe816139a2565b6040860151606090960151949790965092505050565b5f805f60608486031215613fe6575f80fd5b8351613ff1816139a2565b602085015160409095015190969495509392505050565b5f82518060208501845e5f920191825250919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b88516001600160a01b0390811682526020808b01518216908301526040808b015162ffffff16908301526060808b015160020b908301526080808b01519091169082015261409f60a082018960020b9052565b6140ae60c082018860020b9052565b8560e08201526140ca6101008201866001600160801b03169052565b6001600160801b0384166101208201526001600160a01b0383166101408201526101806101608201525f6111d961018083018461401e565b604081525f614114604083018561401e565b828103602084015280845180835260208301915060208160051b840101602087015f5b8381101561416957601f1986840301855261415383835161401e565b6020958601959093509190910190600101614137565b509098975050505050505050565b604081525f614189604083018561401e565b90508260208301529392505050565b5f602082840312156141a8575f80fd5b8151611fbc81613831565b5f608082018683528560208401526080604084015280855180835260a0850191506020870192505f5b818110156142035783516001600160a01b03168352602093840193909201916001016141dc565b50506001600160a01b0394909416606093909301929092525090949350505050565b5f60208284031215614235575f80fd5b8151611fbc81613dfb56fe945458c62aa39df7a4d87d6c4dbaaab7de5d870c9a1fe40e2b7571d84f158a8da2646970667358221220ea9daff9b187127e739696df1f34fed2f555c7ad437231e03c00c63157fc840c64736f6c634300081a0033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| Global Dollar (USDG) | USDG | 4 | $1 | $4 |
| DIH | 1 | $0.0000102 | $0 | |
| Vladhood (VLAD) | VLAD | 80 | — | — |
| YOLO (YOLO) | YOLO | 15 | — | — |
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0xc49fb9…a5ee19 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0xb1caa0…b51c | [0] 0x000000000000…54b0dd8f [1] 0x000000000000…000589f1 data: 0x000000000000000000…00000003 |
| 0xc49fb9…a5ee19 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x945458…8a8d | [0] 0x000000000000…54b0dd8f [1] 0x000000000000…16f1d168 data: 0x000000000000000000…00000730 |
| 0x786fb0…0fb05a | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0xb1caa0…b51c | [0] 0x000000000000…54b0dd8f [1] 0x000000000000…00057585 data: 0x000000000000000000…00000003 |
| 0x786fb0…0fb05a | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x945458…8a8d | [0] 0x000000000000…54b0dd8f [1] 0x000000000000…1eacad73 data: 0x000000000000000000…d4a51000 |
| 0x407f66…804f6f | 24 days agoFri, 24 Jul 2026 07:28:17 UTC | 0xc09a87…4884 | [0] 0x000000000000…6c4c2f51 [1] 0x000000000000…1eacad73 [2] 0x000000000000…54feab71 data: 0x000000000000000000…5a694fbe |
| 0x0dd8bc…9087ea | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0xc09a87…4884 | [0] 0x000000000000…6c4c2f51 [1] 0x000000000000…1eacad73 [2] 0x000000000000…54feab71 data: 0x000000000000000000…db2df77b |
| 0x0dd8bc…9087ea | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0x945458…8a8d | [0] 0x000000000000…6c4c2f51 [1] 0x000000000000…1eacad73 data: 0x000000000000000000…7def3000 |
| 0x79b1b1…5a0870 | 24 days agoFri, 24 Jul 2026 06:40:01 UTC | 0xb1caa0…b51c | [0] 0x000000000000…f9d06b14 [1] 0x000000000000…0005722d data: 0x000000000000000000…00000003 |
| 0x7d82a5…72ce99 | 24 days agoFri, 24 Jul 2026 06:30:31 UTC | 0xb1caa0…b51c | [0] 0x000000000000…f9d06b14 [1] 0x000000000000…000571b5 data: 0x000000000000000000…00000003 |
| 0x370512…ea6e6a | 24 days agoFri, 24 Jul 2026 03:58:36 UTC | 0xb1caa0…b51c | [0] 0x000000000000…54b0dd8f [1] 0x000000000000…00056a9f data: 0x000000000000000000…00000003 |
| 0x370512…ea6e6a | 24 days agoFri, 24 Jul 2026 03:58:36 UTC | 0x945458…8a8d | [0] 0x000000000000…54b0dd8f [1] 0x000000000000…1eacad73 data: 0x000000000000000000…d4a51000 |
| 0x52248a…5910af | 25 days agoThu, 23 Jul 2026 14:01:14 UTC | 0xb1caa0…b51c | [0] 0x000000000000…57d59353 [1] 0x000000000000…0005267e data: 0x000000000000000000…00000003 |
| 0x52248a…5910af | 25 days agoThu, 23 Jul 2026 14:01:14 UTC | 0x945458…8a8d | [0] 0x000000000000…57d59353 [1] 0x000000000000…54feab71 data: 0x000000000000000000…456a8000 |
| 0x99f5ea…c07249 | 26 days agoThu, 23 Jul 2026 01:35:59 UTC | 0xb1caa0…b51c | [0] 0x000000000000…53df2630 [1] 0x000000000000…000500bf data: 0x000000000000000000…00000003 |
| 0x983ffe…e152c3 | 26 days agoWed, 22 Jul 2026 06:13:00 UTC | 0xb1caa0…b51c | [0] 0x000000000000…53df2630 [1] 0x000000000000…00049b67 data: 0x000000000000000000…00000003 |
| 0xdbc993…df0e14 | 26 days agoWed, 22 Jul 2026 06:06:07 UTC | 0xb1caa0…b51c | [0] 0x000000000000…53df2630 [1] 0x000000000000…00049b19 data: 0x000000000000000000…00000003 |
| 0x8bfb74…6b6876 | 27 days agoTue, 21 Jul 2026 22:38:26 UTC | 0xb1caa0…b51c | [0] 0x000000000000…8c321974 [1] 0x000000000000…00047901 data: 0x000000000000000000…00000003 |
| 0x2403e3…11543e | 27 days agoTue, 21 Jul 2026 20:51:44 UTC | 0xb1caa0…b51c | [0] 0x000000000000…6be12b4c [1] 0x000000000000…00046d82 data: 0x000000000000000000…00000003 |
| 0x2403e3…11543e | 27 days agoTue, 21 Jul 2026 20:51:44 UTC | 0x945458…8a8d | [0] 0x000000000000…6be12b4c [1] 0x000000000000…16f1d168 data: 0x000000000000000000…00000384 |
| 0xabcfde…1cc600 | 27 days agoTue, 21 Jul 2026 18:18:49 UTC | 0xb1caa0…b51c | [0] 0x000000000000…79b4c6f4 [1] 0x000000000000…00045a62 data: 0x000000000000000000…00000003 |
| 0xabcfde…1cc600 | 27 days agoTue, 21 Jul 2026 18:18:49 UTC | 0x945458…8a8d | [0] 0x000000000000…79b4c6f4 [1] 0x000000000000…1eacad73 data: 0x000000000000000000…316ec000 |
| 0x563b29…56222b | 27 days agoTue, 21 Jul 2026 07:01:04 UTC | 0xc09a87…4884 | [0] 0x000000000000…57d59353 [1] 0x000000000000…89197777 [2] 0x000000000000…1eacad73 data: 0x000000000000000000…eab91dd0 |
| 0x563b29…56222b | 27 days agoTue, 21 Jul 2026 07:01:04 UTC | 0x945458…8a8d | [0] 0x000000000000…57d59353 [1] 0x000000000000…89197777 data: 0x000000000000000000…f50f09f5 |
| 0x3e7c3b…71600a | 27 days agoTue, 21 Jul 2026 06:49:47 UTC | 0xc09a87…4884 | [0] 0x000000000000…57d59353 [1] 0x000000000000…1eacad73 [2] 0x000000000000…89197777 data: 0x000000000000000000…42bee527 |
| 0x3e7c3b…71600a | 27 days agoTue, 21 Jul 2026 06:49:47 UTC | 0x945458…8a8d | [0] 0x000000000000…57d59353 [1] 0x000000000000…1eacad73 data: 0x000000000000000000…6a528800 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x39cfa3a3…24c18c | Transfer | 20,027,825 | 22 days agoSun, 26 Jul 2026 16:50:58 UTC | 0x1673…13db | IN | 0x6430…7efa | 15 YOLO | YOLO (YOLO) | |
| 0xefced962…ccaf0d | Transfer | 19,847,568 | 22 days agoSun, 26 Jul 2026 11:49:50 UTC | 0xd2e4…b70c | IN | 0x6430…7efa | 2 USDG | Global Dollar (USDG) | |
| 0x31991b3d…dab966 | Transfer | 19,792,938 | 22 days agoSun, 26 Jul 2026 10:18:25 UTC | 0xcaf7…5d11 | IN | 0x6430…7efa | $0.001 DIH | ||
| 0x39d8af80…36f7b0 | Transfer | 18,304,144 | 24 days agoFri, 24 Jul 2026 16:47:53 UTC | 0xd2e4…b70c | IN | 0x6430…7efa | 2 USDG | Global Dollar (USDG) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x6430…7efa | OUT | 0x8c9e…dd8f | $0.000.000000 NVDA | NVIDIA • Robinhood Token (NVDA) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x6430…7efa | OUT | 0x8c9e…dd8f | $0.000.000096 USDG | Global Dollar (USDG) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x6430…7efa | OUT | 0xd4eb…14a3 | $1.210.005387 NVDA | NVIDIA • Robinhood Token (NVDA) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x6430…7efa | OUT | 0xd4eb…14a3 | $0.730.723776 USDG | Global Dollar (USDG) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x6430…7efa | OUT | 0xb944…7e2b | $1.121.114288 USDG | Global Dollar (USDG) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0xb944…7e2b | IN | 0x6430…7efa | $1.210.005387 NVDA | NVIDIA • Robinhood Token (NVDA) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x6430…7efa | OUT | 0x82cb…1974 | $0.000.00184 USDG | Global Dollar (USDG) | |
| 0xc49fb97f…a5ee19 | Transfer | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x8c9e…dd8f | IN | 0x6430…7efa | $1.851.84 USDG | Global Dollar (USDG) | |
| 0x786fb0fc…0fb05a | Transfer | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x6430…7efa | OUT | 0x8c9e…dd8f | $0.000.000000 SNOP | ||
| 0x786fb0fc…0fb05a | Transfer | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x6430…7efa | OUT | 0x87f5…58bc | $NaN2,697.411810 SNOP | ||
| 0x786fb0fc…0fb05a | Transfer | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x6430…7efa | OUT | 0x87f5…58bc | 0.000999 WETH | WETH (WETH) | |
| 0x786fb0fc…0fb05a | Transfer | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x87f5…58bc | IN | 0x6430…7efa | $NaN2,697.411810 SNOP | ||
| 0x786fb0fc…0fb05a | Transfer | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x6430…7efa | OUT | 0x82cb…1974 | 0.000001 WETH | WETH (WETH) | |
| 0x786fb0fc…0fb05a | Transfer | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x8c9e…dd8f | IN | 0x6430…7efa | 0.001 WETH | WETH (WETH) | |
| 0x407f6655…804f6f | Transfer | 17,969,420 | 24 days agoFri, 24 Jul 2026 07:28:17 UTC | 0x6430…7efa | OUT | 0x0c6c…5101 | 0.002 WETH | WETH (WETH) | |
| 0x407f6655…804f6f | Transfer | 17,969,420 | 24 days agoFri, 24 Jul 2026 07:28:17 UTC | 0x0000…0000 | IN | 0x6430…7efa | 0.002 WETH | WETH (WETH) | |
| 0x0dd8bcc1…9087ea | Transfer | 17,968,582 | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0x6430…7efa | OUT | 0x0c6c…5101 | 0.002997 WETH | WETH (WETH) | |
| 0x0dd8bcc1…9087ea | Transfer | 17,968,582 | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0x6430…7efa | OUT | 0x82cb…1974 | 0.000003 WETH | WETH (WETH) | |
| 0x0dd8bcc1…9087ea | Transfer | 17,968,582 | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0x0000…0000 | IN | 0x6430…7efa | 0.003 WETH | WETH (WETH) | |
| 0x562337f5…2f4cfa | Transfer | 17,943,634 | 24 days agoFri, 24 Jul 2026 06:45:09 UTC | 0xcc05…efe3 | IN | 0x6430…7efa | 40 VLAD | Vladhood (VLAD) | |
| 0xeabcefc1…7ced24 | Transfer | 17,941,425 | 24 days agoFri, 24 Jul 2026 06:41:27 UTC | 0xcc05…efe3 | IN | 0x6430…7efa | 40 VLAD | Vladhood (VLAD) |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xc49fb9…a5ee19 | zapMintV3 | 18,204,386 | 24 days agoFri, 24 Jul 2026 14:01:29 UTC | 0x8c9e…dd8f | IN | FeeRouter | $0.000 ETH | 0.00008824 | |
| 0x786fb0…0fb05a | zapMintV3 | 17,976,021 | 24 days agoFri, 24 Jul 2026 07:39:19 UTC | 0x8c9e…dd8f | IN | FeeRouter | $0.000 ETH | 0.00007797 | |
| 0x407f66…804f6f | swap | 17,969,420 | 24 days agoFri, 24 Jul 2026 07:28:17 UTC | 0x6205…2f51 | IN | FeeRouter | $3.790.002 ETH | 0.00001883 | |
| 0x0dd8bc…9087ea | swap | 17,968,582 | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0x6205…2f51 | IN | FeeRouter | $5.680.003 ETH | 0.00002572 | |
| 0x79b1b1…5a0870 | zapMintV3 | 17,940,566 | 24 days agoFri, 24 Jul 2026 06:40:01 UTC | 0x7ceb…6b14 | IN | FeeRouter | $132.540.07 ETH | 0.00006882 | |
| 0x7d82a5…72ce99 | zapMintV3 | 17,934,883 | 24 days agoFri, 24 Jul 2026 06:30:31 UTC | 0x7ceb…6b14 | IN | FeeRouter | $265.070.14 ETH | 0.00007757 | |
| 0x370512…ea6e6a | zapMintV3 | 17,844,123 | 24 days agoFri, 24 Jul 2026 03:58:36 UTC | 0x8c9e…dd8f | IN | FeeRouter | $0.000 ETH | 0.00008441 | |
| !0xdf32db…5bbb7f | zapMintV3 | 17,842,919 | 24 days agoFri, 24 Jul 2026 03:56:35 UTC | 0x8c9e…dd8f | IN | FeeRouter | $0.000 ETH | 0.00002991 | |
| 0x52248a…5910af | zapMintV3 | 17,342,971 | 25 days agoThu, 23 Jul 2026 14:01:14 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.000 ETH | 0.00006505 | |
| 0x99f5ea…c07249 | mintV3 | 16,897,036 | 26 days agoThu, 23 Jul 2026 01:35:59 UTC | sigmaprinciples.hood | IN | FeeRouter | $1.790.00094 ETH | 0.00005047 | |
| 0x983ffe…e152c3 | mintV3 | 16,200,627 | 26 days agoWed, 22 Jul 2026 06:13:00 UTC | sigmaprinciples.hood | IN | FeeRouter | $4.120.00217 ETH | 0.00003755 | |
| 0xdbc993…df0e14 | mintV3 | 16,196,511 | 26 days agoWed, 22 Jul 2026 06:06:07 UTC | sigmaprinciples.hood | IN | FeeRouter | $4.080.00215 ETH | 0.00003844 | |
| 0x8bfb74…6b6876 | mintV3 | 15,928,532 | 27 days agoTue, 21 Jul 2026 22:38:26 UTC | 0x82cb…1974 | IN | FeeRouter | $0.000 ETH | 0.00004180 | |
| 0x2403e3…11543e | zapMintV3 | 15,864,562 | 27 days agoTue, 21 Jul 2026 20:51:44 UTC | 0xec4c…2b4c | IN | FeeRouter | $0.000 ETH | 0.00003108 | |
| 0xabcfde…1cc600 | zapMintV3 | 15,772,963 | 27 days agoTue, 21 Jul 2026 18:18:49 UTC | 0x15c8…c6f4 | IN | FeeRouter | $568.020.3 ETH | 0.00004497 | |
| !0x7ccfa9…f83006 | zapMintV3 | 15,762,275 | 27 days agoTue, 21 Jul 2026 18:00:59 UTC | 0x15c8…c6f4 | IN | FeeRouter | $18.930.01 ETH | 0.00001614 | |
| 0x563b29…56222b | swap | 15,367,224 | 27 days agoTue, 21 Jul 2026 07:01:04 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.000 ETH | 0.00001927 | |
| 0x3e7c3b…71600a | swap | 15,360,467 | 27 days agoTue, 21 Jul 2026 06:49:47 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.950.0005 ETH | 0.00001622 | |
| 0x1415b1…c15b84 | mintV3 | 15,357,067 | 27 days agoTue, 21 Jul 2026 06:44:06 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.730.00038 ETH | 0.00003661 | |
| 0xb97acf…73e079 | mintV3 | 15,261,629 | 27 days agoTue, 21 Jul 2026 04:04:32 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.630.00033 ETH | 0.00003805 | |
| 0xd6dc85…b0d99a | mintV3 | 15,259,850 | 27 days agoTue, 21 Jul 2026 04:01:34 UTC | 0x4eb6…9353 | IN | FeeRouter | $1.760.00093 ETH | 0.00003601 | |
| 0x4bd22b…a87359 | mintV3 | 15,227,396 | 27 days agoTue, 21 Jul 2026 03:07:20 UTC | 0x4eb6…9353 | IN | FeeRouter | $1.890.00099 ETH | 0.00003841 | |
| 0x0da9e8…a0a17b | swap | 15,224,435 | 27 days agoTue, 21 Jul 2026 03:02:24 UTC | 0x4eb6…9353 | IN | FeeRouter | $1.040.00055 ETH | 0.00001176 | |
| 0x55459b…98c07c | swap | 15,223,582 | 27 days agoTue, 21 Jul 2026 03:00:58 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.000 ETH | 0.00002004 | |
| 0xb18fc6…8e3e9a | swap | 15,180,781 | 28 days agoTue, 21 Jul 2026 01:49:27 UTC | 0x4eb6…9353 | IN | FeeRouter | $0.570.0003 ETH | 0.00001637 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 17,969,420 | 24 days agoFri, 24 Jul 2026 07:28:17 UTC | 0x407f66…804f6f | CALL | swap | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.002 ETH |
| 17,968,582 | 24 days agoFri, 24 Jul 2026 07:26:52 UTC | 0x0dd8bc…9087ea | CALL | swap | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.003 ETH |
| 17,940,566 | 24 days agoFri, 24 Jul 2026 06:40:01 UTC | 0x79b1b1…5a0870 | CALL | zapMintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.07 ETH |
| 17,934,883 | 24 days agoFri, 24 Jul 2026 06:30:31 UTC | 0x7d82a5…72ce99 | CALL | zapMintV3 | 0x6430…7efa | OUT | 0x7ceb…6b14 | 0.00224 ETH |
| 17,934,883 | 24 days agoFri, 24 Jul 2026 06:30:31 UTC | 0x7d82a5…72ce99 | CALL | zapMintV3 | 0x0bd7…ad73 | IN | 0x6430…7efa | 0.00224 ETH |
| 17,934,883 | 24 days agoFri, 24 Jul 2026 06:30:31 UTC | 0x7d82a5…72ce99 | CALL | zapMintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.14 ETH |
| 16,897,036 | 26 days agoThu, 23 Jul 2026 01:35:59 UTC | 0x99f5ea…c07249 | CALL | mintV3 | 0x6430…7efa | OUT | sigmaprinciples.hood | 0.00002 ETH |
| 16,897,036 | 26 days agoThu, 23 Jul 2026 01:35:59 UTC | 0x99f5ea…c07249 | CALL | mintV3 | 0x0bd7…ad73 | IN | 0x6430…7efa | 0.00002 ETH |
| 16,897,036 | 26 days agoThu, 23 Jul 2026 01:35:59 UTC | 0x99f5ea…c07249 | CALL | mintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.00094 ETH |
| 16,200,627 | 26 days agoWed, 22 Jul 2026 06:13:00 UTC | 0x983ffe…e152c3 | CALL | mintV3 | 0x6430…7efa | OUT | sigmaprinciples.hood | 0.00000 ETH |
| 16,200,627 | 26 days agoWed, 22 Jul 2026 06:13:00 UTC | 0x983ffe…e152c3 | CALL | mintV3 | 0x0bd7…ad73 | IN | 0x6430…7efa | 0.00000 ETH |
| 16,200,627 | 26 days agoWed, 22 Jul 2026 06:13:00 UTC | 0x983ffe…e152c3 | CALL | mintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.00217 ETH |
| 16,196,511 | 26 days agoWed, 22 Jul 2026 06:06:07 UTC | 0xdbc993…df0e14 | CALL | mintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.00215 ETH |
| 15,772,963 | 27 days agoTue, 21 Jul 2026 18:18:49 UTC | 0xabcfde…1cc600 | CALL | zapMintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.3 ETH |
| 15,762,275 | 27 days agoTue, 21 Jul 2026 18:00:59 UTC | 0x7ccfa9…f83006 | CALL | zapMintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.01 ETH |
| 15,367,224 | 27 days agoTue, 21 Jul 2026 07:01:04 UTC | 0x563b29…56222b | CALL | swap | 0x6430…7efa | OUT | 0x4eb6…9353 | 0.00042 ETH |
| 15,367,224 | 27 days agoTue, 21 Jul 2026 07:01:04 UTC | 0x563b29…56222b | CALL | swap | 0x0bd7…ad73 | IN | 0x6430…7efa | 0.00042 ETH |
| 15,360,467 | 27 days agoTue, 21 Jul 2026 06:49:47 UTC | 0x3e7c3b…71600a | CALL | swap | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.0005 ETH |
| 15,357,067 | 27 days agoTue, 21 Jul 2026 06:44:06 UTC | 0x1415b1…c15b84 | CALL | mintV3 | 0x6430…7efa | OUT | 0x4eb6…9353 | 0.00000 ETH |
| 15,357,067 | 27 days agoTue, 21 Jul 2026 06:44:06 UTC | 0x1415b1…c15b84 | CALL | mintV3 | 0x0bd7…ad73 | IN | 0x6430…7efa | 0.00000 ETH |
| 15,357,067 | 27 days agoTue, 21 Jul 2026 06:44:06 UTC | 0x1415b1…c15b84 | CALL | mintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.00038 ETH |
| 15,261,629 | 27 days agoTue, 21 Jul 2026 04:04:32 UTC | 0xb97acf…73e079 | CALL | mintV3 | 0x6430…7efa | OUT | 0x4eb6…9353 | 0.00000 ETH |
| 15,261,629 | 27 days agoTue, 21 Jul 2026 04:04:32 UTC | 0xb97acf…73e079 | CALL | mintV3 | 0x0bd7…ad73 | IN | 0x6430…7efa | 0.00000 ETH |
| 15,261,629 | 27 days agoTue, 21 Jul 2026 04:04:32 UTC | 0xb97acf…73e079 | CALL | mintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.00033 ETH |
| 15,259,850 | 27 days agoTue, 21 Jul 2026 04:01:34 UTC | 0xd6dc85…b0d99a | CALL | mintV3 | 0x6430…7efa | OUT | 0x0bd7…ad73 | 0.00093 ETH |