// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {
IPoolManager,
IUnlockCallback,
PoolKey,
SwapParams,
V4TickMath,
BalanceDeltaLib
} from "./interfaces/IUniswapV4.sol";
import {ISignatureTransfer} from "./interfaces/IPermit2.sol";
interface IBasketToken {
function getRequiredUnits(uint256 basketAmount)
external
view
returns (address[] memory tokens, uint256[] memory amounts);
function backingOf(uint256 basketAmount) external view returns (address[] memory tokens, uint256[] memory amounts);
function mint(uint256 basketAmount, address to) external;
function redeem(uint256 basketAmount, address to) external;
}
/// @title VimenZap3 — single-transaction basket mint/redeem against Uniswap v4
/// and Rialto (PropAMM spot exchange), venue-selectable per constituent
/// @notice `zapMint`: pay one currency (USDG, or native ETH), the router buys
/// the exact constituent amounts on Uniswap v4 (exact-output, so zero
/// dust) and mints the basket to you, atomically. If any leg cannot
/// be filled, everything reverts: no partial state, ever.
/// `zapRedeem`: burn basket tokens and receive one currency back.
///
/// Trust model, same as BasketToken: no owner, no admin, no pause,
/// no upgradability, holds no funds between transactions. The swap
/// path for every constituent is chosen by the caller; the contract
/// only enforces that each path starts at the payment currency, ends
/// at the right constituent, and fills exactly.
///
/// Quoting: `quoteZapMint` / `quoteZapRedeem` execute the real swaps
/// inside a v4 unlock and revert with the amounts (the v4 Quoter
/// trick), so an `eth_call` returns the exact execution numbers with
/// no token balance needed. They are not `view` on paper, but never
/// change state when called.
interface IRialtoRegistry {
function getFeature(uint128 featureId)
external
view
returns (address previous, address current, address next, bool paused);
}
contract VimenZap3 is IUnlockCallback, ReentrancyGuard {
using SafeERC20 for IERC20;
using BalanceDeltaLib for int256;
// ---------------------------------------------------------------- errors
error Expired();
error NotPoolManager();
error LegCountMismatch();
error EmptyPath();
error PathDiscontinuous();
error PathInputMismatch(uint256 leg);
error PathOutputMismatch(uint256 leg);
error LegUnderfilled(uint256 leg);
error MaxSpendExceeded(uint256 required, uint256 maxSpend);
error MinOutNotMet(uint256 out, uint256 minOut);
error WrongMsgValue();
error NativeRefundFailed();
error UnexpectedQuoteSuccess();
error RialtoRouterPaused();
error RialtoTargetNotRouter();
error LegNotCovered(uint256 leg);
error LegDoublyCovered(uint256 leg);
error RialtoSellMismatch(uint256 leg);
error NativeNotSupported();
/// @dev Never surfaces to callers: carries quote results out of the
/// reverted unlock. `total` is spend (mint) or proceeds (redeem).
error QuoteResult(uint256 total, uint256[] perLeg);
// ---------------------------------------------------------------- events
event ZapMinted(
address indexed sender, address indexed basket, address inputCurrency, uint256 basketAmount, uint256 spent
);
event ZapRedeemed(
address indexed sender, address indexed basket, address outputCurrency, uint256 basketAmount, uint256 received
);
// ----------------------------------------------------------------- types
/// @notice One Rialto-filled constituent. `data` is the quote API's tx.data,
/// verbatim; the call target is NOT taken from the quote but always
/// resolved from Rialto's on-chain router registry, so this contract
/// can never be pointed at an arbitrary address. Approvals are exact
/// and reset to zero around the call; if the constituent balance
/// does not grow by the required amount, the whole zap reverts.
struct RialtoCall {
uint256 legIndex; // which constituent this call fills (mint) / sells (redeem)
uint256 sellAmount; // exact input from the quote (payment currency on mint, constituent on redeem)
address spender; // issues.allowance.spender from the quote
bytes data; // tx.data from the quote, unmodified
}
/// @notice One pool traversal. `zeroForOne = true` means the hop consumes
/// `key.currency0` and produces `key.currency1`.
struct Hop {
PoolKey key;
bool zeroForOne;
}
enum Action {
MINT,
REDEEM,
QUOTE_MINT,
QUOTE_REDEEM
}
/// @notice Permit2 SignatureTransfer payload: the user signs
/// (token = paymentCurrency, amount = maxSpend, spender = this
/// router) off-chain, and the approve transaction disappears.
struct Permit2Data {
uint256 nonce;
uint256 deadline;
bytes signature;
}
struct ZapData {
Action action;
address paymentCurrency; // mint: what the payer spends; redeem: what the recipient gets
address payer; // mint execution only: constituent settlement pulls from them
address recipient; // redeem execution only: receives the output currency
uint256 limit; // mint: maxSpend; redeem: minOut (ignored for quotes)
address[] tokens; // basket constituents, in basket order
uint256[] amounts; // mint: exact amounts to buy; redeem: exact amounts to sell
Hop[][] legs; // legs[i] = path for tokens[i], aligned with `tokens`
Permit2Data permit; // empty signature = classic allowance path
}
// --------------------------------------------------------------- storage
/// @dev Canonical Permit2, verified deployed on Robinhood Chain.
ISignatureTransfer public constant PERMIT2 = ISignatureTransfer(0x000000000022D473030F116dDEE9F6B43aC78BA3);
/// @dev Rialto router registry on Robinhood Chain; feature 2 is the
/// taker-submitted swap router. The active router is resolved from
/// here at execution time — never trusted from calldata.
IRialtoRegistry public constant RIALTO_REGISTRY = IRialtoRegistry(0x71a120CbBf3Ce7cD910a3c50fF77aFc62735687E);
uint128 public constant RIALTO_SWAP_FEATURE = 2;
IPoolManager public immutable poolManager;
constructor(IPoolManager poolManager_) {
poolManager = poolManager_;
}
/// @dev Accept native ETH: the PoolManager sends it here via `take` on the
/// ETH-output redeem paths, and native-ETH mints refund through here.
/// Only the PoolManager and refunds ever pay in; the contract holds no
/// ETH between transactions.
receive() external payable {}
// ------------------------------------------------------------------ mint
/// @notice Buy every constituent of `basket` for exactly `basketAmount`
/// and mint it to `to`, paying at most `maxSpend` of
/// `paymentCurrency` (address(0) = native ETH, sent as msg.value).
/// @param legs One swap path per constituent, in `constituents()` order.
/// @return spent The exact amount of `paymentCurrency` consumed.
function zapMint(
address basket,
uint256 basketAmount,
address paymentCurrency,
uint256 maxSpend,
Hop[][] calldata legs,
address to,
uint256 deadline
) external payable nonReentrant returns (uint256 spent) {
if (block.timestamp > deadline) revert Expired();
if (paymentCurrency == address(0)) {
if (msg.value != maxSpend) revert WrongMsgValue();
} else {
if (msg.value != 0) revert WrongMsgValue();
}
(address[] memory tokens, uint256[] memory required) = IBasketToken(basket).getRequiredUnits(basketAmount);
spent = _runMint(
basket,
basketAmount,
paymentCurrency,
maxSpend,
legs,
to,
tokens,
required,
Permit2Data({nonce: 0, deadline: 0, signature: ""})
);
if (paymentCurrency == address(0) && msg.value > spent) {
(bool ok,) = msg.sender.call{value: msg.value - spent}("");
if (!ok) revert NativeRefundFailed();
}
}
/// @notice `zapMint` without the approve transaction: the payer signs a
/// Permit2 SignatureTransfer for (paymentCurrency, maxSpend,
/// spender = this router) and USDG flows straight into the
/// PoolManager. One signature, one transaction, no allowance
/// left behind. Requires the once-ever ERC-20 approval of the
/// payment token to Permit2 itself.
function zapMintPermit2(
address basket,
uint256 basketAmount,
address paymentCurrency,
uint256 maxSpend,
Hop[][] calldata legs,
address to,
uint256 deadline,
Permit2Data calldata permit
) external nonReentrant returns (uint256 spent) {
if (block.timestamp > deadline) revert Expired();
if (paymentCurrency == address(0) || permit.signature.length == 0) revert WrongMsgValue();
(address[] memory tokens, uint256[] memory required) = IBasketToken(basket).getRequiredUnits(basketAmount);
spent = _runMint(basket, basketAmount, paymentCurrency, maxSpend, legs, to, tokens, required, permit);
}
function _runMint(
address basket,
uint256 basketAmount,
address paymentCurrency,
uint256 maxSpend,
Hop[][] calldata legs,
address to,
address[] memory tokens,
uint256[] memory required,
Permit2Data memory permit
) private returns (uint256 spent) {
// v1 entry points cover every leg on Uniswap; only the v2 mixed-venue
// paths (guarded by _checkCoverage) may leave a leg empty. Reject empty
// legs here so the callback's mixed-venue skip can never strand a
// constituent on a single-venue mint.
_requireAllPaths(legs);
bytes memory result = poolManager.unlock(
abi.encode(
ZapData({
action: Action.MINT,
paymentCurrency: paymentCurrency,
payer: msg.sender,
recipient: address(0),
limit: maxSpend,
tokens: tokens,
amounts: required,
legs: legs,
permit: permit
})
)
);
spent = abi.decode(result, (uint256));
// The swaps delivered the exact required amounts; the basket pulls
// them all, so allowances return to zero by construction.
for (uint256 i = 0; i < tokens.length; i++) {
IERC20(tokens[i]).forceApprove(basket, required[i]);
}
IBasketToken(basket).mint(basketAmount, to);
emit ZapMinted(msg.sender, basket, paymentCurrency, basketAmount, spent);
}
// ---------------------------------------------------------------- redeem
/// @notice Burn `basketAmount` of `basket` (caller must approve this
/// contract), sell every constituent along `legs` and send at
/// least `minOut` of `outputCurrency` to `to`.
/// @return received The exact amount of `outputCurrency` delivered.
function zapRedeem(
address basket,
uint256 basketAmount,
address outputCurrency,
uint256 minOut,
Hop[][] calldata legs,
address to,
uint256 deadline
) external nonReentrant returns (uint256 received) {
if (block.timestamp > deadline) revert Expired();
_requireAllPaths(legs); // single-venue redeem: every leg sells on Uniswap
IERC20(basket).safeTransferFrom(msg.sender, address(this), basketAmount);
(address[] memory tokens, uint256[] memory amounts) = IBasketToken(basket).backingOf(basketAmount);
IBasketToken(basket).redeem(basketAmount, address(this));
bytes memory result = poolManager.unlock(
abi.encode(
ZapData({
action: Action.REDEEM,
paymentCurrency: outputCurrency,
payer: address(0),
recipient: to,
limit: minOut,
tokens: tokens,
amounts: amounts,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
received = abi.decode(result, (uint256));
emit ZapRedeemed(msg.sender, basket, outputCurrency, basketAmount, received);
}
// ---------------------------------------------------------------- quotes
/// @notice Exact execution quote for `zapMint`, callable via eth_call.
/// @return totalIn Total `paymentCurrency` a zapMint would consume now.
/// @return legIn Per-constituent spend, aligned with `constituents()`.
function quoteZapMint(address basket, uint256 basketAmount, address paymentCurrency, Hop[][] calldata legs)
external
returns (uint256 totalIn, uint256[] memory legIn)
{
(address[] memory tokens, uint256[] memory required) = IBasketToken(basket).getRequiredUnits(basketAmount);
return _quote(
ZapData({
action: Action.QUOTE_MINT,
paymentCurrency: paymentCurrency,
payer: address(0),
recipient: address(0),
limit: type(uint256).max,
tokens: tokens,
amounts: required,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
);
}
/// @notice Exact execution quote for `zapRedeem`, callable via eth_call.
function quoteZapRedeem(address basket, uint256 basketAmount, address outputCurrency, Hop[][] calldata legs)
external
returns (uint256 totalOut, uint256[] memory legOut)
{
(address[] memory tokens, uint256[] memory amounts) = IBasketToken(basket).backingOf(basketAmount);
return _quote(
ZapData({
action: Action.QUOTE_REDEEM,
paymentCurrency: outputCurrency,
payer: address(0),
recipient: address(0),
limit: 0,
tokens: tokens,
amounts: amounts,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
);
}
function _quote(ZapData memory data) private returns (uint256, uint256[] memory) {
try poolManager.unlock(abi.encode(data)) {
revert UnexpectedQuoteSuccess();
} catch (bytes memory reason) {
if (reason.length < 4 || bytes4(reason) != QuoteResult.selector) {
// a real failure (bad path, no liquidity): bubble it up
assembly ("memory-safe") {
revert(add(reason, 0x20), mload(reason))
}
}
assembly ("memory-safe") {
// strip the 4-byte selector in place
let len := mload(reason)
reason := add(reason, 4)
mstore(reason, sub(len, 4))
}
return abi.decode(reason, (uint256, uint256[]));
}
}
// -------------------------------------------------------- mixed-venue v2
/// @notice `zapMint` with per-constituent venue choice: legs with a
/// non-empty Uniswap path fill on v4 exactly as v1; legs listed in
/// `rialtoCalls` fill on Rialto with calldata from its quote API.
/// ERC20 payment only. The whole budget (`maxSpend`) moves into
/// this contract first, both venues draw from it, and whatever is
/// left flows back to the payer in the same transaction — the
/// contract holds nothing afterwards, as always.
/// @dev Every constituent must be covered by exactly one venue. The
/// Rialto call target is always the router resolved from Rialto's
/// on-chain registry, never an address from calldata.
function zapMint2(
address basket,
uint256 basketAmount,
address paymentCurrency,
uint256 maxSpend,
Hop[][] calldata legs,
RialtoCall[] calldata rialtoCalls,
address to,
uint256 deadline,
Permit2Data calldata permit
) external nonReentrant returns (uint256 spent) {
if (block.timestamp > deadline) revert Expired();
if (paymentCurrency == address(0)) revert NativeNotSupported();
(address[] memory tokens, uint256[] memory required) = IBasketToken(basket).getRequiredUnits(basketAmount);
_checkCoverage(tokens.length, legs, rialtoCalls);
// measure the payment balance BEFORE pulling the budget, so the final
// refund returns exactly this tx's unspent amount even if someone has
// donated payment currency to the contract (no donation-driven
// under/overflow of `spent`, no accidental sweep of foreign residue).
uint256 prePay = IERC20(paymentCurrency).balanceOf(address(this));
// pull the whole budget in, from allowance or via one Permit2 signature
if (permit.signature.length > 0) {
PERMIT2.permitTransferFrom(
ISignatureTransfer.PermitTransferFrom({
permitted: ISignatureTransfer.TokenPermissions({token: paymentCurrency, amount: maxSpend}),
nonce: permit.nonce,
deadline: permit.deadline
}),
ISignatureTransfer.SignatureTransferDetails({to: address(this), requestedAmount: maxSpend}),
msg.sender,
permit.signature
);
} else {
IERC20(paymentCurrency).safeTransferFrom(msg.sender, address(this), maxSpend);
}
// Rialto legs first: plain ERC20 world, exact approvals, delta-checked
uint256 rialtoBudget = _fillOnRialto(paymentCurrency, tokens, required, rialtoCalls, maxSpend);
// Uniswap legs inside the unlock, paying from this contract's balance
uint256 uniIn = 0;
if (_hasUniswapLegs(legs)) {
bytes memory result = poolManager.unlock(
abi.encode(
ZapData({
action: Action.MINT,
paymentCurrency: paymentCurrency,
payer: address(this),
recipient: address(0),
limit: maxSpend - rialtoBudget,
tokens: tokens,
amounts: required,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
uniIn = abi.decode(result, (uint256));
}
for (uint256 i = 0; i < tokens.length; i++) {
IERC20(tokens[i]).forceApprove(basket, required[i]);
}
IBasketToken(basket).mint(basketAmount, to);
// Rialto legs are exact-input: any constituent overshoot goes to the
// recipient, and the unspent payment budget (this tx's, measured
// against the pre-pull balance) returns to the payer.
_sweepSurplus(tokens, rialtoCalls, to);
uint256 leftover = IERC20(paymentCurrency).balanceOf(address(this)) - prePay;
if (leftover > 0) IERC20(paymentCurrency).safeTransfer(msg.sender, leftover);
spent = maxSpend - leftover;
emit ZapMinted(msg.sender, basket, paymentCurrency, basketAmount, spent);
}
/// @notice `zapRedeem` with per-constituent venue choice. Constituents
/// listed in `rialtoCalls` are sold on Rialto (exact-input fits a
/// redeem natively: `sellAmount` must equal the redeemed amount);
/// the rest sell on Uniswap v4 as v1. ERC20 output only.
function zapRedeem2(
address basket,
uint256 basketAmount,
address outputCurrency,
uint256 minOut,
Hop[][] calldata legs,
RialtoCall[] calldata rialtoCalls,
address to,
uint256 deadline
) external nonReentrant returns (uint256 received) {
if (block.timestamp > deadline) revert Expired();
if (outputCurrency == address(0)) revert NativeNotSupported();
IERC20(basket).safeTransferFrom(msg.sender, address(this), basketAmount);
(address[] memory tokens, uint256[] memory amounts) = IBasketToken(basket).backingOf(basketAmount);
_checkCoverage(tokens.length, legs, rialtoCalls);
IBasketToken(basket).redeem(basketAmount, address(this));
// Rialto legs: sell the exact redeemed constituent amounts
address router = _activeRialtoRouter();
for (uint256 c = 0; c < rialtoCalls.length; c++) {
RialtoCall calldata call_ = rialtoCalls[c];
if (call_.sellAmount != amounts[call_.legIndex]) revert RialtoSellMismatch(call_.legIndex);
_rialtoSwap(router, tokens[call_.legIndex], call_);
}
if (_hasUniswapLegs(legs)) {
poolManager.unlock(
abi.encode(
ZapData({
action: Action.REDEEM,
paymentCurrency: outputCurrency,
payer: address(0),
recipient: address(this),
limit: 0, // enforced on the combined total below
tokens: tokens,
amounts: amounts,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
}
received = IERC20(outputCurrency).balanceOf(address(this));
if (received < minOut) revert MinOutNotMet(received, minOut);
IERC20(outputCurrency).safeTransfer(to, received);
// Defence-in-depth: an exact-input Rialto router should consume the
// whole approved sellAmount, but if a leg leaves constituent wei
// behind, sweep it to the recipient rather than let it strand in the
// (immutable, zero-balance-invariant) contract for the next caller.
for (uint256 i = 0; i < tokens.length; i++) {
if (tokens[i] == outputCurrency) continue; // already delivered above
uint256 dust = IERC20(tokens[i]).balanceOf(address(this));
if (dust > 0) IERC20(tokens[i]).safeTransfer(to, dust);
}
emit ZapRedeemed(msg.sender, basket, outputCurrency, basketAmount, received);
}
// ------------------------------------------------- native-ETH mixed (v3)
/// @dev Global Dollar (USDG), the intermediary currency for Rialto legs on
/// the native-ETH paths. Canonical on Robinhood Chain, verified.
address internal constant USDG = 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168;
/// @notice Mint paying native ETH, mixing Uniswap v4 and Rialto per leg.
/// Rialto only quotes USDG->stock, so the exact USDG the Rialto
/// legs need is bought first with ETH on the deep ETH/USDG pair
/// (`ethToUsdgRoute`), then spent on Rialto; the Uniswap legs are
/// paid straight in ETH. Both ETH swaps reuse the audited MINT
/// callback. Whatever ETH is left returns to the payer; the
/// contract holds nothing of this tx afterwards.
/// @dev `ethToUsdgRoute` must end at USDG (enforced by the callback's
/// path check); every constituent must be covered by exactly one
/// venue (`_checkCoverage`). Rialto call targets are always the
/// registry-resolved router, never from calldata.
function zapMintEth(
address basket,
uint256 basketAmount,
uint256 maxSpendEth,
Hop[][] calldata legs,
RialtoCall[] calldata rialtoCalls,
Hop[] calldata ethToUsdgRoute,
address to,
uint256 deadline
) external payable nonReentrant returns (uint256 spent) {
if (block.timestamp > deadline) revert Expired();
if (msg.value != maxSpendEth) revert WrongMsgValue();
(address[] memory tokens, uint256[] memory required) = IBasketToken(basket).getRequiredUnits(basketAmount);
_checkCoverage(tokens.length, legs, rialtoCalls);
// measure USDG before buying any, so a Rialto router that under-consumes
// its approved input leaves no strandable USDG (mirrors v2 zapMint2's
// payment-currency refund; keeps the zero-balance invariant intact).
uint256 preUsdg = IERC20(USDG).balanceOf(address(this));
uint256 ethSpent = 0;
// 1. Buy exactly the USDG the Rialto legs need, paying ETH, through the
// MINT callback (USDG treated as the single "constituent" to buy).
uint256 rialtoBudget = 0;
for (uint256 c = 0; c < rialtoCalls.length; c++) {
rialtoBudget += rialtoCalls[c].sellAmount;
}
if (rialtoBudget > 0) {
address[] memory usdgTok = new address[](1);
usdgTok[0] = USDG;
uint256[] memory usdgAmt = new uint256[](1);
usdgAmt[0] = rialtoBudget;
Hop[][] memory usdgLeg = new Hop[][](1);
usdgLeg[0] = ethToUsdgRoute;
bytes memory r = poolManager.unlock(
abi.encode(
ZapData({
action: Action.MINT,
paymentCurrency: address(0),
payer: address(this),
recipient: address(0),
limit: maxSpendEth,
tokens: usdgTok,
amounts: usdgAmt,
legs: usdgLeg,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
ethSpent += abi.decode(r, (uint256));
// 2. Rialto legs from the USDG just bought (approve USDG, exact,
// reset, per-leg constituent delta check — unchanged from v2).
_fillOnRialto(USDG, tokens, required, rialtoCalls, rialtoBudget);
}
// 3. Uniswap legs, paid straight in ETH, through the MINT callback.
if (_hasUniswapLegs(legs)) {
bytes memory r2 = poolManager.unlock(
abi.encode(
ZapData({
action: Action.MINT,
paymentCurrency: address(0),
payer: address(this),
recipient: address(0),
limit: maxSpendEth - ethSpent,
tokens: tokens,
amounts: required,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
ethSpent += abi.decode(r2, (uint256));
}
// 4. Mint the basket to the recipient.
for (uint256 i = 0; i < tokens.length; i++) {
IERC20(tokens[i]).forceApprove(basket, required[i]);
}
IBasketToken(basket).mint(basketAmount, to);
// 5. Constituent overshoot to the recipient; any USDG a Rialto router
// left unconsumed back to the payer; unspent ETH to the payer.
// `ethSpent` is summed from the unlock returns (not a balance diff),
// so a native donation to the contract cannot inflate the refund.
_sweepSurplus(tokens, rialtoCalls, to);
uint256 usdgLeft = IERC20(USDG).balanceOf(address(this)) - preUsdg;
if (usdgLeft > 0) IERC20(USDG).safeTransfer(msg.sender, usdgLeft);
uint256 leftover = maxSpendEth - ethSpent;
if (leftover > 0) {
(bool ok,) = msg.sender.call{value: leftover}("");
if (!ok) revert NativeRefundFailed();
}
spent = ethSpent;
emit ZapMinted(msg.sender, basket, address(0), basketAmount, spent);
}
/// @notice Redeem receiving native ETH, mixing Uniswap and Rialto per leg.
/// Rialto legs sell the constituent for USDG; the Uniswap legs sell
/// straight to ETH; the USDG from Rialto is then swapped to ETH on
/// the deep pair (`usdgToEthRoute`), and the combined ETH, floored
/// by `minOutEth`, goes to `to`.
function zapRedeemEth(
address basket,
uint256 basketAmount,
uint256 minOutEth,
Hop[][] calldata legs,
RialtoCall[] calldata rialtoCalls,
Hop[] calldata usdgToEthRoute,
address to,
uint256 deadline
) external nonReentrant returns (uint256 received) {
if (block.timestamp > deadline) revert Expired();
// isolate this tx's ETH gain from any pre-existing/donated balance
uint256 preEth = address(this).balance;
IERC20(basket).safeTransferFrom(msg.sender, address(this), basketAmount);
(address[] memory tokens, uint256[] memory amounts) = IBasketToken(basket).backingOf(basketAmount);
_checkCoverage(tokens.length, legs, rialtoCalls);
IBasketToken(basket).redeem(basketAmount, address(this));
// Rialto legs: sell the exact redeemed constituent amounts for USDG.
address router = _activeRialtoRouter();
uint256 preUsdg = IERC20(USDG).balanceOf(address(this));
for (uint256 c = 0; c < rialtoCalls.length; c++) {
RialtoCall calldata call_ = rialtoCalls[c];
if (call_.sellAmount != amounts[call_.legIndex]) revert RialtoSellMismatch(call_.legIndex);
_rialtoSwap(router, tokens[call_.legIndex], call_);
}
// Uniswap legs: sell straight to native ETH, delivered to this contract.
if (_hasUniswapLegs(legs)) {
poolManager.unlock(
abi.encode(
ZapData({
action: Action.REDEEM,
paymentCurrency: address(0),
payer: address(0),
recipient: address(this),
limit: 0,
tokens: tokens,
amounts: amounts,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
}
// Swap the USDG the Rialto legs produced (this tx only) into ETH.
uint256 usdgGained = IERC20(USDG).balanceOf(address(this)) - preUsdg;
if (usdgGained > 0) {
address[] memory usdgTok = new address[](1);
usdgTok[0] = USDG;
uint256[] memory usdgAmt = new uint256[](1);
usdgAmt[0] = usdgGained;
Hop[][] memory usdgLeg = new Hop[][](1);
usdgLeg[0] = usdgToEthRoute;
poolManager.unlock(
abi.encode(
ZapData({
action: Action.REDEEM,
paymentCurrency: address(0),
payer: address(0),
recipient: address(this),
limit: 0,
tokens: usdgTok,
amounts: usdgAmt,
legs: usdgLeg,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
)
);
}
received = address(this).balance - preEth;
if (received < minOutEth) revert MinOutNotMet(received, minOutEth);
(bool ok,) = to.call{value: received}("");
if (!ok) revert NativeRefundFailed();
// Defence-in-depth: sweep any unsold constituent wei AND any USDG the
// conversion left behind (e.g. an empty/under-consuming usdgToEthRoute)
// to the recipient, so nothing strands in the zero-balance contract.
for (uint256 i = 0; i < tokens.length; i++) {
uint256 dust = IERC20(tokens[i]).balanceOf(address(this));
if (dust > 0) IERC20(tokens[i]).safeTransfer(to, dust);
}
uint256 usdgDust = IERC20(USDG).balanceOf(address(this)) - preUsdg;
if (usdgDust > 0) IERC20(USDG).safeTransfer(to, usdgDust);
emit ZapRedeemed(msg.sender, basket, address(0), basketAmount, received);
}
/// @notice Generic exact-output quote for an arbitrary set of legs,
/// basket-free: the frontend uses it to price the Uniswap side of
/// a mixed-venue mint (Rialto legs are quoted by Rialto's API).
/// Legs with an empty path return zero. eth_call only.
function quoteLegs(
address[] calldata tokens,
uint256[] calldata amounts,
address paymentCurrency,
Hop[][] calldata legs
) external returns (uint256 totalIn, uint256[] memory legIn) {
return _quote(
ZapData({
action: Action.QUOTE_MINT,
paymentCurrency: paymentCurrency,
payer: address(0),
recipient: address(0),
limit: type(uint256).max,
tokens: tokens,
amounts: amounts,
legs: legs,
permit: Permit2Data({nonce: 0, deadline: 0, signature: ""})
})
);
}
// ---------------------------------------------------- Rialto internals
function _activeRialtoRouter() private view returns (address router) {
(, address current,, bool paused) = RIALTO_REGISTRY.getFeature(RIALTO_SWAP_FEATURE);
if (paused) revert RialtoRouterPaused();
if (current == address(0)) revert RialtoTargetNotRouter();
return current;
}
/// @dev Executes all Rialto mint legs and returns the total input budget
/// they were allowed to draw (actual spend can be lower; the router
/// refunds unspent input and the final sweep returns it to the payer).
function _fillOnRialto(
address paymentCurrency,
address[] memory tokens,
uint256[] memory required,
RialtoCall[] calldata rialtoCalls,
uint256 maxSpend
) private returns (uint256 budget) {
if (rialtoCalls.length == 0) return 0;
// the whole Rialto budget must fit under maxSpend BEFORE any call runs
for (uint256 c = 0; c < rialtoCalls.length; c++) {
budget += rialtoCalls[c].sellAmount;
}
if (budget > maxSpend) revert MaxSpendExceeded(budget, maxSpend);
address router = _activeRialtoRouter();
for (uint256 c = 0; c < rialtoCalls.length; c++) {
RialtoCall calldata call_ = rialtoCalls[c];
uint256 i = call_.legIndex;
uint256 before = IERC20(tokens[i]).balanceOf(address(this));
_rialtoApproveCallReset(router, paymentCurrency, call_);
if (IERC20(tokens[i]).balanceOf(address(this)) - before < required[i]) revert LegUnderfilled(i);
}
}
/// @dev Redeem-side single Rialto sale of a constituent.
function _rialtoSwap(address router, address sellToken, RialtoCall calldata call_) private {
_rialtoApproveCallReset(router, sellToken, call_);
}
/// @dev The Rialto integration boundary, per their executor spec: approve
/// the quoted spender for exactly `sellAmount`, execute the quote's
/// calldata against the registry-resolved router, reset the approval.
/// Any revert bubbles up untouched.
function _rialtoApproveCallReset(address router, address sellToken, RialtoCall calldata call_) private {
IERC20(sellToken).forceApprove(call_.spender, call_.sellAmount);
(bool ok, bytes memory ret) = router.call(call_.data);
if (!ok) {
assembly ("memory-safe") {
revert(add(ret, 0x20), mload(ret))
}
}
IERC20(sellToken).forceApprove(call_.spender, 0);
}
/// @dev Every leg is covered by exactly one venue: a non-empty Uniswap
/// path XOR a Rialto call.
function _checkCoverage(uint256 n, Hop[][] calldata legs, RialtoCall[] calldata rialtoCalls) private pure {
if (legs.length != n) revert LegCountMismatch();
bool[] memory rialto = new bool[](n);
for (uint256 c = 0; c < rialtoCalls.length; c++) {
uint256 i = rialtoCalls[c].legIndex;
if (i >= n || rialto[i]) revert LegDoublyCovered(i);
rialto[i] = true;
}
for (uint256 i = 0; i < n; i++) {
bool uni = legs[i].length > 0;
if (uni && rialto[i]) revert LegDoublyCovered(i);
if (!uni && !rialto[i]) revert LegNotCovered(i);
}
}
function _hasUniswapLegs(Hop[][] calldata legs) private pure returns (bool) {
for (uint256 i = 0; i < legs.length; i++) {
if (legs[i].length > 0) return true;
}
return false;
}
/// @dev Rejects any empty leg. The callback silently skips empty legs (they
/// are the Rialto-covered slots of a v2 mixed-venue zap); the v1
/// single-venue entry points call this first so a stray empty leg can
/// never reach the callback and strand an unswapped constituent.
function _requireAllPaths(Hop[][] calldata legs) private pure {
for (uint256 i = 0; i < legs.length; i++) {
if (legs[i].length == 0) revert EmptyPath();
}
}
function _sweepSurplus(address[] memory tokens, RialtoCall[] calldata rialtoCalls, address to) private {
for (uint256 c = 0; c < rialtoCalls.length; c++) {
IERC20 t = IERC20(tokens[rialtoCalls[c].legIndex]);
uint256 bal = t.balanceOf(address(this));
if (bal > 0) t.safeTransfer(to, bal);
}
}
// ------------------------------------------------------------ v4 callback
function unlockCallback(bytes calldata rawData) external returns (bytes memory) {
if (msg.sender != address(poolManager)) revert NotPoolManager();
ZapData memory data = abi.decode(rawData, (ZapData));
uint256 n = data.tokens.length;
if (data.legs.length != n) revert LegCountMismatch();
if (data.action == Action.MINT || data.action == Action.QUOTE_MINT) {
uint256 totalIn = 0;
uint256[] memory legIn = new uint256[](n);
for (uint256 i = 0; i < n; i++) {
if (data.legs[i].length == 0) continue; // leg filled on Rialto before the unlock
legIn[i] = _swapExactOut(data.legs[i], data.paymentCurrency, data.tokens[i], data.amounts[i], i);
totalIn += legIn[i];
}
if (data.action == Action.QUOTE_MINT) revert QuoteResult(totalIn, legIn);
if (totalIn > data.limit) revert MaxSpendExceeded(totalIn, data.limit);
// collect the constituents, then pay the pools once
for (uint256 i = 0; i < n; i++) {
if (data.legs[i].length == 0) continue;
poolManager.take(data.tokens[i], address(this), data.amounts[i]);
}
if (data.paymentCurrency == address(0)) {
poolManager.settle{value: totalIn}();
} else if (data.permit.signature.length > 0) {
// Permit2 path: the signed amount is maxSpend, only the
// actual cost is pulled, straight into the PoolManager
poolManager.sync(data.paymentCurrency);
PERMIT2.permitTransferFrom(
ISignatureTransfer.PermitTransferFrom({
permitted: ISignatureTransfer.TokenPermissions({
token: data.paymentCurrency, amount: data.limit
}),
nonce: data.permit.nonce,
deadline: data.permit.deadline
}),
ISignatureTransfer.SignatureTransferDetails({to: address(poolManager), requestedAmount: totalIn}),
data.payer,
data.permit.signature
);
poolManager.settle();
} else if (data.payer == address(this)) {
// v2 mixed-venue path: the payment budget already sits in this
// contract, so pay the PoolManager directly
poolManager.sync(data.paymentCurrency);
IERC20(data.paymentCurrency).safeTransfer(address(poolManager), totalIn);
poolManager.settle();
} else {
poolManager.sync(data.paymentCurrency);
IERC20(data.paymentCurrency).safeTransferFrom(data.payer, address(poolManager), totalIn);
poolManager.settle();
}
return abi.encode(totalIn);
}
// REDEEM / QUOTE_REDEEM
uint256 totalOut = 0;
uint256[] memory legOut = new uint256[](n);
for (uint256 i = 0; i < n; i++) {
if (data.legs[i].length == 0) continue; // leg sold on Rialto after the unlock
legOut[i] = _swapExactIn(data.legs[i], data.tokens[i], data.paymentCurrency, data.amounts[i], i);
totalOut += legOut[i];
}
if (data.action == Action.QUOTE_REDEEM) revert QuoteResult(totalOut, legOut);
if (totalOut < data.limit) revert MinOutNotMet(totalOut, data.limit);
for (uint256 i = 0; i < n; i++) {
if (data.legs[i].length == 0) continue;
poolManager.sync(data.tokens[i]);
IERC20(data.tokens[i]).safeTransfer(address(poolManager), data.amounts[i]);
poolManager.settle();
}
poolManager.take(data.paymentCurrency, data.recipient, totalOut);
return abi.encode(totalOut);
}
// ------------------------------------------------------------- internals
/// @dev Walks the path forward to validate it, then executes the hops in
/// reverse as chained exact-output swaps. Intermediate currencies
/// net to zero inside the unlock; the return value is the exact
/// amount of `inputCurrency` owed at the start of the path.
function _swapExactOut(
Hop[] memory hops,
address inputCurrency,
address outputToken,
uint256 amountOut,
uint256 legIndex
) private returns (uint256 amountIn) {
_validatePath(hops, inputCurrency, outputToken, legIndex);
uint256 need = amountOut;
for (uint256 j = hops.length; j > 0; j--) {
Hop memory hop = hops[j - 1];
int256 delta = poolManager.swap(
hop.key,
SwapParams({
zeroForOne: hop.zeroForOne,
amountSpecified: int256(need), // positive = exact output
sqrtPriceLimitX96: hop.zeroForOne
? V4TickMath.MIN_SQRT_PRICE_PLUS_ONE
: V4TickMath.MAX_SQRT_PRICE_MINUS_ONE
}),
""
);
int128 dOut = hop.zeroForOne ? delta.amount1() : delta.amount0();
int128 dIn = hop.zeroForOne ? delta.amount0() : delta.amount1();
// an unlimited-price exact-output swap that runs out of range
// liquidity fills partially instead of reverting: reject it
if (dOut < 0 || uint256(uint128(dOut)) != need) revert LegUnderfilled(legIndex);
need = uint256(uint128(-dIn));
}
return need;
}
/// @dev Executes the hops forward as chained exact-input swaps and
/// returns the amount of the final currency produced.
function _swapExactIn(
Hop[] memory hops,
address inputToken,
address outputCurrency,
uint256 amountIn,
uint256 legIndex
) private returns (uint256 amountOut) {
_validatePath(hops, inputToken, outputCurrency, legIndex);
uint256 carry = amountIn;
for (uint256 j = 0; j < hops.length; j++) {
Hop memory hop = hops[j];
int256 delta = poolManager.swap(
hop.key,
SwapParams({
zeroForOne: hop.zeroForOne,
amountSpecified: -int256(carry), // negative = exact input
sqrtPriceLimitX96: hop.zeroForOne
? V4TickMath.MIN_SQRT_PRICE_PLUS_ONE
: V4TickMath.MAX_SQRT_PRICE_MINUS_ONE
}),
""
);
int128 dIn = hop.zeroForOne ? delta.amount0() : delta.amount1();
int128 dOut = hop.zeroForOne ? delta.amount1() : delta.amount0();
// partial fill = pool ran dry mid-path; the leftover input would
// strand as an unresolvable delta, so reject
if (uint256(uint128(-dIn)) != carry) revert LegUnderfilled(legIndex);
carry = uint256(uint128(dOut));
}
return carry;
}
function _validatePath(Hop[] memory hops, address from, address to, uint256 legIndex) private pure {
if (hops.length == 0) revert EmptyPath();
address current = from;
for (uint256 j = 0; j < hops.length; j++) {
address hopIn = hops[j].zeroForOne ? hops[j].key.currency0 : hops[j].key.currency1;
address hopOut = hops[j].zeroForOne ? hops[j].key.currency1 : hops[j].key.currency0;
if (hopIn != current) {
if (j == 0) revert PathInputMismatch(legIndex);
revert PathDiscontinuous();
}
current = hopOut;
}
if (current != to) revert PathOutputMismatch(legIndex);
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "poolManager_",
"type": "address",
"internalType": "contract IPoolManager"
}
],
"stateMutability": "nonpayable"
},
{
"name": "EmptyPath",
"type": "error",
"inputs": []
},
{
"name": "Expired",
"type": "error",
"inputs": []
},
{
"name": "LegCountMismatch",
"type": "error",
"inputs": []
},
{
"name": "LegDoublyCovered",
"type": "error",
"inputs": [
{
"name": "leg",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "LegNotCovered",
"type": "error",
"inputs": [
{
"name": "leg",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "LegUnderfilled",
"type": "error",
"inputs": [
{
"name": "leg",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "MaxSpendExceeded",
"type": "error",
"inputs": [
{
"name": "required",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "maxSpend",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "MinOutNotMet",
"type": "error",
"inputs": [
{
"name": "out",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minOut",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "NativeNotSupported",
"type": "error",
"inputs": []
},
{
"name": "NativeRefundFailed",
"type": "error",
"inputs": []
},
{
"name": "NotPoolManager",
"type": "error",
"inputs": []
},
{
"name": "PathDiscontinuous",
"type": "error",
"inputs": []
},
{
"name": "PathInputMismatch",
"type": "error",
"inputs": [
{
"name": "leg",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "PathOutputMismatch",
"type": "error",
"inputs": [
{
"name": "leg",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "QuoteResult",
"type": "error",
"inputs": [
{
"name": "total",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "perLeg",
"type": "uint256[]",
"internalType": "uint256[]"
}
]
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "RialtoRouterPaused",
"type": "error",
"inputs": []
},
{
"name": "RialtoSellMismatch",
"type": "error",
"inputs": [
{
"name": "leg",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "RialtoTargetNotRouter",
"type": "error",
"inputs": []
},
{
"name": "SafeERC20FailedOperation",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "UnexpectedQuoteSuccess",
"type": "error",
"inputs": []
},
{
"name": "WrongMsgValue",
"type": "error",
"inputs": []
},
{
"name": "ZapMinted",
"type": "event",
"inputs": [
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "basket",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "inputCurrency",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "spent",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ZapRedeemed",
"type": "event",
"inputs": [
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "basket",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "outputCurrency",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "received",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "PERMIT2",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract ISignatureTransfer"
}
],
"stateMutability": "view"
},
{
"name": "RIALTO_REGISTRY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IRialtoRegistry"
}
],
"stateMutability": "view"
},
{
"name": "RIALTO_SWAP_FEATURE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint128",
"internalType": "uint128"
}
],
"stateMutability": "view"
},
{
"name": "poolManager",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IPoolManager"
}
],
"stateMutability": "view"
},
{
"name": "quoteLegs",
"type": "function",
"inputs": [
{
"name": "tokens",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "amounts",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "paymentCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
}
],
"outputs": [
{
"name": "totalIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legIn",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "nonpayable"
},
{
"name": "quoteZapMint",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "paymentCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
}
],
"outputs": [
{
"name": "totalIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legIn",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "nonpayable"
},
{
"name": "quoteZapRedeem",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "outputCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
}
],
"outputs": [
{
"name": "totalOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legOut",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "nonpayable"
},
{
"name": "unlockCallback",
"type": "function",
"inputs": [
{
"name": "rawData",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"stateMutability": "nonpayable"
},
{
"name": "zapMint",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "paymentCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "maxSpend",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "spent",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "zapMint2",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "paymentCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "maxSpend",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "rialtoCalls",
"type": "tuple[]",
"components": [
{
"name": "legIndex",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "sellAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct VimenZap3.RialtoCall[]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "permit",
"type": "tuple",
"components": [
{
"name": "nonce",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "signature",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct VimenZap3.Permit2Data"
}
],
"outputs": [
{
"name": "spent",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "zapMintEth",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "maxSpendEth",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "rialtoCalls",
"type": "tuple[]",
"components": [
{
"name": "legIndex",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "sellAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct VimenZap3.RialtoCall[]"
},
{
"name": "ethToUsdgRoute",
"type": "tuple[]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "spent",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "zapMintPermit2",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "paymentCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "maxSpend",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "permit",
"type": "tuple",
"components": [
{
"name": "nonce",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "signature",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct VimenZap3.Permit2Data"
}
],
"outputs": [
{
"name": "spent",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "zapRedeem",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "outputCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "minOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "received",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "zapRedeem2",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "outputCurrency",
"type": "address",
"internalType": "address"
},
{
"name": "minOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "rialtoCalls",
"type": "tuple[]",
"components": [
{
"name": "legIndex",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "sellAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct VimenZap3.RialtoCall[]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "received",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "zapRedeemEth",
"type": "function",
"inputs": [
{
"name": "basket",
"type": "address",
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minOutEth",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "legs",
"type": "tuple[][]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[][]"
},
{
"name": "rialtoCalls",
"type": "tuple[]",
"components": [
{
"name": "legIndex",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "sellAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct VimenZap3.RialtoCall[]"
},
{
"name": "usdgToEthRoute",
"type": "tuple[]",
"components": [
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "address"
}
],
"internalType": "struct PoolKey"
},
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct VimenZap3.Hop[]"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "received",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x60a0346200017457601f62005b5738819003918201601f19168301916001600160401b0383118484101762000178578084926020946040528339810103126200017457516001600160a01b0381168103620001745760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556080526040516159ca90816200018d823960805181818161011c015281816109e901528181610b2a015281816111b6015281816116d80152818161180201528181611aad015281816123bd01528181613083015281816132ac0152818161332a015281816133b40152818161341601528181613479015281816134d6015281816136f5015281816138e40152818161397c015281816139de01528181613a7001528181613b6c01528181613c1601528181613c7801528181613cba01528181613d1a01528181613d6601528181613dc801528181613e1801528181613e9901528181613f17015281816140ff015281816150d401526153e00152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe610100604052600436101561001b575b3615610019575f80fd5b005b5f803560e01c806302f7ae7814611e925780630a42b5e414611d135780630ef646c514611b9d5780631f46d64d1461192757806320bf5d2c1461130257806323a0c35d14610dc1578063387785d714610caf5780633d5ef958146104465780636afdd8501461041c5780637f594c98146102f257806391dd734614610285578063af2284371461015c578063b134e13214610140578063dc4c90d3146100fc5763fdd7a846146100cb575061000f565b346100f957806003193601126100f95760206040517371a120cbbf3ce7cd910a3c50ff77afc62735687e8152f35b80fd5b50346100f957806003193601126100f95760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100f957806003193601126100f957602060405160028152f35b50346100f95780602461016e3661266f565b92919590936001600160a01b0395869360405194859384927fffbe48420000000000000000000000000000000000000000000000000000000084526004840152165afa90811561027a57906102309392918761024098918193610254575b50604051966101da88612795565b8188528160208901526040516101ef816127e2565b8281526040890152604051986102048a6127c5565b60038a52166020890152806040890152806060890152608088015260a087015260c08601523691612b20565b60e08301526101008201526153b9565b90610250604051928392836126c5565b0390f35b90925061027391503d8084833e61026b81836127fe565b8101906128ae565b915f6101cc565b6040513d88823e3d90fd5b50346100f95760206003193601126100f95760043567ffffffffffffffff918282116100f957366023830112156100f95781600401359283116100f95736602484840101116100f9576102506102de8460248501613078565b604051918291602083526020830190612727565b50346100f95760806003193601126100f95767ffffffffffffffff6004358181116104185761032590369060040161251d565b906024358381116104145761033e90369060040161251d565b9190926103496124dd565b9460643590811161041057602094610230946103f8600298956001600160a01b03956102409b61038061040497369060040161251d565b989099826040519d8e61039281612795565b82815201528c60408051916103a6836127e2565b85835201526040519d8e6103b9816127c5565b521660208d01528060408d015260608c01527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60808c01523691612fd4565b60a0890152369161302a565b60c08601523691612b20565b8680fd5b8480fd5b8280fd5b50346100f957806003193601126100f95760206040516e22d473030f116ddee9f6b43ac78ba38152f35b50346100f957610455366125bb565b61046a9b9897959293949b9a9691999a6142db565b4211610c855747946104878b30336001600160a01b038b16614513565b604051927fffbe48420000000000000000000000000000000000000000000000000000000084528b600485015289846024816001600160a01b038c165afa938415610c7a578a6080528a94610c5a575b506104e88d82858560805151614398565b6001600160a01b0388163b15610c56576040517f7bde82f2000000000000000000000000000000000000000000000000000000008152600481018d90523060248201528a81604481836001600160a01b038e165af18015610c3757610c42575b5060209c610554615290565b906040519e8f6370a0823160e01b8152306004820152602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa60a05260a05115610c37578b9e60a051610c03575b50908b94939291855b818110610b7957505050506105b78282614ce3565b610a8d575b505050506040516370a0823160e01b8152306004820152602081602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa908115610a8257879392918b918591610a47575b509061060f916129d4565b908161088f575b5050505061062490476129d4565b9180831061085857508280808085885af161063d612ef3565b501561082e57825b6080515181101561070a578060206001600160a01b03610669602494608051612e5a565b5116604051938480926370a0823160e01b82523060048301525afa80156106ff5785906106c8575b60019250806106a2575b5001610645565b6106c290876001600160a01b036106bb85608051612e5a565b5116614f93565b5f61069b565b506020823d6020116106f7575b816106e2602093836127fe565b810103126106f35760019151610691565b5f80fd5b3d91506106d5565b6040513d87823e3d90fd5b50929093916040516370a0823160e01b8152306004820152602081602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa91821561082257916107ef575b50602095610759916129d4565b806107df575b50507f1a26248ef0da34dfaf4677bb7bd9ad9e32c5250f7c4f2ad692eb4f330a3ea2466001600160a01b03604051931692806107b0863395836040909392919360608101945f825260208201520152565b0390a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051908152f35b6107e891614ed6565b5f8061075f565b90506020813d60201161081a575b8161080a602093836127fe565b810103126106f35751602061074c565b3d91506107fd565b604051903d90823e3d90fd5b60046040517f8520d710000000000000000000000000000000000000000000000000000000008152fd5b82604491604051917f9c45586c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6109dc9392610993926109a192610908604051936108ac8561274c565b6001855260203681870137735fc5360d0400a0fd4f2af552add042d716f1d1686108d586612e20565b52604051936108e38561274c565b60018552602036818701376108f785612e20565b52610900612fa0565b923691612a2a565b61091182612e20565b5261091b81612e20565b506040519161092983612795565b86835286602084015260405161093e816127e2565b878152604084015260405193610953856127c5565b6001855287602086015287604086015230606086015287608086015260a085015260c084015260e083015261010082015260405192839160208301612ba0565b03601f1981018352826127fe565b604051809381927f48c89491000000000000000000000000000000000000000000000000000000008352602060048401526024830190612727565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af180156106ff57906106249291610a25575b85919281610616565b610a40903d8088833e610a3881836127fe565b810190612dc1565b505f610a1c565b945050506020833d602011610a7a575b81610a64602093836127fe565b810103126106f35761060f8a8894519091610604565b3d9150610a57565b6040513d89823e3d90fd5b610b1d9361099392610b036109a19360405192610aa984612795565b878452876020850152604051610abe816127e2565b888152604085015260405194610ad3866127c5565b6001865288602087015288604087015230606087015288608087015260805160a087015260c08601523691612b20565b60e083015261010082015260405192839160208301612ba0565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af18015610a8257610b5f575b8681806105bc565b610b72903d8089833e610a3881836127fe565b505f610b57565b90919293949550610b8b818386612f22565b8035610b97818a612e5a565b51602083013503610bd257600192916001600160a01b03610bbd610bc593608051612e5a565b5116866155f4565b01908c95949392916105a2565b602490604051907f619db1b40000000000000000000000000000000000000000000000000000000082526004820152fd5b909e506020813d602011610c2f575b81610c1f602093836127fe565b810103126106f357519d5f610599565b3d9150610c12565b6040513d8d823e3d90fd5b610c4c8b916127b1565b610c56575f610548565b8980fd5b610c6f9194503d808c833e61026b81836127fe565b90608052925f6104d7565b6040513d8c823e3d90fd5b60046040517f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346100f957806024610cc13661266f565b92919590936001600160a01b0395869360405194859384927fbd7b76d20000000000000000000000000000000000000000000000000000000084526004840152165afa90811561027a57906102309392918761024098918193610da3575b5060405196610d2d88612795565b818852816020890152604051610d42816127e2565b828152604089015260405198610d578a6127c5565b60028a5216602089015280604089015260608801527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608088015260a087015260c08601523691612b20565b909250610dba91503d8084833e61026b81836127fe565b915f610d1f565b50346100f9576101006003193601126100f957610ddc6124c7565b610de46124dd565b9167ffffffffffffffff906084358281116112fe57610e0790369060040161251d565b9260a43590811161041857610e2090369060040161251d565b9093610e2a6124f3565b92610e336142db565b60e4354211610c85576001600160a01b038816156112d457610e6260243530336001600160a01b038b16614513565b604051957fffbe4842000000000000000000000000000000000000000000000000000000008752602435600488015285876024816001600160a01b038c165afa93841561027a57869787956112b2575b50610ec1818386868c51614398565b6001600160a01b0389163b15610410576040517f7bde82f200000000000000000000000000000000000000000000000000000000815260248035600483015230908201528781604481836001600160a01b038f165af180156112a757908891611293575b5093929190610f32615290565b90855b818110611211575050505088610f4b8383614ce3565b61112d575b50505050506040516370a0823160e01b9586825230600483015260209182816024816001600160a01b0386165afa9081156106ff578591611100575b5060643581106110c757610faa81856001600160a01b038516614f93565b845b8651811015611074576001600160a01b0383166001600160a01b03610fd1838a612e5a565b51161461106c576001600160a01b03610fea8289612e5a565b511690848a60246040518095819382523060048301525afa8015610a8257879061103e575b6001925080611021575b505b01610fac565b61103890876001600160a01b036106bb858d612e5a565b5f611019565b508482813d8311611065575b61105481836127fe565b810103126106f3576001915161100f565b503d61104a565b60019061101b565b50604080516001600160a01b0393841681526024356020820152908101829052909187169033907f1a26248ef0da34dfaf4677bb7bd9ad9e32c5250f7c4f2ad692eb4f330a3ea2469080606081016107b0565b604490604051907f9c45586c00000000000000000000000000000000000000000000000000000000825260048201526064356024820152fd5b90508281813d8311611126575b61111781836127fe565b810103126106f357515f610f8c565b503d61110d565b6111a994610b036109a193610993956040519361114985612795565b88855288602086015260405161115e816127e2565b89815260408601526001600160a01b036040519661117b886127c5565b600188521660208701528860408701523060608701528860808701528c60a087015260c08601523691612b20565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af18015611206576111ec575b82818088610f50565b6111ff903d8085833e610a3881836127fe565b505f6111e3565b6040513d85823e3d90fd5b90919293949550611223818386612f22565b61122e813589612e5a565b516020820135036112615790611254826001600160a01b03610bbd8e6001963590612e5a565b0190889594939291610f35565b602490604051907f619db1b4000000000000000000000000000000000000000000000000000000008252356004820152fd5b61129c906127b1565b61041057865f610f25565b6040513d8a823e3d90fd5b9094506112ca9197503d8088833e61026b81836127fe565b969096935f610eb2565b60046040517f0a7287b5000000000000000000000000000000000000000000000000000000008152fd5b5080fd5b5061130c366125bb565b60c09590955292999598979691959490939192916113286142db565b4211610c85578234036118fd57604051987fbd7b76d2000000000000000000000000000000000000000000000000000000008a528760048b0152858a6024816001600160a01b038d165afa998a1561027a57869a8760e0526118de575b506113978b8b848460c0519251614398565b604051946370a0823160e01b8652306004870152602086602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa958615610a825787966118aa575b50869b9a9b978791885b8d811061187c57509082918e9493611749575b5050506114008382614ce3565b61160e575b505050835b895181101561144757806114416001600160a01b0361142b6001948e612e5a565b51168a61143a8460e051612e5a565b5191614d15565b0161140a565b508789979596976001600160a01b0387163b1561160a576040517f94bf804d000000000000000000000000000000000000000000000000000000008152600481018a90526001600160a01b0384166024820152868180604481010381836001600160a01b038d165af18015610a82579087916115f6575b505060c0516114ce939291614e17565b6040516370a0823160e01b8152306004820152602081602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa9081156115eb579086929185916115b0575b5061152a9361151e916129d4565b806115a0575b506129d4565b80611584575b50506020927fcdec7057ada93125d9ccbbcae0600d685e9cc0c663e6dc4b5e632c5a52c981096001600160a01b03604051931692806107b0863395836040909392919360608101945f825260208201520152565b81808092335af1611593612ef3565b501561082e578380611530565b6115aa9033614ed6565b87611524565b939250506020833d6020116115e3575b816115cd602093836127fe565b810103126106f35791519091859161152a611510565b3d91506115c0565b6040513d86823e3d90fd5b6115ff906127b1565b61160a57858a6114be565b8580fd5b61169088938893610b036109939461162a6116cb999d8b6129d4565b936040519361163885612795565b88855288602086015260405161164d816127e2565b898152604086015260405195611662876127c5565b898752896020880152306040880152896060880152608087015260a086015260e05160c08601523691612b20565b604051809481927f48c89491000000000000000000000000000000000000000000000000000000008352602060048401526024830190612727565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af19182156106ff57859261172d575b506020828051810103126106f357602061172492015190612f62565b935f8981611405565b6117429192503d8087833e610a3881836127fe565b905f611708565b829a506117f59450610993918a936116909261176b604051936108ac8561274c565b61177482612e20565b5261177e81612e20565b506040519161178c83612795565b8683528660208401526040516117a1816127e2565b8781526040840152604051936117b6856127c5565b8785528760208601523060408601528760608601528c608086015260a085015260c084015260e083015261010082015260405192839160208301612ba0565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1918215610a82578792611860575b506020828051810103126106f35761185760208d930151988c60c05160e051866145ca565b505f80806113f3565b6118759192503d8089833e610a3881836127fe565b905f611832565b929c6001819f9e61189e906020611896888660c051612f22565b013590612f62565b940190509d9c9d6113e0565b9095506020813d6020116118d6575b816118c6602093836127fe565b810103126106f35751945f6113d6565b3d91506118b9565b6118f3919a503d8088833e61026b81836127fe565b60e052985f611385565b60046040517f77f0f862000000000000000000000000000000000000000000000000000000008152fd5b50346100f9576119363661254e565b611942939192936142db565b4211610c85578261195489948361523b565b6119698730336001600160a01b038c16614513565b6040517fffbe484200000000000000000000000000000000000000000000000000000000815287600482015284816024816001600160a01b038d165afa9081156106ff5785908692611b80575b506001600160a01b038a163b1561160a576040517f7bde82f2000000000000000000000000000000000000000000000000000000008152600481018a90523060248201529686888c81836001600160a01b0382604481010393165af1978815610a82578998611b5d575b5093611aa097936109939693610b03936109a1976001600160a01b0360405197611a4989612795565b8c89528c60208a0152604051611a5e816127e2565b8d815260408a0152816040519a611a748c6127c5565b60018c521660208b01528c60408b0152166060890152608088015260a087015260c08601523691612b20565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1948515610822578095611b40575b50506020848051810103126106f357602093840151604080516001600160a01b03938416815280870194909452830181905292169033907f1a26248ef0da34dfaf4677bb7bd9ad9e32c5250f7c4f2ad692eb4f330a3ea2469080606081016107b0565b611b559295503d8091833e610a3881836127fe565b925f80611add565b879192949693959850611b6f906127b1565b61160a57918796939194925f611a20565b9050611b9691503d8087833e61026b81836127fe565b905f6119b6565b50611ba73661254e565b611bb9989698979594979291926142db565b4211610c85576001600160a01b03928385161597885f14611ce3578034036118fd575b878a6024604051809881937fbd7b76d200000000000000000000000000000000000000000000000000000000835260048301528b165afa9586156112a75788999a611c5999968b98611cc1575b5060405198611c378a612795565b8b8a528b60208b0152604051611c4c816127e2565b8c815260408b0152615006565b9180611cb8575b611c94575b60208260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051908152f35b808080611ca185346129d4565b335af1611cac612ef3565b501561082e575f611c65565b50813411611c60565b909750611cd99196503d808c833e61026b81836127fe565b959095965f611c29565b3415611bdc5760046040517f77f0f862000000000000000000000000000000000000000000000000000000008152fd5b50346100f957600319610100813601126112fe57611d2f6124c7565b60243591611d3b6124dd565b67ffffffffffffffff929060843584811161041057611d5e90369060040161251d565b92909160a435946001600160a01b039687871687036106f35760e435908111610c5657606081600401928236030112610c5657611d996142db565b60c4354211610c855787831615908115611e7b575b506118fd5788602497604051988980927fbd7b76d20000000000000000000000000000000000000000000000000000000082528c600483015287165afa968715611e70579189959391611e21999897959360209b978099611e4d575b5050611e17903690612e6e565b9760643592615006565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051908152f35b611e67929950611e1798503d8091833e61026b81836127fe565b9790965f611e0a565b6040513d8b823e3d90fd5b611e89915060440182612950565b9050155f611dae565b50346106f357600319610120813601126106f357611eae6124c7565b611eb66124dd565b9267ffffffffffffffff906084358281116106f357611ed990369060040161251d565b60a4969196358481116106f357611ef490369060040161251d565b949096611eff6124f3565b9161010435116106f35760609061010435360301126106f357611f206142db565b60e4354211610c85576001600160a01b038316156112d457604051947fbd7b76d200000000000000000000000000000000000000000000000000000000865260243560048701525f866024816001600160a01b038b165afa988915612443575f965f9a6124a5575b50611f97828a86848b51614398565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038a165afa9485156124435787915f9661246e575b508b878a8d611fe76044610104350161010435600401612950565b15905061244e575050505090506040516120008161274c565b6001600160a01b038716815260643560208201526040519061202182612795565b815261010435600401356020820152602461010435013560408201526040519061204a8261274c565b308252606435602083015261206b6044610104350161010435600401612950565b9290916e22d473030f116ddee9f6b43ac78ba390813b156106f3575f80946120cd92601f19601f6120e8996040519a8b998a9889967f30f28b7a00000000000000000000000000000000000000000000000000000000885260048801906129a1565b80516001600160a01b031660848701526020015160a4860152565b3360c485015261010060e48501528061010485015280610124958686013785858286010152011681010301925af1908115612443578b8a918e93612422575b508993929161213f8a925b8860643591868587614af7565b6121498588614ce3565b61232a575b505050505090505b865181101561218b57806121858b8a61143a846001600160a01b0361217d6001988f612e5a565b511693612e5a565b01612156565b508692918691896001600160a01b0386163b1561231b576040517f94bf804d0000000000000000000000000000000000000000000000000000000081526024803560048301526001600160a01b038516908201528890818180604481010381836001600160a01b038d165af1801561231f57612307575b505061220d93614e17565b6040516370a0823160e01b81523060048201526020816024816001600160a01b0388165afa94851561082257946122d1575b5061224f61225d916020956129d4565b806122b8575b6064356129d4565b917fcdec7057ada93125d9ccbbcae0600d685e9cc0c663e6dc4b5e632c5a52c981096001600160a01b03604051931692806107b086339560243590846040919493926001600160a01b03606083019616825260208201520152565b6122cc81336001600160a01b038716614f93565b612255565b93506020843d6020116122ff575b816122ec602093836127fe565b810103126106f35792519261224f61223f565b3d91506122df565b612310906127b1565b61231b578789612202565b8780fd5b6040513d84823e3d90fd5b6123b096610993956109a195612345610b03946064356129d4565b946040519561235387612795565b8a87528a6020880152604051612368816127e2565b8b815260408801526001600160a01b03604051986123858a6127c5565b8c8a521660208901523060408901528a6060890152608088015260a087015260c08601523691612b20565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af190811561027a57906020918791612408575b508051810103126106f3575f85818b878a8361214e565b61241c91503d8089833e610a3881836127fe565b5f6123f1565b9093925061213f995061243591506127b1565b5f9750908b90899088612127565b6040513d5f823e3d90fd5b61213f9061246960643530336001600160a01b038816614513565b612132565b915094506020813d60201161249d575b8161248b602093836127fe565b810103126106f357869051945f611fcc565b3d915061247e565b9099506124bd9196503d805f833e61026b81836127fe565b959095985f611f88565b600435906001600160a01b03821682036106f357565b604435906001600160a01b03821682036106f357565b60c435906001600160a01b03821682036106f357565b35906001600160a01b03821682036106f357565b9181601f840112156106f35782359167ffffffffffffffff83116106f3576020808501948460051b0101116106f357565b9060e06003198301126106f3576001600160a01b0360043581811681036106f357926024359260443583811681036106f35792606435926084359067ffffffffffffffff82116106f3576125a49160040161251d565b9290929160a43590811681036106f3579060c43590565b906101006003198301126106f3576001600160a01b039060043582811681036106f35792602435926044359267ffffffffffffffff926064358481116106f357816126089160040161251d565b949094936084358281116106f357836126239160040161251d565b9490949360a435908482116106f357806023830112156106f35781600401359485116106f357602460c08602830101116106f357602401929160c43590811681036106f3579060e43590565b60806003198201126106f3576001600160a01b039060043582811681036106f357926024359260443590811681036106f357916064359067ffffffffffffffff82116106f3576126c19160040161251d565b9091565b90604082019082526020606081936040838201528551809452019301915f5b8281106126f2575050505090565b8351855293810193928101926001016126e4565b5f5b8381106127175750505f910152565b8181015183820152602001612708565b90601f19601f60209361274581518092818752878088019101612706565b0116010190565b6040810190811067ffffffffffffffff82111761276857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6060810190811067ffffffffffffffff82111761276857604052565b67ffffffffffffffff811161276857604052565b610120810190811067ffffffffffffffff82111761276857604052565b6020810190811067ffffffffffffffff82111761276857604052565b90601f601f19910116810190811067ffffffffffffffff82111761276857604052565b67ffffffffffffffff81116127685760051b60200190565b51906001600160a01b03821682036106f357565b9080601f830112156106f35781519060209161286881612821565b9361287660405195866127fe565b81855260208086019260051b8201019283116106f357602001905b82821061289f575050505090565b81518152908301908301612891565b9190916040818403126106f35780519267ffffffffffffffff938481116106f35782019381601f860112156106f3578451946020956128ec81612821565b916128fa60405193846127fe565b818352878084019260051b820101918583116106f35788809201905b8382106129395750505050948301519081116106f357612936920161284d565b90565b82809161294584612839565b815201910190612916565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1813603018212156106f3570180359067ffffffffffffffff82116106f3576020019181360383136106f357565b60406060916129c4848251602080916001600160a01b0381511684520151910152565b6020810151828501520151910152565b919082039182116129e157565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b67ffffffffffffffff811161276857601f01601f191660200190565b929192612a3682612821565b604094612a45865192836127fe565b819584835260208093019160c08096028501948186116106f357925b858410612a715750505050505050565b838203908782126106f357835191612a888361274c565b60a08091126106f357845181810181811067ffffffffffffffff821117612768578652612ab487612509565b8152612ac1888801612509565b888201528587013562ffffff811681036106f35786820152606080880135908160020b82036106f3578201526080612afa818901612509565b9082015283528501359081151582036106f357828792838b950152815201930192612a61565b92919092612b2d84612821565b91612b3b60405193846127fe565b829480845260208094019060051b8301928284116106f35780915b848310612b6557505050505050565b823567ffffffffffffffff81116106f357820184601f820112156106f3578691612b958683858095359101612a2a565b815201920191612b56565b90602080835261014083019282516004811015612d945782820152818301516001600160a01b038091166040830152806040850151166060830152806060850151166080830152608084015160a09060a084015260a0850151946101209260c0978460c087015287518091528661016087019801915f905b828210612d7b575050505060c081015191601f1996878682030160e08701528680855192838152019401905f5b818110612d675750505060e082015197610100938887820301858801528951918282528882019089808560051b8501019c01945f935b858510612cbd57505050505050509261293696959260609592604095015193828803019101528151855280820151908501520151918160408201520190612727565b9091929394959c8b8e8e84840301875251918180845192838152019301905f905b87818310612cff5750505050806001929f0195019501939594929190612c7b565b83958560019496939551612d52838251608090816001600160a01b039182815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b015115158982015201940192018e9291612cde565b825186529488019491880191600101612c45565b835181168a529888019892880192600190910190612c18565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020818303126106f35780519067ffffffffffffffff82116106f3570181601f820112156106f3578051612df481612a0e565b92612e0260405194856127fe565b818452602082840101116106f3576129369160208085019101612706565b805115612e2d5760200190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8051821015612e2d5760209160051b010190565b91906060838203126106f35760405192612e8784612795565b8381358152602091828101358383015260408101359067ffffffffffffffff82116106f3570183601f820112156106f357803592612ec484612a0e565b94612ed260405196876127fe565b8486528185840101116106f35783604094825f940183880137850101520152565b3d15612f1d573d90612f0482612a0e565b91612f1260405193846127fe565b82523d5f602084013e565b606090565b9190811015612e2d5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81813603018212156106f3570190565b919082018092116129e157565b90612f7982612821565b612f8660405191826127fe565b828152601f19612f968294612821565b0190602036910137565b604051612fac8161274c565b60018152805f5b602080821015612fce57906060602092828501015201612fb3565b50505090565b9291612fdf82612821565b91612fed60405193846127fe565b829481845260208094019160051b81019283116106f357905b8282106130135750505050565b83809161301f84612509565b815201910190613006565b929161303582612821565b9161304360405193846127fe565b829481845260208094019160051b81019283116106f357905b8282106130695750505050565b8135815290830190830161305c565b906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633036142b15760208282810103126106f35781359167ffffffffffffffff83116106f35761012083820183830103126106f357604051926130e3846127c5565b8082013560048110156106f3578452613100602082840101612509565b6020850152613113604082840101612509565b6040850152613126606082840101612509565b60608501528181016080818101359086015260a0013567ffffffffffffffff81116106f35781830101838301601f820112156106f35761316f9084840190602081359101612fd4565b60a085015260c0818301013567ffffffffffffffff81116106f35781830101838301601f820112156106f3576131ae908484019060208135910161302a565b60c085015260e0818301013567ffffffffffffffff81116106f357838301601f82848601010112156106f3576131f1908385019083850101803590602001612b20565b60e085015261010081830101359067ffffffffffffffff82116106f35761321c938301920101612e6e565b61010082015260a081015151908160e082015151036142875780516004811015612d9457158015614273575b613858575f9161325781612f6f565b5f5b8281106135c1575082516004811015612d94576003146135875750608082015180841061355057505f5b81811061337d5750506001600160a01b0360608160208401511692015116906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163b156106f3576040517f0b0d9c090000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015291166024820152604481018290525f8180606481010381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af180156124435761336e575b50604051906020820152602081526129368161274c565b613377906127b1565b5f613357565b61338b8160e0850151612e5a565b515115613548576001600160a01b036133a88260a0860151612e5a565b51166001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163b156106f357604051907fa584119400000000000000000000000000000000000000000000000000000000825260048201525f81602481836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1801561244357613539575b5061349f6001600160a01b0361345d8360a0870151612e5a565b511661346d8360c0870151612e5a565b51906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690614f93565b6040517f11da60b40000000000000000000000000000000000000000000000000000000081526020816004815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af180156124435761350e575b506001905b01613283565b602090813d8311613532575b61352481836127fe565b810103126106f3575f613503565b503d61351a565b613542906127b1565b5f613443565b600190613508565b83604491604051917f9c45586c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b836135bd6040519283927f9d3facf9000000000000000000000000000000000000000000000000000000008452600484016126c5565b0390fd5b9491926135d58660e0839794970151612e5a565b51511561384a576135ea8660e0830151612e5a565b51926001600160a01b036136028860a0850151612e5a565b511661362c886001600160a01b036020860151166136248260c0880151612e5a565b51938861581b565b915f925b8551841015613817576136438487612e5a565b519081519060208301511515917f800000000000000000000000000000000000000000000000000000000000000082146129e1576020848101516136e894919290156137f5576001600160a01b036401000276a45b604051936136a585612795565b8452855f038585015216604083015260405194859283927ff3cd914c0000000000000000000000000000000000000000000000000000000084526004840161552c565b03815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1918215612443575f926137be575b506020613764930151151591825f146137b4578060801d600f0b925b156137a857600f0b915b6fffffffffffffffffffffffffffffffff9384916155b1565b1603613777579060019116930192613630565b60248a604051907ff380d7da0000000000000000000000000000000000000000000000000000000082526004820152fd5b60801d600f0b9161374b565b80600f0b92613741565b9291506020833d6020116137ed575b816137da602093836127fe565b810103126106f357915190916020613725565b3d91506137cd565b6001600160a01b0373fffd8963efd1fc6a506488495d951d5263988d25613698565b6138429298979491969550600193506138308886612e5a565b5261383b8785612e5a565b5190612f62565b945b01613259565b929194600190949194613844565b5f9161386381612f6f565b5f5b828110613f9e575082516004811015612d945760021461358757506080820151808411613f6757505f5b818110613e5157505060208101516001600160a01b0316806139535750506040517f11da60b4000000000000000000000000000000000000000000000000000000008152602081600481856001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af180156124435761392857505b604051906020820152602081526129368161274c565b602090813d831161394c575b61393e81836127fe565b810103126106f3575f613357565b503d613934565b610100820151604001515115613be857506001600160a01b036020820151166001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163b156106f357604051907fa584119400000000000000000000000000000000000000000000000000000000825260048201525f81602481836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1801561244357613bd9575b506001600160a01b03602082015116608082015160405191613a2c8361274c565b82526020820152610100820151602081519101519060405192613a4e84612795565b835260208301526040820152604051613a668161274c565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016815283602082015260406101006001600160a01b0382860151169401510151926e22d473030f116ddee9f6b43ac78ba390813b156106f3575f8094613b25613b0d976120cd94604051998a98899788967f30f28b7a00000000000000000000000000000000000000000000000000000000885260048801906129a1565b60c484015261010060e4840152610104830190612727565b03925af1801561244357613bca575b506040517f11da60b40000000000000000000000000000000000000000000000000000000081526020816004815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1801561244357613b9f575b50613912565b602090813d8311613bc3575b613bb581836127fe565b810103126106f3575f613b99565b503d613bab565b613bd3906127b1565b5f613b34565b613be2906127b1565b5f613a0b565b60408201516001600160a01b03163003613d5b57506001600160a01b03602082015116906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163b156106f357604051917fa584119400000000000000000000000000000000000000000000000000000000835260048301525f82602481836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af190811561244357613ce3928492613d4c575b506001600160a01b036020817f00000000000000000000000000000000000000000000000000000000000000001692015116614f93565b6040517f11da60b40000000000000000000000000000000000000000000000000000000081526020816004815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1801561244357613b9f5750613912565b613d55906127b1565b5f613cac565b906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163b156106f357604051917fa584119400000000000000000000000000000000000000000000000000000000835260048301525f82602481836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af190811561244357613ce3928492613e42575b506001600160a01b036020820151166001600160a01b036040817f0000000000000000000000000000000000000000000000000000000000000000169301511690614513565b613e4b906127b1565b5f613dfc565b613e5f8160e0850151612e5a565b515115613f5f576001600160a01b03613e7c8260a0860151612e5a565b511690613e8d8160c0860151612e5a565b51916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163b156106f3576040517f0b0d9c090000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015230602482015260448101929092525f8280606481010381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af191821561244357600192613f50575b505b0161388f565b613f59906127b1565b5f613f48565b600190613f4a565b83604491604051917fba0975e800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b93613fad8560e0860151612e5a565b51511561426a57613fc28560e0860151612e5a565b516001600160a01b03602086015116614003876001600160a01b03613feb8260a08b0151612e5a565b5116613ffb8260c08b0151612e5a565b51938561581b565b90805190815b614028575050600191614020916138308886612e5a565b945b01613865565b9091827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101116129e1576140f26140827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff850184612e5a565b516020815181830151151590815f14614248576001600160a01b036401000276a45b604051936140b185612795565b8452878585015216604083015260405194859283927ff3cd914c0000000000000000000000000000000000000000000000000000000084526004840161552c565b03815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1918215612443575f92614213575b506020015115801591906142065780600f0b915b156141fd5760801d600f0b915b5f82600f0b129182156141e0575b50506141af5761417e6fffffffffffffffffffffffffffffffff916155b1565b169180156129e1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019081614009565b602488604051907ff380d7da0000000000000000000000000000000000000000000000000000000082526004820152fd5b6fffffffffffffffffffffffffffffffff16141590505f8061415e565b600f0b91614150565b8060801d600f0b91614143565b9091506020813d602011614240575b8161422f602093836127fe565b810103126106f3575190602061412f565b3d9150614222565b6001600160a01b0373fffd8963efd1fc6a506488495d951d5263988d256140a4565b93600190614022565b5080516004811015612d9457600214613248565b60046040517f12f57b85000000000000000000000000000000000000000000000000000000008152fd5b60046040517fae18210a000000000000000000000000000000000000000000000000000000008152fd5b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00600281541461430b5760029055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b9190811015612e2d5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1813603018212156106f357019081359167ffffffffffffffff83116106f35760200160c08302360381136106f3579190565b929190838203614287576143ab84612821565b926040956143bc60405195866127fe565b858552601f196143cb87612821565b013660208701375f5b8181106144a0575050505f5b8481106143ef57505050505050565b6143fa818484614335565b90501580158061448d575b61445d578061444b575b61441b576001016143e0565b6024908651907f82a23f720000000000000000000000000000000000000000000000000000000082526004820152fd5b506144568185612e5a565b511561440f565b6024828851907f5a3569f80000000000000000000000000000000000000000000000000000000082526004820152fd5b506144988286612e5a565b511515614405565b6144ab818385612f22565b35878110801590614500575b6144d0579060016144c9819389612e5a565b52016143d4565b6024908951907f5a3569f80000000000000000000000000000000000000000000000000000000082526004820152fd5b5061450b8188612e5a565b5115156144b7565b9092604051937f23b872dd000000000000000000000000000000000000000000000000000000005f526001600160a01b0393848092166004521660245260445260205f60648180855af160015f51148116156145ab575b836040525f6060521561457c57505050565b602493507f5274afe7000000000000000000000000000000000000000000000000000000008352166004820152fd5b60018115166145c157813b15153d15161661456a565b833d5f823e3d90fd5b929493945f958115614aed575f5b828110614ad25750808711614a9b57506145f0615290565b905f5b81811061460257505050505050565b61460d818387612f22565b6001600160a01b03614620823589612e5a565b511690604051916370a0823160e01b835282602081600493308583015260249687915afa908115612443575f91614a69575b5061465f604084016155e0565b6020840135604051917f095ea7b3000000000000000000000000000000000000000000000000000000005f526001600160a01b0381169283865282885260205f60448180735fc5360d0400a0fd4f2af552add042d716f1d1685af19060015f5114821615614a46575b6040521561491c575b5050505f806146e36060860186612950565b9081604051928392833781018381520390828b5af1614700612ef3565b901561491457508390614715604085016155e0565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000005f526001600160a01b03821685525f845260205f60448180735fc5360d0400a0fd4f2af552add042d716f1d1685af19060015f51148216156148f1575b60405215614844575b5060206001600160a01b0361479586358e612e5a565b5116604051938480926370a0823160e01b825230888301525afa8015612443575f90614810575b6147c692506129d4565b6147d1833589612e5a565b51116147e2575050506001016145f3565b604051917ff380d7da0000000000000000000000000000000000000000000000000000000083523590820152fd5b506020823d60201161483c575b8161482a602093836127fe565b810103126106f3576147c691516147bc565b3d915061481d565b90915061485081615740565b156148ae5761485e90615740565b1561486b5783905f61477f565b8382735fc5360d0400a0fd4f2af552add042d716f1d168604051917f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b8483735fc5360d0400a0fd4f2af552add042d716f1d168604051917f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b90735fc5360d0400a0fd4f2af552add042d716f1d1683b15153d15161690614776565b602081519101fd5b61492590615740565b15614a0357604051917f095ea7b3000000000000000000000000000000000000000000000000000000005f528452855260205f60448180735fc5360d0400a0fd4f2af552add042d716f1d1685af160015f51148116156149d0575b81604052156149905780806146d1565b80735fc5360d0400a0fd4f2af552add042d716f1d168847f5274afe700000000000000000000000000000000000000000000000000000000889452820152fd5b60018115166149fa57735fc5360d0400a0fd4f2af552add042d716f1d1683b15153d151616614980565b503d5f823e3d90fd5b8584735fc5360d0400a0fd4f2af552add042d716f1d168604051917f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b90735fc5360d0400a0fd4f2af552add042d716f1d1683b15153d151616906146c8565b90506020813d602011614a93575b81614a84602093836127fe565b810103126106f357515f614652565b3d9150614a77565b86604491604051917fba0975e800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b96614ae660019160206118968b878a612f22565b97016145d8565b505f955050505050565b919092939594955f968115614cd8575f5b828110614cbd5750808811614c865750614b20615290565b905f5b818110614b335750505050505050565b614b3e818389612f22565b6001600160a01b03614b51823589612e5a565b51166040516370a0823160e01b815260208160248160049530878301525afa8015612443575f90614c53575b60249150614b8c848a896155f4565b60206001600160a01b03614ba186358d612e5a565b5116604051938480926370a0823160e01b825230888301525afa8015612443575f90614c1f575b614bd292506129d4565b614bdd833588612e5a565b5111614bed575050600101614b23565b60249250604051917ff380d7da0000000000000000000000000000000000000000000000000000000083523590820152fd5b506020823d602011614c4b575b81614c39602093836127fe565b810103126106f357614bd29151614bc8565b3d9150614c2c565b506020813d602011614c7e575b81614c6d602093836127fe565b810103126106f35760249051614b7d565b3d9150614c60565b87604491604051917fba0975e800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b97614cd160019160206118968c878c612f22565b9801614b08565b505f96505050505050565b905f5b818110614cf4575050505f90565b614cff818385614335565b9050614d0d57600101614ce6565b505050600190565b604051927f095ea7b30000000000000000000000000000000000000000000000000000000093845f526001600160a01b039384811691826004528360245260205f60448180895af19060015f5114821615614e08575b60405215614d7c575b505050505050565b614d8690846157c5565b15614dd557604051945f5260045260245260205f60448180855af160015f5114811615614dbf575b836040521561457c57808080614d74565b60018115166145c157813b15153d151616614dae565b60248385604051917f5274afe7000000000000000000000000000000000000000000000000000000008352166004820152fd5b90853b15153d15161690614d6b565b90915f5b818110614e29575050505050565b6001600160a01b03614e46614e3f838588612f22565b3585612e5a565b5116906040918251926370a0823160e01b845230600485015260208085602481865afa918215614ecd57505f91614e9e575b50600193508781614e8d575b50505001614e1b565b614e9692614f93565b5f8087614e84565b905083813d8311614ec6575b614eb481836127fe565b810103126106f357600192515f614e78565b503d614eaa565b513d5f823e3d90fd5b906001600160a01b03604051927fa9059cbb000000000000000000000000000000000000000000000000000000005f5216600452602452735fc5360d0400a0fd4f2af552add042d716f1d16860205f60448180855af160015f5114811615614f74575b8260405215614f46575050565b602492507f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b6001811516614f8a57813b15153d151616614f39565b823d5f823e3d90fd5b604051927fa9059cbb000000000000000000000000000000000000000000000000000000005f526001600160a01b0380931660045260245260205f60448180855af160015f5114811615614ff0575b836040521561457c57505050565b60018115166145c157813b15153d151616614fe2565b9799939695929094986150198a8961523b565b6001600160a01b039760409a8b5193615031856127c5565b5f85528a86166020860152338d860152606085015f905260808501528860a08501528c60c0850152369061506492612b20565b60e083015261010082015288518091602082019061508191612ba0565b03601f198101825261509390826127fe565b885180917f48c894910000000000000000000000000000000000000000000000000000000082526004820160209052602482016150cf91612727565b0381887f00000000000000000000000000000000000000000000000000000000000000001691815a5f948591f1908115615231575f91615217575b506020818051810103126106f35760200151935f5b8651811015615145578061513f8c8b61143a848d61217d6001988f612e5a565b0161511f565b509450949196929750941693843b156106f35781517f94bf804d000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039190911660248201525f8160448183895af1801561520d5787927fcdec7057ada93125d9ccbbcae0600d685e9cc0c663e6dc4b5e632c5a52c9810994926151f9926151fe575b50519283923396846040919493926001600160a01b03606083019616825260208201520152565b0390a3565b615207906127b1565b5f6151d2565b82513d5f823e3d90fd5b61522b91503d805f833e610a3881836127fe565b5f61510a565b89513d5f823e3d90fd5b91905f5b81811061524c5750509050565b615257818386614335565b9050156152665760010161523f565b60046040517f20a2d33d000000000000000000000000000000000000000000000000000000008152fd5b6040517f46df01a4000000000000000000000000000000000000000000000000000000008152600260048201526080816024817371a120cbbf3ce7cd910a3c50ff77afc62735687e5afa8015612443575f915f91615354575b5061532a576001600160a01b038116156153005790565b60046040517ff5e001a5000000000000000000000000000000000000000000000000000000008152fd5b60046040517f3ef98287000000000000000000000000000000000000000000000000000000008152fd5b9150506080813d6080116153b1575b81615370608093836127fe565b810103126106f35761538181612839565b50606061539060208301612839565b9161539d60408201612839565b5001519081151582036106f357905f6152e9565b3d9150615363565b5f6109936109a16153d39360405192839160208301612ba0565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af19081615512575b506154e857615416612ef3565b908151600481108015615475575b61546f57604060031991828101600486015284019184830301126106f35760248301519260448101519167ffffffffffffffff83116106f3576129369260206024920192010161284d565b60208301fd5b7f9d3facf900000000000000000000000000000000000000000000000000000000906020850151907fffffffff000000000000000000000000000000000000000000000000000000008281809416926154d3575b5050161415615424565b908092508560040360031b1b1616815f6154c9565b60046040517fc8539a6c000000000000000000000000000000000000000000000000000000008152fd5b615525903d805f833e610a3881836127fe565b505f615409565b905f906001600160a01b036040610140956155888661012095608090816001600160a01b039182815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051151560a0870152602081015160c087015201511660e0840152806101008401528201520190565b600f0b7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081146129e1575f0390565b356001600160a01b03811681036106f35790565b906001600160a01b03809116925f80604094816156308786019561562661561a886155e0565b6020830135908c614d15565b6060810190612950565b91908289519384928337810182815203925af161564b612ef3565b9015614914575061565b906155e0565b908251907f095ea7b3000000000000000000000000000000000000000000000000000000005f5282166004525f60245260205f60448180885af19060015f5114821615615731575b8352156156af57505050565b6156b981846157c5565b15615701576156c890836157c5565b156156d1575050565b6024925051907f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b6024838351907f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b90843b15153d151616906156a3565b906001600160a01b03604051927f095ea7b3000000000000000000000000000000000000000000000000000000005f52166004525f602452735fc5360d0400a0fd4f2af552add042d716f1d1689160205f60448180875af19260015f51148416156157ac575b50604052565b600184929415166145c1573b15153d151616915f6157a6565b91906001600160a01b03604051917f095ea7b3000000000000000000000000000000000000000000000000000000005f52166004525f60245260205f60448180875af19260015f51148416156157ac5750604052565b909391929381511561526657915f925b8251841015615948576020806158418686612e5a565b5101511561592a576001600160a01b0361585b8686612e5a565b51515116905b8061586c8787612e5a565b5101511561590d576001600160a01b03906158878787612e5a565b5151015116915b6001600160a01b038091169116036158ab5760019093019261582b565b8584156158dc5760046040517f54b3e62a000000000000000000000000000000000000000000000000000000008152fd5b602490604051907fd1619a200000000000000000000000000000000000000000000000000000000082526004820152fd5b506001600160a01b036159208686612e5a565b515151169161588e565b6001600160a01b038161593d8787612e5a565b515101511690615861565b9250939290506001600160a01b038091169116036159635750565b602490604051907f6b52ffce0000000000000000000000000000000000000000000000000000000082526004820152fdfea26469706673582212206c2e0e78ff567a32e6fb3a6c3bdd53eef8d41e61740e2ba75c4e21d33605fbbe64736f6c634300081800330000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951
0x610100604052600436101561001b575b3615610019575f80fd5b005b5f803560e01c806302f7ae7814611e925780630a42b5e414611d135780630ef646c514611b9d5780631f46d64d1461192757806320bf5d2c1461130257806323a0c35d14610dc1578063387785d714610caf5780633d5ef958146104465780636afdd8501461041c5780637f594c98146102f257806391dd734614610285578063af2284371461015c578063b134e13214610140578063dc4c90d3146100fc5763fdd7a846146100cb575061000f565b346100f957806003193601126100f95760206040517371a120cbbf3ce7cd910a3c50ff77afc62735687e8152f35b80fd5b50346100f957806003193601126100f95760206040516001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951168152f35b50346100f957806003193601126100f957602060405160028152f35b50346100f95780602461016e3661266f565b92919590936001600160a01b0395869360405194859384927fffbe48420000000000000000000000000000000000000000000000000000000084526004840152165afa90811561027a57906102309392918761024098918193610254575b50604051966101da88612795565b8188528160208901526040516101ef816127e2565b8281526040890152604051986102048a6127c5565b60038a52166020890152806040890152806060890152608088015260a087015260c08601523691612b20565b60e08301526101008201526153b9565b90610250604051928392836126c5565b0390f35b90925061027391503d8084833e61026b81836127fe565b8101906128ae565b915f6101cc565b6040513d88823e3d90fd5b50346100f95760206003193601126100f95760043567ffffffffffffffff918282116100f957366023830112156100f95781600401359283116100f95736602484840101116100f9576102506102de8460248501613078565b604051918291602083526020830190612727565b50346100f95760806003193601126100f95767ffffffffffffffff6004358181116104185761032590369060040161251d565b906024358381116104145761033e90369060040161251d565b9190926103496124dd565b9460643590811161041057602094610230946103f8600298956001600160a01b03956102409b61038061040497369060040161251d565b989099826040519d8e61039281612795565b82815201528c60408051916103a6836127e2565b85835201526040519d8e6103b9816127c5565b521660208d01528060408d015260608c01527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60808c01523691612fd4565b60a0890152369161302a565b60c08601523691612b20565b8680fd5b8480fd5b8280fd5b50346100f957806003193601126100f95760206040516e22d473030f116ddee9f6b43ac78ba38152f35b50346100f957610455366125bb565b61046a9b9897959293949b9a9691999a6142db565b4211610c855747946104878b30336001600160a01b038b16614513565b604051927fffbe48420000000000000000000000000000000000000000000000000000000084528b600485015289846024816001600160a01b038c165afa938415610c7a578a6080528a94610c5a575b506104e88d82858560805151614398565b6001600160a01b0388163b15610c56576040517f7bde82f2000000000000000000000000000000000000000000000000000000008152600481018d90523060248201528a81604481836001600160a01b038e165af18015610c3757610c42575b5060209c610554615290565b906040519e8f6370a0823160e01b8152306004820152602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa60a05260a05115610c37578b9e60a051610c03575b50908b94939291855b818110610b7957505050506105b78282614ce3565b610a8d575b505050506040516370a0823160e01b8152306004820152602081602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa908115610a8257879392918b918591610a47575b509061060f916129d4565b908161088f575b5050505061062490476129d4565b9180831061085857508280808085885af161063d612ef3565b501561082e57825b6080515181101561070a578060206001600160a01b03610669602494608051612e5a565b5116604051938480926370a0823160e01b82523060048301525afa80156106ff5785906106c8575b60019250806106a2575b5001610645565b6106c290876001600160a01b036106bb85608051612e5a565b5116614f93565b5f61069b565b506020823d6020116106f7575b816106e2602093836127fe565b810103126106f35760019151610691565b5f80fd5b3d91506106d5565b6040513d87823e3d90fd5b50929093916040516370a0823160e01b8152306004820152602081602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa91821561082257916107ef575b50602095610759916129d4565b806107df575b50507f1a26248ef0da34dfaf4677bb7bd9ad9e32c5250f7c4f2ad692eb4f330a3ea2466001600160a01b03604051931692806107b0863395836040909392919360608101945f825260208201520152565b0390a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051908152f35b6107e891614ed6565b5f8061075f565b90506020813d60201161081a575b8161080a602093836127fe565b810103126106f35751602061074c565b3d91506107fd565b604051903d90823e3d90fd5b60046040517f8520d710000000000000000000000000000000000000000000000000000000008152fd5b82604491604051917f9c45586c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6109dc9392610993926109a192610908604051936108ac8561274c565b6001855260203681870137735fc5360d0400a0fd4f2af552add042d716f1d1686108d586612e20565b52604051936108e38561274c565b60018552602036818701376108f785612e20565b52610900612fa0565b923691612a2a565b61091182612e20565b5261091b81612e20565b506040519161092983612795565b86835286602084015260405161093e816127e2565b878152604084015260405193610953856127c5565b6001855287602086015287604086015230606086015287608086015260a085015260c084015260e083015261010082015260405192839160208301612ba0565b03601f1981018352826127fe565b604051809381927f48c89491000000000000000000000000000000000000000000000000000000008352602060048401526024830190612727565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af180156106ff57906106249291610a25575b85919281610616565b610a40903d8088833e610a3881836127fe565b810190612dc1565b505f610a1c565b945050506020833d602011610a7a575b81610a64602093836127fe565b810103126106f35761060f8a8894519091610604565b3d9150610a57565b6040513d89823e3d90fd5b610b1d9361099392610b036109a19360405192610aa984612795565b878452876020850152604051610abe816127e2565b888152604085015260405194610ad3866127c5565b6001865288602087015288604087015230606087015288608087015260805160a087015260c08601523691612b20565b60e083015261010082015260405192839160208301612ba0565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af18015610a8257610b5f575b8681806105bc565b610b72903d8089833e610a3881836127fe565b505f610b57565b90919293949550610b8b818386612f22565b8035610b97818a612e5a565b51602083013503610bd257600192916001600160a01b03610bbd610bc593608051612e5a565b5116866155f4565b01908c95949392916105a2565b602490604051907f619db1b40000000000000000000000000000000000000000000000000000000082526004820152fd5b909e506020813d602011610c2f575b81610c1f602093836127fe565b810103126106f357519d5f610599565b3d9150610c12565b6040513d8d823e3d90fd5b610c4c8b916127b1565b610c56575f610548565b8980fd5b610c6f9194503d808c833e61026b81836127fe565b90608052925f6104d7565b6040513d8c823e3d90fd5b60046040517f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346100f957806024610cc13661266f565b92919590936001600160a01b0395869360405194859384927fbd7b76d20000000000000000000000000000000000000000000000000000000084526004840152165afa90811561027a57906102309392918761024098918193610da3575b5060405196610d2d88612795565b818852816020890152604051610d42816127e2565b828152604089015260405198610d578a6127c5565b60028a5216602089015280604089015260608801527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608088015260a087015260c08601523691612b20565b909250610dba91503d8084833e61026b81836127fe565b915f610d1f565b50346100f9576101006003193601126100f957610ddc6124c7565b610de46124dd565b9167ffffffffffffffff906084358281116112fe57610e0790369060040161251d565b9260a43590811161041857610e2090369060040161251d565b9093610e2a6124f3565b92610e336142db565b60e4354211610c85576001600160a01b038816156112d457610e6260243530336001600160a01b038b16614513565b604051957fffbe4842000000000000000000000000000000000000000000000000000000008752602435600488015285876024816001600160a01b038c165afa93841561027a57869787956112b2575b50610ec1818386868c51614398565b6001600160a01b0389163b15610410576040517f7bde82f200000000000000000000000000000000000000000000000000000000815260248035600483015230908201528781604481836001600160a01b038f165af180156112a757908891611293575b5093929190610f32615290565b90855b818110611211575050505088610f4b8383614ce3565b61112d575b50505050506040516370a0823160e01b9586825230600483015260209182816024816001600160a01b0386165afa9081156106ff578591611100575b5060643581106110c757610faa81856001600160a01b038516614f93565b845b8651811015611074576001600160a01b0383166001600160a01b03610fd1838a612e5a565b51161461106c576001600160a01b03610fea8289612e5a565b511690848a60246040518095819382523060048301525afa8015610a8257879061103e575b6001925080611021575b505b01610fac565b61103890876001600160a01b036106bb858d612e5a565b5f611019565b508482813d8311611065575b61105481836127fe565b810103126106f3576001915161100f565b503d61104a565b60019061101b565b50604080516001600160a01b0393841681526024356020820152908101829052909187169033907f1a26248ef0da34dfaf4677bb7bd9ad9e32c5250f7c4f2ad692eb4f330a3ea2469080606081016107b0565b604490604051907f9c45586c00000000000000000000000000000000000000000000000000000000825260048201526064356024820152fd5b90508281813d8311611126575b61111781836127fe565b810103126106f357515f610f8c565b503d61110d565b6111a994610b036109a193610993956040519361114985612795565b88855288602086015260405161115e816127e2565b89815260408601526001600160a01b036040519661117b886127c5565b600188521660208701528860408701523060608701528860808701528c60a087015260c08601523691612b20565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af18015611206576111ec575b82818088610f50565b6111ff903d8085833e610a3881836127fe565b505f6111e3565b6040513d85823e3d90fd5b90919293949550611223818386612f22565b61122e813589612e5a565b516020820135036112615790611254826001600160a01b03610bbd8e6001963590612e5a565b0190889594939291610f35565b602490604051907f619db1b4000000000000000000000000000000000000000000000000000000008252356004820152fd5b61129c906127b1565b61041057865f610f25565b6040513d8a823e3d90fd5b9094506112ca9197503d8088833e61026b81836127fe565b969096935f610eb2565b60046040517f0a7287b5000000000000000000000000000000000000000000000000000000008152fd5b5080fd5b5061130c366125bb565b60c09590955292999598979691959490939192916113286142db565b4211610c85578234036118fd57604051987fbd7b76d2000000000000000000000000000000000000000000000000000000008a528760048b0152858a6024816001600160a01b038d165afa998a1561027a57869a8760e0526118de575b506113978b8b848460c0519251614398565b604051946370a0823160e01b8652306004870152602086602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa958615610a825787966118aa575b50869b9a9b978791885b8d811061187c57509082918e9493611749575b5050506114008382614ce3565b61160e575b505050835b895181101561144757806114416001600160a01b0361142b6001948e612e5a565b51168a61143a8460e051612e5a565b5191614d15565b0161140a565b508789979596976001600160a01b0387163b1561160a576040517f94bf804d000000000000000000000000000000000000000000000000000000008152600481018a90526001600160a01b0384166024820152868180604481010381836001600160a01b038d165af18015610a82579087916115f6575b505060c0516114ce939291614e17565b6040516370a0823160e01b8152306004820152602081602481735fc5360d0400a0fd4f2af552add042d716f1d1685afa9081156115eb579086929185916115b0575b5061152a9361151e916129d4565b806115a0575b506129d4565b80611584575b50506020927fcdec7057ada93125d9ccbbcae0600d685e9cc0c663e6dc4b5e632c5a52c981096001600160a01b03604051931692806107b0863395836040909392919360608101945f825260208201520152565b81808092335af1611593612ef3565b501561082e578380611530565b6115aa9033614ed6565b87611524565b939250506020833d6020116115e3575b816115cd602093836127fe565b810103126106f35791519091859161152a611510565b3d91506115c0565b6040513d86823e3d90fd5b6115ff906127b1565b61160a57858a6114be565b8580fd5b61169088938893610b036109939461162a6116cb999d8b6129d4565b936040519361163885612795565b88855288602086015260405161164d816127e2565b898152604086015260405195611662876127c5565b898752896020880152306040880152896060880152608087015260a086015260e05160c08601523691612b20565b604051809481927f48c89491000000000000000000000000000000000000000000000000000000008352602060048401526024830190612727565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af19182156106ff57859261172d575b506020828051810103126106f357602061172492015190612f62565b935f8981611405565b6117429192503d8087833e610a3881836127fe565b905f611708565b829a506117f59450610993918a936116909261176b604051936108ac8561274c565b61177482612e20565b5261177e81612e20565b506040519161178c83612795565b8683528660208401526040516117a1816127e2565b8781526040840152604051936117b6856127c5565b8785528760208601523060408601528760608601528c608086015260a085015260c084015260e083015261010082015260405192839160208301612ba0565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1918215610a82578792611860575b506020828051810103126106f35761185760208d930151988c60c05160e051866145ca565b505f80806113f3565b6118759192503d8089833e610a3881836127fe565b905f611832565b929c6001819f9e61189e906020611896888660c051612f22565b013590612f62565b940190509d9c9d6113e0565b9095506020813d6020116118d6575b816118c6602093836127fe565b810103126106f35751945f6113d6565b3d91506118b9565b6118f3919a503d8088833e61026b81836127fe565b60e052985f611385565b60046040517f77f0f862000000000000000000000000000000000000000000000000000000008152fd5b50346100f9576119363661254e565b611942939192936142db565b4211610c85578261195489948361523b565b6119698730336001600160a01b038c16614513565b6040517fffbe484200000000000000000000000000000000000000000000000000000000815287600482015284816024816001600160a01b038d165afa9081156106ff5785908692611b80575b506001600160a01b038a163b1561160a576040517f7bde82f2000000000000000000000000000000000000000000000000000000008152600481018a90523060248201529686888c81836001600160a01b0382604481010393165af1978815610a82578998611b5d575b5093611aa097936109939693610b03936109a1976001600160a01b0360405197611a4989612795565b8c89528c60208a0152604051611a5e816127e2565b8d815260408a0152816040519a611a748c6127c5565b60018c521660208b01528c60408b0152166060890152608088015260a087015260c08601523691612b20565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1948515610822578095611b40575b50506020848051810103126106f357602093840151604080516001600160a01b03938416815280870194909452830181905292169033907f1a26248ef0da34dfaf4677bb7bd9ad9e32c5250f7c4f2ad692eb4f330a3ea2469080606081016107b0565b611b559295503d8091833e610a3881836127fe565b925f80611add565b879192949693959850611b6f906127b1565b61160a57918796939194925f611a20565b9050611b9691503d8087833e61026b81836127fe565b905f6119b6565b50611ba73661254e565b611bb9989698979594979291926142db565b4211610c85576001600160a01b03928385161597885f14611ce3578034036118fd575b878a6024604051809881937fbd7b76d200000000000000000000000000000000000000000000000000000000835260048301528b165afa9586156112a75788999a611c5999968b98611cc1575b5060405198611c378a612795565b8b8a528b60208b0152604051611c4c816127e2565b8c815260408b0152615006565b9180611cb8575b611c94575b60208260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051908152f35b808080611ca185346129d4565b335af1611cac612ef3565b501561082e575f611c65565b50813411611c60565b909750611cd99196503d808c833e61026b81836127fe565b959095965f611c29565b3415611bdc5760046040517f77f0f862000000000000000000000000000000000000000000000000000000008152fd5b50346100f957600319610100813601126112fe57611d2f6124c7565b60243591611d3b6124dd565b67ffffffffffffffff929060843584811161041057611d5e90369060040161251d565b92909160a435946001600160a01b039687871687036106f35760e435908111610c5657606081600401928236030112610c5657611d996142db565b60c4354211610c855787831615908115611e7b575b506118fd5788602497604051988980927fbd7b76d20000000000000000000000000000000000000000000000000000000082528c600483015287165afa968715611e70579189959391611e21999897959360209b978099611e4d575b5050611e17903690612e6e565b9760643592615006565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051908152f35b611e67929950611e1798503d8091833e61026b81836127fe565b9790965f611e0a565b6040513d8b823e3d90fd5b611e89915060440182612950565b9050155f611dae565b50346106f357600319610120813601126106f357611eae6124c7565b611eb66124dd565b9267ffffffffffffffff906084358281116106f357611ed990369060040161251d565b60a4969196358481116106f357611ef490369060040161251d565b949096611eff6124f3565b9161010435116106f35760609061010435360301126106f357611f206142db565b60e4354211610c85576001600160a01b038316156112d457604051947fbd7b76d200000000000000000000000000000000000000000000000000000000865260243560048701525f866024816001600160a01b038b165afa988915612443575f965f9a6124a5575b50611f97828a86848b51614398565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038a165afa9485156124435787915f9661246e575b508b878a8d611fe76044610104350161010435600401612950565b15905061244e575050505090506040516120008161274c565b6001600160a01b038716815260643560208201526040519061202182612795565b815261010435600401356020820152602461010435013560408201526040519061204a8261274c565b308252606435602083015261206b6044610104350161010435600401612950565b9290916e22d473030f116ddee9f6b43ac78ba390813b156106f3575f80946120cd92601f19601f6120e8996040519a8b998a9889967f30f28b7a00000000000000000000000000000000000000000000000000000000885260048801906129a1565b80516001600160a01b031660848701526020015160a4860152565b3360c485015261010060e48501528061010485015280610124958686013785858286010152011681010301925af1908115612443578b8a918e93612422575b508993929161213f8a925b8860643591868587614af7565b6121498588614ce3565b61232a575b505050505090505b865181101561218b57806121858b8a61143a846001600160a01b0361217d6001988f612e5a565b511693612e5a565b01612156565b508692918691896001600160a01b0386163b1561231b576040517f94bf804d0000000000000000000000000000000000000000000000000000000081526024803560048301526001600160a01b038516908201528890818180604481010381836001600160a01b038d165af1801561231f57612307575b505061220d93614e17565b6040516370a0823160e01b81523060048201526020816024816001600160a01b0388165afa94851561082257946122d1575b5061224f61225d916020956129d4565b806122b8575b6064356129d4565b917fcdec7057ada93125d9ccbbcae0600d685e9cc0c663e6dc4b5e632c5a52c981096001600160a01b03604051931692806107b086339560243590846040919493926001600160a01b03606083019616825260208201520152565b6122cc81336001600160a01b038716614f93565b612255565b93506020843d6020116122ff575b816122ec602093836127fe565b810103126106f35792519261224f61223f565b3d91506122df565b612310906127b1565b61231b578789612202565b8780fd5b6040513d84823e3d90fd5b6123b096610993956109a195612345610b03946064356129d4565b946040519561235387612795565b8a87528a6020880152604051612368816127e2565b8b815260408801526001600160a01b03604051986123858a6127c5565b8c8a521660208901523060408901528a6060890152608088015260a087015260c08601523691612b20565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af190811561027a57906020918791612408575b508051810103126106f3575f85818b878a8361214e565b61241c91503d8089833e610a3881836127fe565b5f6123f1565b9093925061213f995061243591506127b1565b5f9750908b90899088612127565b6040513d5f823e3d90fd5b61213f9061246960643530336001600160a01b038816614513565b612132565b915094506020813d60201161249d575b8161248b602093836127fe565b810103126106f357869051945f611fcc565b3d915061247e565b9099506124bd9196503d805f833e61026b81836127fe565b959095985f611f88565b600435906001600160a01b03821682036106f357565b604435906001600160a01b03821682036106f357565b60c435906001600160a01b03821682036106f357565b35906001600160a01b03821682036106f357565b9181601f840112156106f35782359167ffffffffffffffff83116106f3576020808501948460051b0101116106f357565b9060e06003198301126106f3576001600160a01b0360043581811681036106f357926024359260443583811681036106f35792606435926084359067ffffffffffffffff82116106f3576125a49160040161251d565b9290929160a43590811681036106f3579060c43590565b906101006003198301126106f3576001600160a01b039060043582811681036106f35792602435926044359267ffffffffffffffff926064358481116106f357816126089160040161251d565b949094936084358281116106f357836126239160040161251d565b9490949360a435908482116106f357806023830112156106f35781600401359485116106f357602460c08602830101116106f357602401929160c43590811681036106f3579060e43590565b60806003198201126106f3576001600160a01b039060043582811681036106f357926024359260443590811681036106f357916064359067ffffffffffffffff82116106f3576126c19160040161251d565b9091565b90604082019082526020606081936040838201528551809452019301915f5b8281106126f2575050505090565b8351855293810193928101926001016126e4565b5f5b8381106127175750505f910152565b8181015183820152602001612708565b90601f19601f60209361274581518092818752878088019101612706565b0116010190565b6040810190811067ffffffffffffffff82111761276857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6060810190811067ffffffffffffffff82111761276857604052565b67ffffffffffffffff811161276857604052565b610120810190811067ffffffffffffffff82111761276857604052565b6020810190811067ffffffffffffffff82111761276857604052565b90601f601f19910116810190811067ffffffffffffffff82111761276857604052565b67ffffffffffffffff81116127685760051b60200190565b51906001600160a01b03821682036106f357565b9080601f830112156106f35781519060209161286881612821565b9361287660405195866127fe565b81855260208086019260051b8201019283116106f357602001905b82821061289f575050505090565b81518152908301908301612891565b9190916040818403126106f35780519267ffffffffffffffff938481116106f35782019381601f860112156106f3578451946020956128ec81612821565b916128fa60405193846127fe565b818352878084019260051b820101918583116106f35788809201905b8382106129395750505050948301519081116106f357612936920161284d565b90565b82809161294584612839565b815201910190612916565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1813603018212156106f3570180359067ffffffffffffffff82116106f3576020019181360383136106f357565b60406060916129c4848251602080916001600160a01b0381511684520151910152565b6020810151828501520151910152565b919082039182116129e157565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b67ffffffffffffffff811161276857601f01601f191660200190565b929192612a3682612821565b604094612a45865192836127fe565b819584835260208093019160c08096028501948186116106f357925b858410612a715750505050505050565b838203908782126106f357835191612a888361274c565b60a08091126106f357845181810181811067ffffffffffffffff821117612768578652612ab487612509565b8152612ac1888801612509565b888201528587013562ffffff811681036106f35786820152606080880135908160020b82036106f3578201526080612afa818901612509565b9082015283528501359081151582036106f357828792838b950152815201930192612a61565b92919092612b2d84612821565b91612b3b60405193846127fe565b829480845260208094019060051b8301928284116106f35780915b848310612b6557505050505050565b823567ffffffffffffffff81116106f357820184601f820112156106f3578691612b958683858095359101612a2a565b815201920191612b56565b90602080835261014083019282516004811015612d945782820152818301516001600160a01b038091166040830152806040850151166060830152806060850151166080830152608084015160a09060a084015260a0850151946101209260c0978460c087015287518091528661016087019801915f905b828210612d7b575050505060c081015191601f1996878682030160e08701528680855192838152019401905f5b818110612d675750505060e082015197610100938887820301858801528951918282528882019089808560051b8501019c01945f935b858510612cbd57505050505050509261293696959260609592604095015193828803019101528151855280820151908501520151918160408201520190612727565b9091929394959c8b8e8e84840301875251918180845192838152019301905f905b87818310612cff5750505050806001929f0195019501939594929190612c7b565b83958560019496939551612d52838251608090816001600160a01b039182815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b015115158982015201940192018e9291612cde565b825186529488019491880191600101612c45565b835181168a529888019892880192600190910190612c18565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020818303126106f35780519067ffffffffffffffff82116106f3570181601f820112156106f3578051612df481612a0e565b92612e0260405194856127fe565b818452602082840101116106f3576129369160208085019101612706565b805115612e2d5760200190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8051821015612e2d5760209160051b010190565b91906060838203126106f35760405192612e8784612795565b8381358152602091828101358383015260408101359067ffffffffffffffff82116106f3570183601f820112156106f357803592612ec484612a0e565b94612ed260405196876127fe565b8486528185840101116106f35783604094825f940183880137850101520152565b3d15612f1d573d90612f0482612a0e565b91612f1260405193846127fe565b82523d5f602084013e565b606090565b9190811015612e2d5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81813603018212156106f3570190565b919082018092116129e157565b90612f7982612821565b612f8660405191826127fe565b828152601f19612f968294612821565b0190602036910137565b604051612fac8161274c565b60018152805f5b602080821015612fce57906060602092828501015201612fb3565b50505090565b9291612fdf82612821565b91612fed60405193846127fe565b829481845260208094019160051b81019283116106f357905b8282106130135750505050565b83809161301f84612509565b815201910190613006565b929161303582612821565b9161304360405193846127fe565b829481845260208094019160051b81019283116106f357905b8282106130695750505050565b8135815290830190830161305c565b906001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409511633036142b15760208282810103126106f35781359167ffffffffffffffff83116106f35761012083820183830103126106f357604051926130e3846127c5565b8082013560048110156106f3578452613100602082840101612509565b6020850152613113604082840101612509565b6040850152613126606082840101612509565b60608501528181016080818101359086015260a0013567ffffffffffffffff81116106f35781830101838301601f820112156106f35761316f9084840190602081359101612fd4565b60a085015260c0818301013567ffffffffffffffff81116106f35781830101838301601f820112156106f3576131ae908484019060208135910161302a565b60c085015260e0818301013567ffffffffffffffff81116106f357838301601f82848601010112156106f3576131f1908385019083850101803590602001612b20565b60e085015261010081830101359067ffffffffffffffff82116106f35761321c938301920101612e6e565b61010082015260a081015151908160e082015151036142875780516004811015612d9457158015614273575b613858575f9161325781612f6f565b5f5b8281106135c1575082516004811015612d94576003146135875750608082015180841061355057505f5b81811061337d5750506001600160a01b0360608160208401511692015116906001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951163b156106f3576040517f0b0d9c090000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015291166024820152604481018290525f8180606481010381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af180156124435761336e575b50604051906020820152602081526129368161274c565b613377906127b1565b5f613357565b61338b8160e0850151612e5a565b515115613548576001600160a01b036133a88260a0860151612e5a565b51166001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951163b156106f357604051907fa584119400000000000000000000000000000000000000000000000000000000825260048201525f81602481836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1801561244357613539575b5061349f6001600160a01b0361345d8360a0870151612e5a565b511661346d8360c0870151612e5a565b51906001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409511690614f93565b6040517f11da60b40000000000000000000000000000000000000000000000000000000081526020816004815f6001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af180156124435761350e575b506001905b01613283565b602090813d8311613532575b61352481836127fe565b810103126106f3575f613503565b503d61351a565b613542906127b1565b5f613443565b600190613508565b83604491604051917f9c45586c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b836135bd6040519283927f9d3facf9000000000000000000000000000000000000000000000000000000008452600484016126c5565b0390fd5b9491926135d58660e0839794970151612e5a565b51511561384a576135ea8660e0830151612e5a565b51926001600160a01b036136028860a0850151612e5a565b511661362c886001600160a01b036020860151166136248260c0880151612e5a565b51938861581b565b915f925b8551841015613817576136438487612e5a565b519081519060208301511515917f800000000000000000000000000000000000000000000000000000000000000082146129e1576020848101516136e894919290156137f5576001600160a01b036401000276a45b604051936136a585612795565b8452855f038585015216604083015260405194859283927ff3cd914c0000000000000000000000000000000000000000000000000000000084526004840161552c565b03815f6001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1918215612443575f926137be575b506020613764930151151591825f146137b4578060801d600f0b925b156137a857600f0b915b6fffffffffffffffffffffffffffffffff9384916155b1565b1603613777579060019116930192613630565b60248a604051907ff380d7da0000000000000000000000000000000000000000000000000000000082526004820152fd5b60801d600f0b9161374b565b80600f0b92613741565b9291506020833d6020116137ed575b816137da602093836127fe565b810103126106f357915190916020613725565b3d91506137cd565b6001600160a01b0373fffd8963efd1fc6a506488495d951d5263988d25613698565b6138429298979491969550600193506138308886612e5a565b5261383b8785612e5a565b5190612f62565b945b01613259565b929194600190949194613844565b5f9161386381612f6f565b5f5b828110613f9e575082516004811015612d945760021461358757506080820151808411613f6757505f5b818110613e5157505060208101516001600160a01b0316806139535750506040517f11da60b4000000000000000000000000000000000000000000000000000000008152602081600481856001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af180156124435761392857505b604051906020820152602081526129368161274c565b602090813d831161394c575b61393e81836127fe565b810103126106f3575f613357565b503d613934565b610100820151604001515115613be857506001600160a01b036020820151166001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951163b156106f357604051907fa584119400000000000000000000000000000000000000000000000000000000825260048201525f81602481836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1801561244357613bd9575b506001600160a01b03602082015116608082015160405191613a2c8361274c565b82526020820152610100820151602081519101519060405192613a4e84612795565b835260208301526040820152604051613a668161274c565b6001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e4095116815283602082015260406101006001600160a01b0382860151169401510151926e22d473030f116ddee9f6b43ac78ba390813b156106f3575f8094613b25613b0d976120cd94604051998a98899788967f30f28b7a00000000000000000000000000000000000000000000000000000000885260048801906129a1565b60c484015261010060e4840152610104830190612727565b03925af1801561244357613bca575b506040517f11da60b40000000000000000000000000000000000000000000000000000000081526020816004815f6001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1801561244357613b9f575b50613912565b602090813d8311613bc3575b613bb581836127fe565b810103126106f3575f613b99565b503d613bab565b613bd3906127b1565b5f613b34565b613be2906127b1565b5f613a0b565b60408201516001600160a01b03163003613d5b57506001600160a01b03602082015116906001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951163b156106f357604051917fa584119400000000000000000000000000000000000000000000000000000000835260048301525f82602481836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af190811561244357613ce3928492613d4c575b506001600160a01b036020817f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409511692015116614f93565b6040517f11da60b40000000000000000000000000000000000000000000000000000000081526020816004815f6001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1801561244357613b9f5750613912565b613d55906127b1565b5f613cac565b906001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951163b156106f357604051917fa584119400000000000000000000000000000000000000000000000000000000835260048301525f82602481836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af190811561244357613ce3928492613e42575b506001600160a01b036020820151166001600160a01b036040817f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951169301511690614513565b613e4b906127b1565b5f613dfc565b613e5f8160e0850151612e5a565b515115613f5f576001600160a01b03613e7c8260a0860151612e5a565b511690613e8d8160c0860151612e5a565b51916001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951163b156106f3576040517f0b0d9c090000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015230602482015260448101929092525f8280606481010381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af191821561244357600192613f50575b505b0161388f565b613f59906127b1565b5f613f48565b600190613f4a565b83604491604051917fba0975e800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b93613fad8560e0860151612e5a565b51511561426a57613fc28560e0860151612e5a565b516001600160a01b03602086015116614003876001600160a01b03613feb8260a08b0151612e5a565b5116613ffb8260c08b0151612e5a565b51938561581b565b90805190815b614028575050600191614020916138308886612e5a565b945b01613865565b9091827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101116129e1576140f26140827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff850184612e5a565b516020815181830151151590815f14614248576001600160a01b036401000276a45b604051936140b185612795565b8452878585015216604083015260405194859283927ff3cd914c0000000000000000000000000000000000000000000000000000000084526004840161552c565b03815f6001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af1918215612443575f92614213575b506020015115801591906142065780600f0b915b156141fd5760801d600f0b915b5f82600f0b129182156141e0575b50506141af5761417e6fffffffffffffffffffffffffffffffff916155b1565b169180156129e1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019081614009565b602488604051907ff380d7da0000000000000000000000000000000000000000000000000000000082526004820152fd5b6fffffffffffffffffffffffffffffffff16141590505f8061415e565b600f0b91614150565b8060801d600f0b91614143565b9091506020813d602011614240575b8161422f602093836127fe565b810103126106f3575190602061412f565b3d9150614222565b6001600160a01b0373fffd8963efd1fc6a506488495d951d5263988d256140a4565b93600190614022565b5080516004811015612d9457600214613248565b60046040517f12f57b85000000000000000000000000000000000000000000000000000000008152fd5b60046040517fae18210a000000000000000000000000000000000000000000000000000000008152fd5b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00600281541461430b5760029055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b9190811015612e2d5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1813603018212156106f357019081359167ffffffffffffffff83116106f35760200160c08302360381136106f3579190565b929190838203614287576143ab84612821565b926040956143bc60405195866127fe565b858552601f196143cb87612821565b013660208701375f5b8181106144a0575050505f5b8481106143ef57505050505050565b6143fa818484614335565b90501580158061448d575b61445d578061444b575b61441b576001016143e0565b6024908651907f82a23f720000000000000000000000000000000000000000000000000000000082526004820152fd5b506144568185612e5a565b511561440f565b6024828851907f5a3569f80000000000000000000000000000000000000000000000000000000082526004820152fd5b506144988286612e5a565b511515614405565b6144ab818385612f22565b35878110801590614500575b6144d0579060016144c9819389612e5a565b52016143d4565b6024908951907f5a3569f80000000000000000000000000000000000000000000000000000000082526004820152fd5b5061450b8188612e5a565b5115156144b7565b9092604051937f23b872dd000000000000000000000000000000000000000000000000000000005f526001600160a01b0393848092166004521660245260445260205f60648180855af160015f51148116156145ab575b836040525f6060521561457c57505050565b602493507f5274afe7000000000000000000000000000000000000000000000000000000008352166004820152fd5b60018115166145c157813b15153d15161661456a565b833d5f823e3d90fd5b929493945f958115614aed575f5b828110614ad25750808711614a9b57506145f0615290565b905f5b81811061460257505050505050565b61460d818387612f22565b6001600160a01b03614620823589612e5a565b511690604051916370a0823160e01b835282602081600493308583015260249687915afa908115612443575f91614a69575b5061465f604084016155e0565b6020840135604051917f095ea7b3000000000000000000000000000000000000000000000000000000005f526001600160a01b0381169283865282885260205f60448180735fc5360d0400a0fd4f2af552add042d716f1d1685af19060015f5114821615614a46575b6040521561491c575b5050505f806146e36060860186612950565b9081604051928392833781018381520390828b5af1614700612ef3565b901561491457508390614715604085016155e0565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000005f526001600160a01b03821685525f845260205f60448180735fc5360d0400a0fd4f2af552add042d716f1d1685af19060015f51148216156148f1575b60405215614844575b5060206001600160a01b0361479586358e612e5a565b5116604051938480926370a0823160e01b825230888301525afa8015612443575f90614810575b6147c692506129d4565b6147d1833589612e5a565b51116147e2575050506001016145f3565b604051917ff380d7da0000000000000000000000000000000000000000000000000000000083523590820152fd5b506020823d60201161483c575b8161482a602093836127fe565b810103126106f3576147c691516147bc565b3d915061481d565b90915061485081615740565b156148ae5761485e90615740565b1561486b5783905f61477f565b8382735fc5360d0400a0fd4f2af552add042d716f1d168604051917f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b8483735fc5360d0400a0fd4f2af552add042d716f1d168604051917f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b90735fc5360d0400a0fd4f2af552add042d716f1d1683b15153d15161690614776565b602081519101fd5b61492590615740565b15614a0357604051917f095ea7b3000000000000000000000000000000000000000000000000000000005f528452855260205f60448180735fc5360d0400a0fd4f2af552add042d716f1d1685af160015f51148116156149d0575b81604052156149905780806146d1565b80735fc5360d0400a0fd4f2af552add042d716f1d168847f5274afe700000000000000000000000000000000000000000000000000000000889452820152fd5b60018115166149fa57735fc5360d0400a0fd4f2af552add042d716f1d1683b15153d151616614980565b503d5f823e3d90fd5b8584735fc5360d0400a0fd4f2af552add042d716f1d168604051917f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b90735fc5360d0400a0fd4f2af552add042d716f1d1683b15153d151616906146c8565b90506020813d602011614a93575b81614a84602093836127fe565b810103126106f357515f614652565b3d9150614a77565b86604491604051917fba0975e800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b96614ae660019160206118968b878a612f22565b97016145d8565b505f955050505050565b919092939594955f968115614cd8575f5b828110614cbd5750808811614c865750614b20615290565b905f5b818110614b335750505050505050565b614b3e818389612f22565b6001600160a01b03614b51823589612e5a565b51166040516370a0823160e01b815260208160248160049530878301525afa8015612443575f90614c53575b60249150614b8c848a896155f4565b60206001600160a01b03614ba186358d612e5a565b5116604051938480926370a0823160e01b825230888301525afa8015612443575f90614c1f575b614bd292506129d4565b614bdd833588612e5a565b5111614bed575050600101614b23565b60249250604051917ff380d7da0000000000000000000000000000000000000000000000000000000083523590820152fd5b506020823d602011614c4b575b81614c39602093836127fe565b810103126106f357614bd29151614bc8565b3d9150614c2c565b506020813d602011614c7e575b81614c6d602093836127fe565b810103126106f35760249051614b7d565b3d9150614c60565b87604491604051917fba0975e800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b97614cd160019160206118968c878c612f22565b9801614b08565b505f96505050505050565b905f5b818110614cf4575050505f90565b614cff818385614335565b9050614d0d57600101614ce6565b505050600190565b604051927f095ea7b30000000000000000000000000000000000000000000000000000000093845f526001600160a01b039384811691826004528360245260205f60448180895af19060015f5114821615614e08575b60405215614d7c575b505050505050565b614d8690846157c5565b15614dd557604051945f5260045260245260205f60448180855af160015f5114811615614dbf575b836040521561457c57808080614d74565b60018115166145c157813b15153d151616614dae565b60248385604051917f5274afe7000000000000000000000000000000000000000000000000000000008352166004820152fd5b90853b15153d15161690614d6b565b90915f5b818110614e29575050505050565b6001600160a01b03614e46614e3f838588612f22565b3585612e5a565b5116906040918251926370a0823160e01b845230600485015260208085602481865afa918215614ecd57505f91614e9e575b50600193508781614e8d575b50505001614e1b565b614e9692614f93565b5f8087614e84565b905083813d8311614ec6575b614eb481836127fe565b810103126106f357600192515f614e78565b503d614eaa565b513d5f823e3d90fd5b906001600160a01b03604051927fa9059cbb000000000000000000000000000000000000000000000000000000005f5216600452602452735fc5360d0400a0fd4f2af552add042d716f1d16860205f60448180855af160015f5114811615614f74575b8260405215614f46575050565b602492507f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b6001811516614f8a57813b15153d151616614f39565b823d5f823e3d90fd5b604051927fa9059cbb000000000000000000000000000000000000000000000000000000005f526001600160a01b0380931660045260245260205f60448180855af160015f5114811615614ff0575b836040521561457c57505050565b60018115166145c157813b15153d151616614fe2565b9799939695929094986150198a8961523b565b6001600160a01b039760409a8b5193615031856127c5565b5f85528a86166020860152338d860152606085015f905260808501528860a08501528c60c0850152369061506492612b20565b60e083015261010082015288518091602082019061508191612ba0565b03601f198101825261509390826127fe565b885180917f48c894910000000000000000000000000000000000000000000000000000000082526004820160209052602482016150cf91612727565b0381887f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409511691815a5f948591f1908115615231575f91615217575b506020818051810103126106f35760200151935f5b8651811015615145578061513f8c8b61143a848d61217d6001988f612e5a565b0161511f565b509450949196929750941693843b156106f35781517f94bf804d000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039190911660248201525f8160448183895af1801561520d5787927fcdec7057ada93125d9ccbbcae0600d685e9cc0c663e6dc4b5e632c5a52c9810994926151f9926151fe575b50519283923396846040919493926001600160a01b03606083019616825260208201520152565b0390a3565b615207906127b1565b5f6151d2565b82513d5f823e3d90fd5b61522b91503d805f833e610a3881836127fe565b5f61510a565b89513d5f823e3d90fd5b91905f5b81811061524c5750509050565b615257818386614335565b9050156152665760010161523f565b60046040517f20a2d33d000000000000000000000000000000000000000000000000000000008152fd5b6040517f46df01a4000000000000000000000000000000000000000000000000000000008152600260048201526080816024817371a120cbbf3ce7cd910a3c50ff77afc62735687e5afa8015612443575f915f91615354575b5061532a576001600160a01b038116156153005790565b60046040517ff5e001a5000000000000000000000000000000000000000000000000000000008152fd5b60046040517f3ef98287000000000000000000000000000000000000000000000000000000008152fd5b9150506080813d6080116153b1575b81615370608093836127fe565b810103126106f35761538181612839565b50606061539060208301612839565b9161539d60408201612839565b5001519081151582036106f357905f6152e9565b3d9150615363565b5f6109936109a16153d39360405192839160208301612ba0565b0381836001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951165af19081615512575b506154e857615416612ef3565b908151600481108015615475575b61546f57604060031991828101600486015284019184830301126106f35760248301519260448101519167ffffffffffffffff83116106f3576129369260206024920192010161284d565b60208301fd5b7f9d3facf900000000000000000000000000000000000000000000000000000000906020850151907fffffffff000000000000000000000000000000000000000000000000000000008281809416926154d3575b5050161415615424565b908092508560040360031b1b1616815f6154c9565b60046040517fc8539a6c000000000000000000000000000000000000000000000000000000008152fd5b615525903d805f833e610a3881836127fe565b505f615409565b905f906001600160a01b036040610140956155888661012095608090816001600160a01b039182815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051151560a0870152602081015160c087015201511660e0840152806101008401528201520190565b600f0b7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081146129e1575f0390565b356001600160a01b03811681036106f35790565b906001600160a01b03809116925f80604094816156308786019561562661561a886155e0565b6020830135908c614d15565b6060810190612950565b91908289519384928337810182815203925af161564b612ef3565b9015614914575061565b906155e0565b908251907f095ea7b3000000000000000000000000000000000000000000000000000000005f5282166004525f60245260205f60448180885af19060015f5114821615615731575b8352156156af57505050565b6156b981846157c5565b15615701576156c890836157c5565b156156d1575050565b6024925051907f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b6024838351907f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b90843b15153d151616906156a3565b906001600160a01b03604051927f095ea7b3000000000000000000000000000000000000000000000000000000005f52166004525f602452735fc5360d0400a0fd4f2af552add042d716f1d1689160205f60448180875af19260015f51148416156157ac575b50604052565b600184929415166145c1573b15153d151616915f6157a6565b91906001600160a01b03604051917f095ea7b3000000000000000000000000000000000000000000000000000000005f52166004525f60245260205f60448180875af19260015f51148416156157ac5750604052565b909391929381511561526657915f925b8251841015615948576020806158418686612e5a565b5101511561592a576001600160a01b0361585b8686612e5a565b51515116905b8061586c8787612e5a565b5101511561590d576001600160a01b03906158878787612e5a565b5151015116915b6001600160a01b038091169116036158ab5760019093019261582b565b8584156158dc5760046040517f54b3e62a000000000000000000000000000000000000000000000000000000008152fd5b602490604051907fd1619a200000000000000000000000000000000000000000000000000000000082526004820152fd5b506001600160a01b036159208686612e5a565b515151169161588e565b6001600160a01b038161593d8787612e5a565b515101511690615861565b9250939290506001600160a01b038091169116036159635750565b602490604051907f6b52ffce0000000000000000000000000000000000000000000000000000000082526004820152fdfea26469706673582212206c2e0e78ff567a32e6fb3a6c3bdd53eef8d41e61740e2ba75c4e21d33605fbbe64736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x48d76e…8c6d84 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0xcdec70…8109 | [0] 0x000000000000…a62d0437 [1] 0x000000000000…0763cd4d data: 0x000000000000000000…1d6442fb |
| 0x56a84c…135848 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0xcdec70…8109 | [0] 0x000000000000…a62d0437 [1] 0x000000000000…b86dc73e data: 0x000000000000000000…1e291132 |
| 0x140b6e…2ca8bd | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0xcdec70…8109 | [0] 0x000000000000…a62d0437 [1] 0x000000000000…3bb0452b data: 0x000000000000000000…1e71fa17 |
| 0xafc17a…722a25 | 32 days agoThu, 16 Jul 2026 15:14:52 UTC | 0xcdec70…8109 | [0] 0x000000000000…7f669a6c [1] 0x000000000000…3bb0452b data: 0x000000000000000000…86cec49c |
| 0x3abfc2…abb9da | 33 days agoWed, 15 Jul 2026 15:03:18 UTC | 0xcdec70…8109 | [0] 0x000000000000…3d8bcf19 [1] 0x000000000000…3bb0452b data: 0x000000000000000000…56537729 |
| 0x569363…f4c306 | 33 days agoWed, 15 Jul 2026 11:29:40 UTC | 0xcdec70…8109 | [0] 0x000000000000…802e3137 [1] 0x000000000000…0763cd4d data: 0x000000000000000000…fe34dcb2 |
| 0x454abb…4de56a | 33 days agoWed, 15 Jul 2026 10:12:03 UTC | 0xcdec70…8109 | [0] 0x000000000000…eceeed58 [1] 0x000000000000…d2c7a9df data: 0x000000000000000000…1cef42bf |
| 0x72c792…d8ef8a | 34 days agoTue, 14 Jul 2026 19:33:57 UTC | 0xcdec70…8109 | [0] 0x000000000000…802e3137 [1] 0x000000000000…dda005c5 data: 0x000000000000000000…9e429ae9 |
| 0xe14b51…bcf8f0 | 34 days agoTue, 14 Jul 2026 18:19:37 UTC | 0x1a2624…a246 | [0] 0x000000000000…4646c3c9 [1] 0x000000000000…d2c7a9df data: 0x000000000000000000…46f7280c |
| 0xa18442…a81bc3 | 34 days agoTue, 14 Jul 2026 18:17:07 UTC | 0xcdec70…8109 | [0] 0x000000000000…4646c3c9 [1] 0x000000000000…d2c7a9df data: 0x000000000000000000…d9a766a6 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | $2.472.46555 USDG | Global Dollar (USDG) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | 0.016872 SPCX | Space Exploration Technologies Corp. Class A Common Stock • Robinhood Token (SPCX) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | $3.040.008907 TSLA | Tesla • Robinhood Token (TSLA) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0xd266…cd4d | 1.835822 SPCX | Space Exploration Technologies Corp. Class A Common Stock • Robinhood Token (SPCX) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0xd266…cd4d | $214.770.629995 TSLA | Tesla • Robinhood Token (TSLA) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0xc941…59bd | IN | 0x7ce8…c776 | 1.852695 SPCX | Space Exploration Technologies Corp. Class A Common Stock • Robinhood Token (SPCX) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0xc941…59bd | $245.73244.944723 USDG | Global Dollar (USDG) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0xc941…59bd | IN | 0x7ce8…c776 | $217.810.638903 TSLA | Tesla • Robinhood Token (TSLA) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x7ce8…c776 | OUT | 0xc941…59bd | $248.97248.165288 USDG | Global Dollar (USDG) | |
| 0x48d76ee3…8c6d84 | Transfer | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x0a13…0437 | IN | 0x7ce8…c776 | $497.17495.575561 USDG | Global Dollar (USDG) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | $2.542.530039 USDG | Global Dollar (USDG) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | 0.008273 GOOGL | Alphabet Class A • Robinhood Token (GOOGL) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | 0.006327 AMZN | Amazon • Robinhood Token (AMZN) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0xa8f2…c73e | 0.670625 GOOGL | Alphabet Class A • Robinhood Token (GOOGL) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0xa8f2…c73e | 0.980629 AMZN | Amazon • Robinhood Token (AMZN) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0xc941…59bd | IN | 0x7ce8…c776 | 0.678898 GOOGL | Alphabet Class A • Robinhood Token (GOOGL) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0xc941…59bd | $253.33252.51563 USDG | Global Dollar (USDG) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0xc941…59bd | IN | 0x7ce8…c776 | 0.986957 AMZN | Amazon • Robinhood Token (AMZN) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | OUT | 0xc941…59bd | $254.31253.492228 USDG | Global Dollar (USDG) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x0a13…0437 | IN | 0x7ce8…c776 | $510.18508.537897 USDG | Global Dollar (USDG) | |
| 0x140b6e56…2ca8bd | Transfer | 11,435,255 | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | $2.562.55393 USDG | Global Dollar (USDG) | |
| 0x140b6e56…2ca8bd | Transfer | 11,435,255 | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | $1.670.003367 MSFT | Microsoft • Robinhood Token (MSFT) | |
| 0x140b6e56…2ca8bd | Transfer | 11,435,255 | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0x7ce8…c776 | OUT | 0x0a13…0437 | $1.100.001855 META | Meta Platforms • Robinhood Token (META) | |
| 0x140b6e56…2ca8bd | Transfer | 11,435,255 | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0x7ce8…c776 | OUT | 0xbde0…452b | $156.560.316467 MSFT | Microsoft • Robinhood Token (MSFT) | |
| 0x140b6e56…2ca8bd | Transfer | 11,435,255 | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0x7ce8…c776 | OUT | 0xbde0…452b | $101.540.171519 META | Meta Platforms • Robinhood Token (META) |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x48d76e…8c6d84 | zapMint2 | 11,436,057 | 32 days agoThu, 16 Jul 2026 17:26:47 UTC | 0x0a13…0437 | IN | VimenZap3 | $0.000 ETH | 0.00006281 | |
| 0x56a84c…135848 | zapMint2 | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x0a13…0437 | IN | VimenZap3 | $0.000 ETH | 0.00006573 | |
| 0x140b6e…2ca8bd | zapMint2 | 11,435,255 | 32 days agoThu, 16 Jul 2026 17:25:26 UTC | 0x0a13…0437 | IN | VimenZap3 | $0.000 ETH | 0.00008577 | |
| 0xafc17a…722a25 | zapMintEth | 11,357,009 | 32 days agoThu, 16 Jul 2026 15:14:52 UTC | 0xc643…9a6c | IN | VimenZap3 | $23.780.01252 ETH | 0.00008326 | |
| 0x3abfc2…abb9da | zapMintEth | 10,485,914 | 33 days agoWed, 15 Jul 2026 15:03:18 UTC | 0xfa81…cf19 | IN | VimenZap3 | $6.980.00367 ETH | 0.00008569 | |
| 0x569363…f4c306 | zapMintEth | 10,357,693 | 33 days agoWed, 15 Jul 2026 11:29:40 UTC | 0xa935…3137 | IN | VimenZap3 | $10.350.00545 ETH | 0.00005650 | |
| 0x454abb…4de56a | zapMint2 | 10,311,047 | 33 days agoWed, 15 Jul 2026 10:12:03 UTC | 0x8cf2…ed58 | IN | VimenZap3 | $0.000 ETH | 0.00014149 | |
| 0x72c792…d8ef8a | zapMint | 9,784,620 | 34 days agoTue, 14 Jul 2026 19:33:57 UTC | 0xa935…3137 | IN | VimenZap3 | $45.720.02408 ETH | 0.00004018 | |
| 0xe14b51…bcf8f0 | zapRedeem | 9,740,069 | 34 days agoTue, 14 Jul 2026 18:19:37 UTC | 0x40f5…c3c9 | IN | VimenZap3 | $0.000 ETH | 0.00004640 | |
| 0xa18442…a81bc3 | zapMintEth | 9,738,562 | 34 days agoTue, 14 Jul 2026 18:17:07 UTC | 0x40f5…c3c9 | IN | VimenZap3 | $102.960.05423 ETH | 0.00013912 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 11,357,009 | 32 days agoThu, 16 Jul 2026 15:14:52 UTC | 0xafc17a…722a25 | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0xc643…9a6c | 0.00006 ETH |
| 11,357,009 | 32 days agoThu, 16 Jul 2026 15:14:52 UTC | 0xafc17a…722a25 | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0x8366…0951 | 0.00642 ETH |
| 11,357,009 | 32 days agoThu, 16 Jul 2026 15:14:52 UTC | 0xafc17a…722a25 | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0x8366…0951 | 0.00603 ETH |
| 10,485,914 | 33 days agoWed, 15 Jul 2026 15:03:18 UTC | 0x3abfc2…abb9da | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0xfa81…cf19 | 0.00001 ETH |
| 10,485,914 | 33 days agoWed, 15 Jul 2026 15:03:18 UTC | 0x3abfc2…abb9da | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0x8366…0951 | 0.00189 ETH |
| 10,485,914 | 33 days agoWed, 15 Jul 2026 15:03:18 UTC | 0x3abfc2…abb9da | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0x8366…0951 | 0.00176 ETH |
| 10,357,693 | 33 days agoWed, 15 Jul 2026 11:29:40 UTC | 0x569363…f4c306 | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0xa935…3137 | 0.00002 ETH |
| 10,357,693 | 33 days agoWed, 15 Jul 2026 11:29:40 UTC | 0x569363…f4c306 | CALL | zapMintEth | 0x7ce8…c776 | OUT | 0x8366…0951 | 0.00542 ETH |