xDAI Price: $1.00 (+0.02%)

Contract

0x87720caEbb7Ae64841c20D2385726Bf0B2945425

Overview

XDAI Balance

Gnosis Chain LogoGnosis Chain LogoGnosis Chain Logo0 XDAI

XDAI Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Sell_conditional...435528572025-12-09 2:09:2542 hrs ago1765246165IN
0x87720caE...0B2945425
0 XDAI00.0000004
Sell_conditional...435528462025-12-09 2:08:3042 hrs ago1765246110IN
0x87720caE...0B2945425
0 XDAI00.00000039
Sell_conditional...435528352025-12-09 2:07:3542 hrs ago1765246055IN
0x87720caE...0B2945425
0 XDAI00.00000046
Sell_conditional...435528232025-12-09 2:06:3542 hrs ago1765245995IN
0x87720caE...0B2945425
0 XDAI00.0000005
Sell_conditional...435528112025-12-09 2:05:3542 hrs ago1765245935IN
0x87720caE...0B2945425
0 XDAI00.0000004
Sell_conditional...435527992025-12-09 2:04:3542 hrs ago1765245875IN
0x87720caE...0B2945425
0 XDAI00.00000064
Sell_conditional...435527872025-12-09 2:03:3542 hrs ago1765245815IN
0x87720caE...0B2945425
0 XDAI00.00000067
Sell_conditional...435527762025-12-09 2:02:4042 hrs ago1765245760IN
0x87720caE...0B2945425
0 XDAI00.00000066
Sell_conditional...435527632025-12-09 2:01:3542 hrs ago1765245695IN
0x87720caE...0B2945425
0 XDAI00.00000062
Sell_conditional...435527512025-12-09 2:00:3542 hrs ago1765245635IN
0x87720caE...0B2945425
0 XDAI00.00000068
Sell_conditional...435527422025-12-09 1:59:3543 hrs ago1765245575IN
0x87720caE...0B2945425
0 XDAI00.00000051
Sell_conditional...435527322025-12-09 1:58:4043 hrs ago1765245520IN
0x87720caE...0B2945425
0 XDAI00.00000051
Sell_conditional...435527192025-12-09 1:57:3543 hrs ago1765245455IN
0x87720caE...0B2945425
0 XDAI00.00000041
Sell_conditional...435527072025-12-09 1:56:3543 hrs ago1765245395IN
0x87720caE...0B2945425
0 XDAI00.00000044
Sell_conditional...435526952025-12-09 1:55:3543 hrs ago1765245335IN
0x87720caE...0B2945425
0 XDAI00.00000051
Sell_conditional...435526812025-12-09 1:54:2543 hrs ago1765245265IN
0x87720caE...0B2945425
0 XDAI00.00000069
Sell_conditional...435526682025-12-09 1:53:2043 hrs ago1765245200IN
0x87720caE...0B2945425
0 XDAI00.00000078
Sell_conditional...435526562025-12-09 1:52:2043 hrs ago1765245140IN
0x87720caE...0B2945425
0 XDAI00.00000078
Sell_conditional...435526442025-12-09 1:51:2043 hrs ago1765245080IN
0x87720caE...0B2945425
0 XDAI00.00000072
Sell_conditional...435526332025-12-09 1:50:2043 hrs ago1765245020IN
0x87720caE...0B2945425
0 XDAI00.00000096
Sell_conditional...435526222025-12-09 1:49:2043 hrs ago1765244960IN
0x87720caE...0B2945425
0 XDAI00.00000079
Sell_conditional...435526092025-12-09 1:48:1543 hrs ago1765244895IN
0x87720caE...0B2945425
0 XDAI00.00000069
Sell_conditional...435525982025-12-09 1:47:2043 hrs ago1765244840IN
0x87720caE...0B2945425
0 XDAI00.00000073
Sell_conditional...435525862025-12-09 1:46:2043 hrs ago1765244780IN
0x87720caE...0B2945425
0 XDAI00.00000115
Sell_conditional...435525752025-12-09 1:45:2543 hrs ago1765244725IN
0x87720caE...0B2945425
0 XDAI00.00000117
View all transactions

View more zero value Internal Transactions in Advanced View mode

Cross-Chain Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x012068E3...FDA768576
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
FutarchyArbExecutorV5

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 1 : FutarchyArbExecutorV5.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;

/// ------------------------
/// Minimal external ABIs
/// ------------------------
interface IERC20 {
    function balanceOf(address) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
}

interface IPermit2 {
    /// Uniswap Permit2 approval: owner = msg.sender
    function approve(address token, address spender, uint160 amount, uint48 expiration) external;
}

/// Minimal composite-like splitter interface (defensive; low-level call used)
interface ICompositeLike {
    function split(uint256 amount) external;
}

/// Futarchy router interface used for proper splits
interface IFutarchyRouter {
    function splitPosition(address proposal, address token, uint256 amount) external;
    /// Merge conditional collateral (YES/NO) back into base collateral `token` for a given `proposal`.
    /// Expected to transferFrom both conditional legs from `msg.sender` (this executor) and mint `token`.
    function mergePositions(address proposal, address token, uint256 amount) external;
}

/// Minimal Algebra/Swapr router interface (exact-in single hop)
interface IAlgebraSwapRouter {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 limitSqrtPrice; // 0 for “no limit”
    }
    function exactInputSingle(ExactInputSingleParams calldata params)
        external
        payable
        returns (uint256 amountOut);

    // NOTE: Swapr/Algebra exactOutputSingle expects tokenIn first, then tokenOut (no fee field).
    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 limitSqrtPrice; // 0 for “no limit”
    }
    function exactOutputSingle(ExactOutputSingleParams calldata params)
        external
        payable
        returns (uint256 amountIn);
}

interface IUniswapV3Pool {
    function fee() external view returns (uint24);
}

interface ISwapRouterV3ExactOutput {
    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24  fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }
    function exactOutputSingle(ExactOutputSingleParams calldata params)
        external
        payable
        returns (uint256 amountIn);
}

/// ------------------------
/// Uniswap V2-like Router (Swapr v2) – exact-in multi-hop
/// ------------------------
interface IUniswapV2Router02 {
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
}

/// ------------------------
/// Balancer BatchRouter (swapExactIn) – typed interface for BUY step 6
/// ------------------------
interface IBalancerBatchRouter {
    struct SwapPathStep {
        address pool;
        address tokenOut;
        bool    isBuffer;
    }
    struct SwapPathExactAmountIn {
        address tokenIn;
        SwapPathStep[] steps;
        uint256 exactAmountIn;
        uint256 minAmountOut;
    }
    function swapExactIn(
        SwapPathExactAmountIn[] calldata paths,
        uint256 deadline,
        bool wethIsEth,
        bytes calldata userData
    )
        external
        payable
        returns (uint256[] memory pathAmountsOut, address[] memory tokensOut, uint256[] memory amountsOut);
}

/// ------------------------
/// Balancer Vault (batchSwap) – used in PNK flows
/// ------------------------
interface IBalancerVault {
    enum SwapKind { GIVEN_IN, GIVEN_OUT }
    struct BatchSwapStep {
        bytes32 poolId;
        uint256 assetInIndex;
        uint256 assetOutIndex;
        uint256 amount; // amount for GIVEN_IN on the first step of each branch; 0 for subsequent chained steps
        bytes userData;
    }
    struct FundManagement {
        address sender;
        bool fromInternalBalance;
        address recipient;
        bool toInternalBalance;
    }
    function batchSwap(
        SwapKind kind,
        BatchSwapStep[] calldata swaps,
        address[] calldata assets,
        FundManagement calldata funds,
        int256[] calldata limits,
        uint256 deadline
    ) external returns (int256[] memory assetDeltas);
}

/**
 * @title FutarchyArbExecutorV5 (Step 1 & 2 only)
 * @notice Snapshot collateral; ensure approvals (Permit2 + Vault); execute pre-encoded Balancer BatchRouter.swapExactIn.
 * @dev Expects `buy_company_ops` to be calldata for BatchRouter.swapExactIn(paths, deadline, wethIsEth, userData).
 *      Contract must already custody the input collateral `cur` (e.g., sDAI).
 */
contract FutarchyArbExecutorV5 {
    /// ------------------------
    /// PNK Trading Constants (Gnosis)
    /// ------------------------
    /// Fixed addresses used by the PNK buy/sell helper flows.
    address internal constant TOKEN_SDAI = 0xaf204776c7245bF4147c2612BF6e5972Ee483701;
    address internal constant TOKEN_WETH = 0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1;
    address internal constant TOKEN_PNK  = 0x37b60f4E9A31A64cCc0024dce7D0fD07eAA0F7B3;
    address internal constant BALANCER_VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
    address internal constant SWAPR_V2_ROUTER = 0xE43e60736b1cb4a75ad25240E2f9a62Bff65c0C0;

    /// Balancer batchSwap GIVEN_IN route: sDAI -> WETH (multi-branch), as observed on-chain.
    bytes32 internal constant PNK_POOL_1 = 0xa91c413d8516164868f6cca19573fe38f88f5982000200000000000000000157;
    bytes32 internal constant PNK_POOL_2 = 0x7e5870ac540adfd01a213c829f2231c309623eb10002000000000000000000e9;
    bytes32 internal constant PNK_POOL_3 = 0x40d2cbc586dd8df50001cdba3f65cd4bbc32d596000200000000000000000154;
    bytes32 internal constant PNK_POOL_4 = 0x480d4f66cc41a1b6784a53a10890e5ece31d75c000020000000000000000014e;
    bytes32 internal constant PNK_POOL_5 = 0xa99fd9950b5d5dceeaf4939e221dca8ca9b938ab000100000000000000000025;

    /// Assets order used for the batchSwap indices.
    /// Index mapping for convenience.
    address internal constant PNK_ASSET_2 = 0xC0d871bD13eBdf5c4ff059D8243Fb38210608bD6;
    address internal constant PNK_ASSET_4 = 0xE0eD85F76D9C552478929fab44693E03F0899F23;
    address internal constant PNK_ASSET_5_GNO = 0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb;
    uint256 internal constant PNK_IDX_SDAI = 0;
    uint256 internal constant PNK_IDX_WETH = 2;

    /// Deadlines
    uint256 internal constant BALANCER_VAULT_DEADLINE = 9007199254740991; // far-future
    uint256 internal constant SWAPR_V2_DEADLINE = 3510754692; // far-future

    /// Helper: assets array in the exact order expected by the PNK Balancer route
    function _pnkAssetsOrder() internal pure returns (address[] memory assets) {
        assets = new address[](5);
        assets[0] = TOKEN_SDAI;
        assets[1] = PNK_ASSET_2;
        assets[2] = TOKEN_WETH;
        assets[3] = PNK_ASSET_4;
        assets[4] = PNK_ASSET_5_GNO; // GNO
    }

    /// Helper: poolIds array used by the PNK Balancer route (sDAI -> WETH)
    function _pnkPoolIds() internal pure returns (bytes32[] memory poolIds) {
        poolIds = new bytes32[](5);
        poolIds[0] = PNK_POOL_1;
        poolIds[1] = PNK_POOL_2;
        poolIds[2] = PNK_POOL_3;
        poolIds[3] = PNK_POOL_4;
        poolIds[4] = PNK_POOL_5;
    }

    /// ------------------------
    /// PNK Buy Flow: sDAI -> WETH (Balancer Vault, single-branch) -> PNK (Swapr)
    /// ------------------------
    // Internal implementation used by on-chain flows
    function _buyPnkWithSdai(uint256 amountSdaiIn, uint256 minWethOut, uint256 minPnkOut) internal {
        require(amountSdaiIn > 0, "amount=0");

        // Approve sDAI to Balancer Vault
        _ensureMaxAllowance(IERC20(TOKEN_SDAI), BALANCER_VAULT);

        // Build assets order
        address[] memory assets = _pnkAssetsOrder();

        // Build swaps: single branch sDAI (0) -> ASSET_4 (3) -> GNO (4) -> WETH (2)
        IBalancerVault.BatchSwapStep[] memory swaps = new IBalancerVault.BatchSwapStep[](3);
        swaps[0] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_3,
            assetInIndex: 0,
            assetOutIndex: 3,
            amount: amountSdaiIn,
            userData: bytes("")
        });
        swaps[1] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_4,
            assetInIndex: 3,
            assetOutIndex: 4,
            amount: 0,
            userData: bytes("")
        });
        swaps[2] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_5,
            assetInIndex: 4,
            assetOutIndex: 2,
            amount: 0,
            userData: bytes("")
        });

        // Limits: positive sDAI in; negative min WETH out if set
        int256[] memory limits = new int256[](assets.length);
        limits[PNK_IDX_SDAI] = int256(amountSdaiIn);
        if (minWethOut > 0) {
            limits[PNK_IDX_WETH] = -int256(minWethOut);
        }

        // Funds: this contract as sender/recipient; no internal balance
        IBalancerVault.FundManagement memory funds = IBalancerVault.FundManagement({
            sender: address(this),
            fromInternalBalance: false,
            recipient: address(this),
            toInternalBalance: false
        });

        // Execute batchSwap
        IBalancerVault(BALANCER_VAULT).batchSwap(
            IBalancerVault.SwapKind.GIVEN_IN,
            swaps,
            assets,
            funds,
            limits,
            BALANCER_VAULT_DEADLINE
        );

        // Validate WETH received
        uint256 wethBal = IERC20(TOKEN_WETH).balanceOf(address(this));
        require(wethBal > 0, "no WETH");
        if (minWethOut > 0) {
            require(wethBal >= minWethOut, "min WETH not met");
        }

        // Approve and swap WETH -> PNK on Swapr v2 (Uniswap v2 router)
        _ensureMaxAllowance(IERC20(TOKEN_WETH), SWAPR_V2_ROUTER);
        address[] memory path = new address[](2);
        path[0] = TOKEN_WETH;
        path[1] = TOKEN_PNK;
        IUniswapV2Router02(SWAPR_V2_ROUTER).swapExactTokensForTokens(
            wethBal,
            minPnkOut,
            path,
            address(this),
            SWAPR_V2_DEADLINE
        );
    }
    // External entrypoint gated to owner only
    function buyPnkWithSdai(uint256 amountSdaiIn, uint256 minWethOut, uint256 minPnkOut) external onlyOwner {
        _buyPnkWithSdai(amountSdaiIn, minWethOut, minPnkOut);
    }

    /// ------------------------
    /// PNK Sell Flow: PNK -> WETH (Swapr) -> sDAI (Balancer Vault)
    /// ------------------------
    // Internal implementation used by on-chain flows
    function _sellPnkForSdai(uint256 amountPnkIn, uint256 minWethOut, uint256 minSdaiOut) internal {
        require(amountPnkIn > 0, "amount=0");

        // 1) Swap PNK -> WETH on Swapr v2 (Uniswap v2 router)
        _ensureMaxAllowance(IERC20(TOKEN_PNK), SWAPR_V2_ROUTER);
        address[] memory pathOut = new address[](2);
        pathOut[0] = TOKEN_PNK;
        pathOut[1] = TOKEN_WETH;
        IUniswapV2Router02(SWAPR_V2_ROUTER).swapExactTokensForTokens(
            amountPnkIn,
            minWethOut,
            pathOut,
            address(this),
            SWAPR_V2_DEADLINE
        );

        // Read WETH received
        uint256 wethBal = IERC20(TOKEN_WETH).balanceOf(address(this));
        require(wethBal > 0, "no WETH");
        if (minWethOut > 0) {
            require(wethBal >= minWethOut, "min WETH not met");
        }

        // 2) Balancer Vault batchSwap: WETH -> sDAI using the reverse path of the buy flow
        _ensureMaxAllowance(IERC20(TOKEN_WETH), BALANCER_VAULT);

        address[] memory assets = _pnkAssetsOrder();

        IBalancerVault.BatchSwapStep[] memory swaps = new IBalancerVault.BatchSwapStep[](5);
        uint256 half = wethBal / 2;
        uint256 other = wethBal - half;

        // Reverse Branch A: WETH (2) -> ASSET_2 (1) -> sDAI (0)
        swaps[0] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_2,
            assetInIndex: 2,
            assetOutIndex: 1,
            amount: half,
            userData: bytes("")
        });
        swaps[1] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_1,
            assetInIndex: 1,
            assetOutIndex: 0,
            amount: 0,
            userData: bytes("")
        });

        // Reverse Branch B: WETH (2) -> GNO (4) -> ASSET_4 (3) -> sDAI (0)
        swaps[2] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_5,
            assetInIndex: 2,
            assetOutIndex: 4,
            amount: other,
            userData: bytes("")
        });
        swaps[3] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_4,
            assetInIndex: 4,
            assetOutIndex: 3,
            amount: 0,
            userData: bytes("")
        });
        swaps[4] = IBalancerVault.BatchSwapStep({
            poolId: PNK_POOL_3,
            assetInIndex: 3,
            assetOutIndex: 0,
            amount: 0,
            userData: bytes("")
        });

        // Limits: positive WETH in; negative min sDAI out if set
        int256[] memory limits = new int256[](assets.length);
        limits[PNK_IDX_WETH] = int256(wethBal);
        if (minSdaiOut > 0) {
            limits[PNK_IDX_SDAI] = -int256(minSdaiOut);
        }

        IBalancerVault.FundManagement memory funds = IBalancerVault.FundManagement({
            sender: address(this),
            fromInternalBalance: false,
            recipient: address(this),
            toInternalBalance: false
        });

        IBalancerVault(BALANCER_VAULT).batchSwap(
            IBalancerVault.SwapKind.GIVEN_IN,
            swaps,
            assets,
            funds,
            limits,
            BALANCER_VAULT_DEADLINE
        );

        // Validate sDAI received
        uint256 sdaiBal = IERC20(TOKEN_SDAI).balanceOf(address(this));
        require(sdaiBal > 0, "no sDAI");
        if (minSdaiOut > 0) {
            require(sdaiBal >= minSdaiOut, "min sDAI not met");
        }
    }
    // External entrypoint gated to owner only
    function sellPnkForSdai(uint256 amountPnkIn, uint256 minWethOut, uint256 minSdaiOut) external onlyOwner {
        _sellPnkForSdai(amountPnkIn, minWethOut, minSdaiOut);
    }

    /**
     * @notice SELL complete arbitrage variant that buys PNK internally (sDAI→WETH→PNK) instead of using Balancer calldata.
     * @dev Signature mirrors sell_conditional_arbitrage_balancer for compatibility; Step 2 differs only.
     */
    function sell_conditional_arbitrage_pnk(
        bytes calldata buy_company_ops, // ignored in this variant
        address balancer_router,         // ignored for Step 2 (kept for signature compatibility)
        address balancer_vault,          // ignored for Step 2 (kept for signature compatibility)
        address comp,                    // MUST be TOKEN_PNK in this variant
        address cur,
        address futarchy_router,
        address proposal,
        address yes_comp,
        address no_comp,
        address yes_cur,
        address no_cur,
        address swapr_router,
        uint256 amount_sdai_in,
        int256  min_out_final
    ) external onlyOwner {
        // Silence unused params
        (buy_company_ops); (balancer_router); (balancer_vault);

        // --- Step 1: snapshot collateral ---
        uint256 initial_cur_balance = IERC20(cur).balanceOf(address(this));
        emit InitialCollateralSnapshot(cur, initial_cur_balance);

        require(amount_sdai_in > 0, "amount=0");
        require(comp == TOKEN_PNK, "comp!=PNK");
        require(futarchy_router != address(0) && proposal != address(0), "router/proposal=0");
        require(cur != address(0) && yes_comp != address(0) && no_comp != address(0), "addr=0");
        require(yes_cur != address(0) && no_cur != address(0) && swapr_router != address(0), "addr=0");

        // --- Step 2 (replaced): buy PNK using internal sDAI→WETH→PNK path ---
        // Uses fixed Balancer route + Swapr v2 router configured in this contract.
        // minWethOut/minPnkOut set to 0 for simplicity; external callers can constrain via min_out_final if needed.
        _buyPnkWithSdai(amount_sdai_in, 0, 0);

        // --- Step 3: verify PNK (comp) acquired ---
        uint256 compBalance = IERC20(comp).balanceOf(address(this));
        emit CompositeAcquired(comp, compBalance);
        require(compBalance > 0, "Failed to acquire composite token");

        // --- Step 4: Split into conditional comps ---
        if (futarchy_router != address(0) && proposal != address(0)) {
            _ensureMaxAllowance(IERC20(comp), futarchy_router);
            IFutarchyRouter(futarchy_router).splitPosition(proposal, comp, compBalance);
        } else {
            (bool ok, ) = comp.call(abi.encodeWithSelector(ICompositeLike.split.selector, compBalance));
            emit CompositeSplitAttempted(comp, compBalance, ok);
        }

        // --- Step 5: Sell conditional composite → conditional collateral on Swapr (exact-in) ---
        uint256 yesCompBal = IERC20(yes_comp).balanceOf(address(this));
        if (yesCompBal > 0) {
            _swaprExactIn(swapr_router, yes_comp, yes_cur, yesCompBal, 0);
        }
        uint256 noCompBal = IERC20(no_comp).balanceOf(address(this));
        if (noCompBal > 0) {
            _swaprExactIn(swapr_router, no_comp, no_cur, noCompBal, 0);
        }

        // --- Step 6: Merge conditional collateral (YES/NO) back into base collateral (cur) ---
        if (futarchy_router != address(0) && proposal != address(0)) {
            uint256 yesCurBal = IERC20(yes_cur).balanceOf(address(this));
            uint256 noCurBal  = IERC20(no_cur).balanceOf(address(this));
            uint256 mergeAmt  = yesCurBal < noCurBal ? yesCurBal : noCurBal;
            if (mergeAmt > 0) {
                // Router will transferFrom both legs; approve both to MAX
                _ensureMaxAllowance(IERC20(yes_cur), futarchy_router);
                _ensureMaxAllowance(IERC20(no_cur),  futarchy_router);
                IFutarchyRouter(futarchy_router).mergePositions(proposal, cur, mergeAmt);
                emit ConditionalCollateralMerged(futarchy_router, proposal, cur, mergeAmt);
            }
        }

        // --- Step 7: Sell any remaining single-sided conditional collateral to base collateral on Swapr ---
        uint256 yesCurLeft = IERC20(yes_cur).balanceOf(address(this));
        uint256 noCurLeft  = IERC20(no_cur).balanceOf(address(this));
        if (yesCurLeft > 0) {
            _swaprExactIn(swapr_router, yes_cur, cur, yesCurLeft, 0);
        } else if (noCurLeft > 0) {
            _swaprExactIn(swapr_router, no_cur,  cur, noCurLeft,  0);
        }

        // --- Step 8: On-chain profit check in base collateral terms (signed) ---
        uint256 final_cur_balance = IERC20(cur).balanceOf(address(this));
        require(
            final_cur_balance <= uint256(type(int256).max) &&
            initial_cur_balance <= uint256(type(int256).max),
            "balance too large"
        );
        int256 signedProfit = int256(final_cur_balance) - int256(initial_cur_balance);
        require(signedProfit >= min_out_final, "min profit not met");
        emit ProfitVerified(initial_cur_balance, final_cur_balance, min_out_final);
    }

    /**
     * @notice BUY complete arbitrage variant that sells PNK internally (PNK→WETH→sDAI) instead of using Balancer calldata.
     * @dev Signature mirrors buy_conditional_arbitrage_balancer for compatibility; only Step 6 differs.
     */
    function buy_conditional_arbitrage_pnk(

        address comp,                     // MUST be TOKEN_PNK in this variant
        address cur,
        bool yes_has_higher_price,
        address futarchy_router,
        address proposal,
        address yes_comp,
        address no_comp,
        address yes_cur,
        address no_cur,
        address yes_pool,
        address no_pool,
        address swapr_router,
        uint256 amount_sdai_in,
        int256  min_out_final
    ) external onlyOwner {

        // --- Step 0: snapshot base collateral for profit accounting ---
        uint256 initial_cur_balance = IERC20(cur).balanceOf(address(this));

        require(amount_sdai_in > 0, "amount=0");
        require(comp == TOKEN_PNK, "comp!=PNK");
        require(futarchy_router != address(0) && proposal != address(0), "router/proposal=0");
        require(cur != address(0) && yes_comp != address(0) && no_comp != address(0), "addr=0");
        require(yes_cur != address(0) && no_cur != address(0) && swapr_router != address(0), "addr=0");

        // Step 1: split sDAI into conditional collateral (YES/NO)
        _ensureMaxAllowance(IERC20(cur), futarchy_router);
        IFutarchyRouter(futarchy_router).splitPosition(proposal, cur, amount_sdai_in);
        emit ConditionalCollateralSplit(futarchy_router, proposal, cur, amount_sdai_in);

        // Defensive check: ensure at least amount_sdai_in exists on both legs
        require(IERC20(yes_cur).balanceOf(address(this)) >= amount_sdai_in, "insufficient YES_cur");
        require(IERC20(no_cur).balanceOf(address(this))  >= amount_sdai_in, "insufficient NO_cur");

        // Step 2 & 3: buy comps symmetrically
        uint24 yesFee = _poolFeeOrDefault(yes_pool);
        uint24 noFee  = _poolFeeOrDefault(no_pool);
        if (yes_has_higher_price) {
            uint256 yesCompOut = _swaprExactIn(swapr_router, yes_cur, yes_comp, amount_sdai_in, 0);
            require(yesCompOut > 0, "YES exact-in produced zero");
            _swaprExactOut(swapr_router, no_cur, no_comp, noFee, yesCompOut, amount_sdai_in);
        } else {
            uint256 noCompOut = _swaprExactIn(swapr_router, no_cur, no_comp, amount_sdai_in, 0);
            require(noCompOut > 0, "NO exact-in produced zero");
            _swaprExactOut(swapr_router, yes_cur, yes_comp, yesFee, noCompOut, amount_sdai_in);
        }

        // Step 4: Merge conditional composite tokens (YES_COMP/NO_COMP -> COMP)
        uint256 yesCompBal = IERC20(yes_comp).balanceOf(address(this));
        uint256 noCompBal  = IERC20(no_comp).balanceOf(address(this));
        uint256 mergeAmt   = yesCompBal < noCompBal ? yesCompBal : noCompBal;
        if (mergeAmt > 0) {
            _ensureMaxAllowance(IERC20(yes_comp), futarchy_router);
            _ensureMaxAllowance(IERC20(no_comp),  futarchy_router);
            IFutarchyRouter(futarchy_router).mergePositions(proposal, comp, mergeAmt);
            emit ConditionalCollateralMerged(futarchy_router, proposal, comp, mergeAmt);
        }

        // Step 6 (replaced): Sell PNK -> sDAI using internal helper
        uint256 pnkBal = IERC20(TOKEN_PNK).balanceOf(address(this));
        if (pnkBal > 0) {
            _sellPnkForSdai(pnkBal, 0, 0);
        }

        // Step 7: Sell any remaining single-sided conditional collateral to base collateral on Swapr
        uint256 yesCurLeft = IERC20(yes_cur).balanceOf(address(this));
        uint256 noCurLeft  = IERC20(no_cur).balanceOf(address(this));
        if (yesCurLeft > 0) {
            _swaprExactIn(swapr_router, yes_cur, cur, yesCurLeft, 0);
        } else if (noCurLeft > 0) {
            _swaprExactIn(swapr_router, no_cur,  cur, noCurLeft,  0);
        }

        // Step 8: Profit check
        uint256 final_cur_balance = IERC20(cur).balanceOf(address(this));
        require(
            final_cur_balance <= uint256(type(int256).max) &&
            initial_cur_balance <= uint256(type(int256).max),
            "balance too large"
        );
        int256 signedProfit = int256(final_cur_balance) - int256(initial_cur_balance);
        require(signedProfit >= min_out_final, "min profit not met");
        emit ProfitVerified(initial_cur_balance, final_cur_balance, min_out_final);
    }
    // --- Ownership ---
    address public owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }

    constructor() {
        owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
    }
    /// Uniswap Permit2 (canonical)
    // Checksummed literal required by recent solc versions
    address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
    uint160 internal constant MAX_UINT160 = type(uint160).max;
    uint48  internal constant MAX_UINT48  = type(uint48).max;

    event InitialCollateralSnapshot(address indexed collateral, uint256 balance);
    event MaxAllowanceEnsured(address indexed token, address indexed spender, uint256 allowance);
    event Permit2AllowanceEnsured(address indexed token, address indexed spender, uint160 amount, uint48 expiration);
    event BalancerBuyExecuted(address indexed router, bytes buyOps);
    event BalancerSellExecuted(address indexed router, bytes sellOps);
    event CompositeAcquired(address indexed comp, uint256 amount);
    event CompositeSplitAttempted(address indexed comp, uint256 amount, bool ok);
    event SwaprExactInExecuted(
        address indexed router,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 amountIn,
        uint256 amountOut
    );
    event SwaprExactOutExecuted(
        address indexed router,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 amountOut,
        uint256 amountIn
    );
    event ConditionalCollateralMerged(
        address indexed router,
        address indexed proposal,
        address indexed collateral,
        uint256 amount
    );
    event ConditionalCollateralSplit(
        address indexed router,
        address indexed proposal,
        address indexed collateral,
        uint256 amount
    );
    event ProfitVerified(uint256 initialBalance, uint256 finalBalance, int256 minProfit);

    /// Idempotent ERC20 max-approval (resets to 0 first if needed)
    function _ensureMaxAllowance(IERC20 token, address spender) internal {
        uint256 cur = token.allowance(address(this), spender);
        if (cur != type(uint256).max) {
            if (cur != 0) {
                require(token.approve(spender, 0), "approve reset failed");
            }
            require(token.approve(spender, type(uint256).max), "approve set failed");
        }
        emit MaxAllowanceEnsured(address(token), spender, token.allowance(address(this), spender));
    }

    /// Ensure both ERC20->Permit2 and Permit2(owner=this)->router allowances
    function _ensurePermit2Approvals(IERC20 token, address router) internal {
        // 1) ERC-20 approval: token spender = Permit2
        _ensureMaxAllowance(token, PERMIT2);
        // 2) Permit2 internal allowance: owner = this contract; spender = router
        IPermit2(PERMIT2).approve(address(token), router, MAX_UINT160, MAX_UINT48);
        emit Permit2AllowanceEnsured(address(token), router, MAX_UINT160, MAX_UINT48);
    }

    /// Algebra/Swapr: approve and execute exact-input single hop
    function _swaprExactIn(
        address swapr_router,
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 minOut
    ) internal returns (uint256 amountOut) {
        require(swapr_router != address(0), "swapr router=0");
        require(tokenIn != address(0) && tokenOut != address(0), "token=0");
        if (amountIn == 0) return 0;
        _ensureMaxAllowance(IERC20(tokenIn), swapr_router);
        IAlgebraSwapRouter.ExactInputSingleParams memory p = IAlgebraSwapRouter.ExactInputSingleParams({
            tokenIn: tokenIn,
            tokenOut: tokenOut,
            recipient: address(this),
            deadline: block.timestamp,
            amountIn: amountIn,
            amountOutMinimum: minOut,
            limitSqrtPrice: 0
        });
        amountOut = IAlgebraSwapRouter(swapr_router).exactInputSingle(p);
        emit SwaprExactInExecuted(swapr_router, tokenIn, tokenOut, amountIn, amountOut);
    }

    /// Swapr/UniswapV3: approve and execute exact-output single hop (requires fee tier)
    function _swaprExactOut(
        address swapr_router,
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountOut,
        uint256 maxIn
    ) internal returns (uint256 amountIn) {
        require(swapr_router != address(0), "swapr router=0");
        require(tokenIn != address(0) && tokenOut != address(0), "token=0");
        if (amountOut == 0) return 0;
        _ensureMaxAllowance(IERC20(tokenIn), swapr_router);
        ISwapRouterV3ExactOutput.ExactOutputSingleParams memory p = ISwapRouterV3ExactOutput.ExactOutputSingleParams({
            tokenIn: tokenIn,
            tokenOut: tokenOut,
            fee: fee,
            recipient: address(this),
            deadline: block.timestamp,
            amountOut: amountOut,
            amountInMaximum: maxIn,
            sqrtPriceLimitX96: 0
        });
        amountIn = ISwapRouterV3ExactOutput(swapr_router).exactOutputSingle(p);
        emit SwaprExactOutExecuted(swapr_router, tokenIn, tokenOut, amountOut, amountIn);
    }

    uint24 internal constant DEFAULT_V3_FEE = 100; // 0.01%
    function _poolFeeOrDefault(address pool) internal view returns (uint24) {
        if (pool == address(0)) return DEFAULT_V3_FEE;
        try IUniswapV3Pool(pool).fee() returns (uint24 f) {
            return f == 0 ? DEFAULT_V3_FEE : f;
        } catch {
            return DEFAULT_V3_FEE;
        }
    }

    /**
     * @notice Symmetric BUY: steps 1–6 already implemented; this patch adds steps 7–8.
     * @dev Steps 1–3: split sDAI -> conditional collateral; buy YES/NO comps (exact-in + exact-out).
     *      Step 4: merge comps -> COMP; Step 5–6: sell COMP -> sDAI on Balancer.
     *      Step 7: sell remaining single-sided conditional collateral (YES_cur or NO_cur) -> cur on Swapr.
     *      Step 8: on-chain profit check in base-collateral terms against `min_out_final`.
     */
    function buy_conditional_arbitrage_balancer(
        bytes calldata sell_company_ops, // Balancer BatchRouter.swapExactIn (COMP -> sDAI) calldata
        address balancer_router,         // BatchRouter address (expects swapExactIn)
        address balancer_vault,          // Vault/V3 (optional; 0 if unused)
        address comp,                    // Composite token (Company)
        address cur,
        bool yes_has_higher_price,
        address futarchy_router,
        address proposal,
        address yes_comp,
        address no_comp,
        address yes_cur,
        address no_cur,
        address yes_pool,
        address no_pool,
        address swapr_router,
        uint256 amount_sdai_in,
        int256  min_out_final
    ) external onlyOwner {
        // KEEPING signature compatible; new arg appended.
        // --- Step 0: snapshot base collateral for profit accounting ---
        uint256 initial_cur_balance = IERC20(cur).balanceOf(address(this));

        require(amount_sdai_in > 0, "amount=0");
        require(futarchy_router != address(0) && proposal != address(0), "router/proposal=0");
        require(cur != address(0) && yes_comp != address(0) && no_comp != address(0), "addr=0");
        require(yes_cur != address(0) && no_cur != address(0) && swapr_router != address(0), "addr=0");

        // Step 1: split sDAI into conditional collateral (YES/NO)
        _ensureMaxAllowance(IERC20(cur), futarchy_router);
        IFutarchyRouter(futarchy_router).splitPosition(proposal, cur, amount_sdai_in);
        emit ConditionalCollateralSplit(futarchy_router, proposal, cur, amount_sdai_in);

        // Defensive check: ensure at least amount_sdai_in exists on both legs
        require(IERC20(yes_cur).balanceOf(address(this)) >= amount_sdai_in, "insufficient YES_cur");
        require(IERC20(no_cur).balanceOf(address(this))  >= amount_sdai_in, "insufficient NO_cur");

        // Step 2 & 3: buy comps symmetrically
        uint24 yesFee = _poolFeeOrDefault(yes_pool);
        uint24 noFee  = _poolFeeOrDefault(no_pool);
        if (yes_has_higher_price) {
            uint256 yesCompOut = _swaprExactIn(swapr_router, yes_cur, yes_comp, amount_sdai_in, 0);
            require(yesCompOut > 0, "YES exact-in produced zero");
            _swaprExactOut(swapr_router, no_cur, no_comp, noFee, yesCompOut, amount_sdai_in);
        } else {
            uint256 noCompOut = _swaprExactIn(swapr_router, no_cur, no_comp, amount_sdai_in, 0);
            require(noCompOut > 0, "NO exact-in produced zero");
            _swaprExactOut(swapr_router, yes_cur, yes_comp, yesFee, noCompOut, amount_sdai_in);
        }

        // ------------------------------------------------------------------ //
        // Step 4: Merge conditional composite tokens (YES_COMP/NO_COMP -> COMP)
        // ------------------------------------------------------------------ //
        uint256 yesCompBal = IERC20(yes_comp).balanceOf(address(this));
        uint256 noCompBal  = IERC20(no_comp).balanceOf(address(this));
        uint256 mergeAmt   = yesCompBal < noCompBal ? yesCompBal : noCompBal;
        if (mergeAmt > 0) {
            // Router will transferFrom both legs; approve both to MAX
            _ensureMaxAllowance(IERC20(yes_comp), futarchy_router);
            _ensureMaxAllowance(IERC20(no_comp),  futarchy_router);
            IFutarchyRouter(futarchy_router).mergePositions(proposal, comp, mergeAmt);
            // Reuse merged event; collateral param carries `comp` in this branch
            emit ConditionalCollateralMerged(futarchy_router, proposal, comp, mergeAmt);
        }

        // ------------------------------------------------------------------ //
        // Step 5 & 6: Sell COMP -> sDAI
        //   - If COMP is PNK, use the internal PNK sell helper (Swapr v2 + Balancer Vault)
        //   - Otherwise, use provided Balancer BatchRouter calldata to sell COMP
        // ------------------------------------------------------------------ //
        if (mergeAmt > 0) {
            if (comp == TOKEN_PNK) {
                // Internal PNK liquidation path in the same tx
                uint256 pnkBal = IERC20(TOKEN_PNK).balanceOf(address(this));
                if (pnkBal > 0) {
                    _sellPnkForSdai(pnkBal, 0, 0);
                }
            } else if (sell_company_ops.length > 0) {
                require(balancer_router != address(0), "balancer router=0");
                _ensurePermit2Approvals(IERC20(comp), balancer_router);
                if (balancer_vault != address(0)) {
                    _ensureMaxAllowance(IERC20(comp), balancer_vault);
                }

                (
                    IBalancerBatchRouter.SwapPathExactAmountIn[] memory paths,
                    uint256 deadline,
                    bool wethIsEth,
                    bytes memory userData
                ) = abi.decode(
                    sell_company_ops[4:],
                    (IBalancerBatchRouter.SwapPathExactAmountIn[], uint256, bool, bytes)
                );
                require(paths.length > 0, "paths=0");
                if (paths[0].tokenIn != comp) {
                    paths[0].tokenIn = comp;
                }
                paths[0].exactAmountIn = mergeAmt;

                IBalancerBatchRouter(balancer_router).swapExactIn(paths, deadline, wethIsEth, userData);
                emit BalancerSellExecuted(balancer_router, sell_company_ops);
            }
        }

        // --- Step 7: Sell any remaining single-sided conditional collateral to base collateral on Swapr ---
        uint256 yesCurLeft = IERC20(yes_cur).balanceOf(address(this));
        uint256 noCurLeft  = IERC20(no_cur).balanceOf(address(this));
        if (yesCurLeft > 0) {
            _swaprExactIn(swapr_router, yes_cur, cur, yesCurLeft, 0);
        } else if (noCurLeft > 0) {
            _swaprExactIn(swapr_router, no_cur,  cur, noCurLeft,  0);
        }

        // --- Step 8: On-chain profit check in base collateral terms (signed) ---
        uint256 final_cur_balance = IERC20(cur).balanceOf(address(this));
        require(
            final_cur_balance <= uint256(type(int256).max) &&
            initial_cur_balance <= uint256(type(int256).max),
            "balance too large"
        );
        int256 signedProfit = int256(final_cur_balance) - int256(initial_cur_balance);
        require(signedProfit >= min_out_final, "min profit not met");
        emit ProfitVerified(initial_cur_balance, final_cur_balance, min_out_final);
    }


    function sell_conditional_arbitrage_balancer(
        bytes calldata buy_company_ops,
        address balancer_router,
        address balancer_vault,
        address comp,
        address cur,
        address futarchy_router,
        address proposal,
        address yes_comp,
        address no_comp,
        address yes_cur,
        address no_cur,
        address swapr_router,
        uint256 amount_sdai_in,
        int256 min_out_final
    ) external onlyOwner {
        // Silence unused param (forward-compat)
        (amount_sdai_in);

        // --- Step 1: snapshot collateral ---
        uint256 initial_cur_balance = IERC20(cur).balanceOf(address(this));
        emit InitialCollateralSnapshot(cur, initial_cur_balance);

        // --- Approvals required for the observed Balancer trace ---
        _ensurePermit2Approvals(IERC20(cur), balancer_router);
        if (balancer_vault != address(0)) {
            _ensureMaxAllowance(IERC20(cur), balancer_vault);
        }

        // --- Step 2: Balancer buy ---
        (bool ok, ) = balancer_router.call(buy_company_ops);
        require(ok, "Balancer buy swap failed");
        emit BalancerBuyExecuted(balancer_router, buy_company_ops);

        // --- Step 3: verify composite acquired ---
        uint256 compBalance = IERC20(comp).balanceOf(address(this));
        emit CompositeAcquired(comp, compBalance);
        require(compBalance > 0, "Failed to acquire composite token");

        // --- Step 4: Split into conditional comps ---
        if (futarchy_router != address(0) && proposal != address(0)) {
            _ensureMaxAllowance(IERC20(comp), futarchy_router);
            IFutarchyRouter(futarchy_router).splitPosition(proposal, comp, compBalance);
        } else {
            (ok, ) = comp.call(abi.encodeWithSelector(ICompositeLike.split.selector, compBalance));
            emit CompositeSplitAttempted(comp, compBalance, ok);
        }

        // --- Step 5: Sell conditional composite → conditional collateral on Swapr (exact-in) ---
        uint256 yesCompBal = IERC20(yes_comp).balanceOf(address(this));
        if (yesCompBal > 0) {
            _swaprExactIn(swapr_router, yes_comp, yes_cur, yesCompBal, 0);
        }
        uint256 noCompBal = IERC20(no_comp).balanceOf(address(this));
        if (noCompBal > 0) {
            _swaprExactIn(swapr_router, no_comp, no_cur, noCompBal, 0);
        }
        // --- Step 6: Merge conditional collateral (YES/NO) back into base collateral (cur) ---
        if (futarchy_router != address(0) && proposal != address(0)) {
            uint256 yesCurBal = IERC20(yes_cur).balanceOf(address(this));
            uint256 noCurBal  = IERC20(no_cur).balanceOf(address(this));
            uint256 mergeAmt  = yesCurBal < noCurBal ? yesCurBal : noCurBal;
            if (mergeAmt > 0) {
                // Router will transferFrom both legs; approve both to MAX
                _ensureMaxAllowance(IERC20(yes_cur), futarchy_router);
                _ensureMaxAllowance(IERC20(no_cur),  futarchy_router);
                IFutarchyRouter(futarchy_router).mergePositions(proposal, cur, mergeAmt);
                emit ConditionalCollateralMerged(futarchy_router, proposal, cur, mergeAmt);
            }
        }

        // --- Step 7: Sell any remaining single-sided conditional collateral to base collateral on Swapr ---
        // After merging min(yes_cur, no_cur), at most one side should remain > 0.
        uint256 yesCurLeft = IERC20(yes_cur).balanceOf(address(this));
        uint256 noCurLeft  = IERC20(no_cur).balanceOf(address(this));
        if (yesCurLeft > 0) {
            _swaprExactIn(swapr_router, yes_cur, cur, yesCurLeft, 0);
        } else if (noCurLeft > 0) {
            _swaprExactIn(swapr_router, no_cur,  cur, noCurLeft,  0);
        }

        // --- Step 8: On-chain profit check in base collateral terms (signed) ---
        uint256 final_cur_balance = IERC20(cur).balanceOf(address(this));
        int256 signedProfit = int256(final_cur_balance) - int256(initial_cur_balance);
        require(signedProfit >= min_out_final, "min profit not met");
        emit ProfitVerified(initial_cur_balance, final_cur_balance, min_out_final - int256(amount_sdai_in));
    }

    receive() external payable {}

    // --- Owner withdrawals ---
    function withdrawToken(IERC20 token, address to, uint256 amount) external onlyOwner {
        require(to != address(0), "to=0");
        require(token.transfer(to, amount), "transfer failed");
    }

    function sweepToken(IERC20 token, address to) external onlyOwner {
        require(to != address(0), "to=0");
        uint256 bal = token.balanceOf(address(this));
        require(token.transfer(to, bal), "transfer failed");
    }

    function withdrawETH(address payable to, uint256 amount) external onlyOwner {
        require(to != address(0), "to=0");
        (bool ok, ) = to.call{value: amount}("");
        require(ok, "eth send failed");
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "newOwner=0");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "viaIR": true,
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":false,"internalType":"bytes","name":"buyOps","type":"bytes"}],"name":"BalancerBuyExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":false,"internalType":"bytes","name":"sellOps","type":"bytes"}],"name":"BalancerSellExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"comp","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CompositeAcquired","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"comp","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"ok","type":"bool"}],"name":"CompositeSplitAttempted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"proposal","type":"address"},{"indexed":true,"internalType":"address","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ConditionalCollateralMerged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"proposal","type":"address"},{"indexed":true,"internalType":"address","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ConditionalCollateralSplit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"InitialCollateralSnapshot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"MaxAllowanceEnsured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint160","name":"amount","type":"uint160"},{"indexed":false,"internalType":"uint48","name":"expiration","type":"uint48"}],"name":"Permit2AllowanceEnsured","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"initialBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"finalBalance","type":"uint256"},{"indexed":false,"internalType":"int256","name":"minProfit","type":"int256"}],"name":"ProfitVerified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"SwaprExactInExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"SwaprExactOutExecuted","type":"event"},{"inputs":[{"internalType":"uint256","name":"amountSdaiIn","type":"uint256"},{"internalType":"uint256","name":"minWethOut","type":"uint256"},{"internalType":"uint256","name":"minPnkOut","type":"uint256"}],"name":"buyPnkWithSdai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"sell_company_ops","type":"bytes"},{"internalType":"address","name":"balancer_router","type":"address"},{"internalType":"address","name":"balancer_vault","type":"address"},{"internalType":"address","name":"comp","type":"address"},{"internalType":"address","name":"cur","type":"address"},{"internalType":"bool","name":"yes_has_higher_price","type":"bool"},{"internalType":"address","name":"futarchy_router","type":"address"},{"internalType":"address","name":"proposal","type":"address"},{"internalType":"address","name":"yes_comp","type":"address"},{"internalType":"address","name":"no_comp","type":"address"},{"internalType":"address","name":"yes_cur","type":"address"},{"internalType":"address","name":"no_cur","type":"address"},{"internalType":"address","name":"yes_pool","type":"address"},{"internalType":"address","name":"no_pool","type":"address"},{"internalType":"address","name":"swapr_router","type":"address"},{"internalType":"uint256","name":"amount_sdai_in","type":"uint256"},{"internalType":"int256","name":"min_out_final","type":"int256"}],"name":"buy_conditional_arbitrage_balancer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"comp","type":"address"},{"internalType":"address","name":"cur","type":"address"},{"internalType":"bool","name":"yes_has_higher_price","type":"bool"},{"internalType":"address","name":"futarchy_router","type":"address"},{"internalType":"address","name":"proposal","type":"address"},{"internalType":"address","name":"yes_comp","type":"address"},{"internalType":"address","name":"no_comp","type":"address"},{"internalType":"address","name":"yes_cur","type":"address"},{"internalType":"address","name":"no_cur","type":"address"},{"internalType":"address","name":"yes_pool","type":"address"},{"internalType":"address","name":"no_pool","type":"address"},{"internalType":"address","name":"swapr_router","type":"address"},{"internalType":"uint256","name":"amount_sdai_in","type":"uint256"},{"internalType":"int256","name":"min_out_final","type":"int256"}],"name":"buy_conditional_arbitrage_pnk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountPnkIn","type":"uint256"},{"internalType":"uint256","name":"minWethOut","type":"uint256"},{"internalType":"uint256","name":"minSdaiOut","type":"uint256"}],"name":"sellPnkForSdai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"buy_company_ops","type":"bytes"},{"internalType":"address","name":"balancer_router","type":"address"},{"internalType":"address","name":"balancer_vault","type":"address"},{"internalType":"address","name":"comp","type":"address"},{"internalType":"address","name":"cur","type":"address"},{"internalType":"address","name":"futarchy_router","type":"address"},{"internalType":"address","name":"proposal","type":"address"},{"internalType":"address","name":"yes_comp","type":"address"},{"internalType":"address","name":"no_comp","type":"address"},{"internalType":"address","name":"yes_cur","type":"address"},{"internalType":"address","name":"no_cur","type":"address"},{"internalType":"address","name":"swapr_router","type":"address"},{"internalType":"uint256","name":"amount_sdai_in","type":"uint256"},{"internalType":"int256","name":"min_out_final","type":"int256"}],"name":"sell_conditional_arbitrage_balancer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"buy_company_ops","type":"bytes"},{"internalType":"address","name":"balancer_router","type":"address"},{"internalType":"address","name":"balancer_vault","type":"address"},{"internalType":"address","name":"comp","type":"address"},{"internalType":"address","name":"cur","type":"address"},{"internalType":"address","name":"futarchy_router","type":"address"},{"internalType":"address","name":"proposal","type":"address"},{"internalType":"address","name":"yes_comp","type":"address"},{"internalType":"address","name":"no_comp","type":"address"},{"internalType":"address","name":"yes_cur","type":"address"},{"internalType":"address","name":"no_cur","type":"address"},{"internalType":"address","name":"swapr_router","type":"address"},{"internalType":"uint256","name":"amount_sdai_in","type":"uint256"},{"internalType":"int256","name":"min_out_final","type":"int256"}],"name":"sell_conditional_arbitrage_pnk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"sweepToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

0x6080806040523461004f575f80546001600160a01b031916339081178255907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a36158579081620000548239f35b5f80fdfe60c0604052600436101561001a575b3615610018575f80fd5b005b5f803560e01c806301e33667146137a6578063258836fe146136815780634782f779146135ef5780638da5cb5b146135c8578063ce12e70d14613289578063d4b21c3314612a59578063de309fc314611acd578063de57a0ae14611259578063e7610d6814610685578063ea9f3f09146101435763f2fde38b1461009e575061000e565b34610140576020366003190112610140576100b7613864565b81546001600160a01b03808216926100d0338514613a80565b1691821561010e5782907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08580a36001600160a01b03191617815580f35b60405162461bcd60e51b815260206004820152600a60248201526906e65774f776e65723d360b41b6044820152606490fd5b80fd5b50346101405761015236613958565b9061016760018060a01b038554163314613a80565b610172831515613d1b565b61017a614a6c565b6040519061018782613b4e565b600282526101f85f602095604036888701377337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b36101b786613efb565b52736a023ccd1ff6f2045c3309768ead9e68f978f6e194856101d882613f1c565b526040516338ed173960e01b815293849283923091889060048601614420565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af180156105c957610663575b506040519084826024816370a0823160e01b968782523060048301525afa9182156105c9575f92610634575b50610255821515614347565b80610622575b50610264614b1d565b61026c6156ab565b6102746140ce565b8260011c918284039184831161060e575f9260405161029281613b33565b848152604051906102a282613b18565b7f7e5870ac540adfd01a213c829f2231c309623eb10002000000000000000000e9825260028b830152600160408301526060968783015260808201526102e783613efb565b526102f182613efb565b506040516102fe81613b33565b8481526040519061030e82613b18565b7fa91c413d8516164868f6cca19573fe38f88f5982000200000000000000000157825260018b8301528560408301528587830152608082015261035083613f1c565b5261035a82613f1c565b5060405161036781613b33565b8481526040519161037783613b18565b5f805160206157a2833981519152835260028b840152600460408401528683015260808201526103a682613f2c565b526103b081613f2c565b506040516103bd81613b33565b838152604051906103cd82613b18565b5f805160206157e2833981519152825260048a83015260036040830152848683015260808201526103fd82613f3c565b5261040781613f3c565b5060405161041481613b33565b8381526040519061042482613b18565b5f805160206157c2833981519152825260038a8301528460408301528486830152608082015261045382613f4c565b5261045d81613f4c565b506104688251614125565b9461047286613f2c565b526104ba87151595866105f6575b846040519661048e88613afd565b308852818c890152306040890152870152604051958694859463945bcec960e01b86526004860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156105c9576105d4575b50604051918252306004830152838260248173af204776c7245bf4147c2612bf6e5972ee4837015afa9182156105c9575f92610596575b50811561056757610525578380f35b106105305780808380f35b6064906040519062461bcd60e51b82526004820152601060248201526f1b5a5b881cd11052481b9bdd081b595d60821b6044820152fd5b60405162461bcd60e51b81526004810185905260076024820152666e6f207344414960c81b6044820152606490fd5b9091508381813d83116105c2575b6105ae8183613b84565b810103126105be5751905f610516565b5f80fd5b503d6105a4565b6040513d5f823e3d90fd5b6105ef903d805f833e6105e78183613b84565b810190614167565b505f6104df565b6105ff89614157565b61060882613efb565b52610480565b634e487b7160e01b5f52601160045260245ffd5b61062e9082101561437d565b5f61025b565b9091508481813d831161065c575b61064c8183613b84565b810103126105be5751905f610249565b503d610642565b61067e903d805f833e6106768183613b84565b8101906143bc565b505f61021d565b5034610140576106943661399f565b9d5094929b509799509597506106b760018060a09796971b038d54163314613a80565b6040516370a0823160e01b81523060048201529860208a6024816001600160a01b038d165afa998a15611070578d9a611225575b506040518a81526001600160a01b038a16907fb2f03ce105b3cd1f9fccfa1de78c921cd3ad2f01048d3a832c7ebb893fd347b990602090a261072e841515613d1b565b6107566001600160a01b0382167337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b31461403b565b6001600160a01b0385161515938480611213575b61077390613d52565b6001600160a01b038a16151580611201575b806111ef575b61079490613d92565b6001600160a01b038c161515806111dd575b806111cb575b6107b590613d92565b6107c0811515613d1b565b6107c861475a565b5f6107d16156ab565b6107d9614073565b6040516107e581613b33565b838152604051906107f582613b18565b5f805160206157c2833981519152825284602083015260036040830152856060830152608082015261082682613efb565b5261083081613efb565b5060405161083d81613b33565b8381526040519061084d82613b18565b5f805160206157e283398151915282526003602083015260046040830152846060830152608082015261087f82613f1c565b5261088981613f1c565b5060405161089681613b33565b838152604051906108a682613b18565b5f805160206157a28339815191528252600460208301526002604083015284606083015260808201526108d882613f2c565b526108e281613f2c565b506108ed8251614125565b936108f785613efb565b526109386040519461090886613afd565b308652846020870152306040870152846060870152604051958694859463945bcec960e01b86526004860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156105c9576111b1575b506040516370a0823160e01b815230600482015290602082602481736a023ccd1ff6f2045c3309768ead9e68f978f6e15afa9182156105c9575f9261117d575b505f826109ae610a29941515614347565b6109b66149bb565b6040516109c281613b4e565b600281526040366020830137736a023ccd1ff6f2045c3309768ead9e68f978f6e16109ec82613efb565b527337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b3610a0b82613f1c565b526040516338ed173960e01b815294859283923091600485016143e4565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af19182156105c9578e92611163575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215611158578392611121575b506040518281526001600160a01b038216907f7ea2559d46b5ca1045280b94e6bd226dc4c60c15c514f72d0fc10c788c80822d90602090a2610ac9821515613c6c565b858061110f575b1561109757610ae8876001600160a01b038316614bce565b6001600160a01b0387163b15611093576040516301abf04560e71b81526001600160a01b03808a16600483015290911660248201526044810191909152818180606481010381836001600160a01b038b165af18015610f3d5761107b575b50505b6040516370a0823160e01b81523060048201526020816024816001600160a01b0386165afa908115611070578d9161103e575b508a8161102b575b50506040516370a0823160e01b815230600482015290506020816024816001600160a01b0386165afa908115611020578c91610fee575b508581610fdb575b50505080610fc9575b610def575b50506040516370a0823160e01b8152306004820152906020826024816001600160a01b038a165afa918215610de4578892610db0575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215610da5578992610d68575b5060249660209594939285928415610d42575050610c5993614e91565b505b6040516370a0823160e01b815230600482015293849182906001600160a01b03165afa918215610d37578492610cff575b505f8051602061578283398151915292610cee90610cbc6001600160ff1b03808611159081610cf4575b50613ffb565b610cd181610cca8587613cc2565b1215613cda565b604051938493846040919493926060820195825260208201520152565b0390a180f35b90508411155f610cb6565b9291506020833d602011610d2f575b81610d1b60209383613b84565b810103126105be5791519091610cee610c8c565b3d9150610d0e565b6040513d86823e3d90fd5b9150809350610d55575b50505050610c5b565b610d5e93614e91565b505f808281610d4c565b9094939291506020813d602011610d9d575b81610d8760209383613b84565b810103126105be57519293919290916024610c3c565b3d9150610d7a565b6040513d8b823e3d90fd5b9091506020813d602011610ddc575b81610dcc60209383613b84565b810103126105be5751905f610c07565b3d9150610dbf565b6040513d8a823e3d90fd5b6040516370a0823160e01b81523060048201526020816024816001600160a01b038c165afa908115610fbe578a91610f8c575b506040516370a0823160e01b81523060048201526020816024816001600160a01b0389165afa908115610f81578b91610f4f575b5080821015610f4857505b80610e6d575b50610bd1565b610e80826001600160a01b038a16614bce565b610e93826001600160a01b038616614bce565b6001600160a01b0382163b15610f3957604051637abef8d160e01b81526001600160a01b03808516600483015287166024820152604481018290528a90818180606481010381836001600160a01b0389165af18015610f3d57610f25575b50506040519081526001600160a01b038681169381169216905f8051602061580283398151915290602090a45f8080610e67565b610f2e90613aea565b610f3957895f610ef1565b8980fd5b6040513d84823e3d90fd5b9050610e61565b90506020813d602011610f79575b81610f6a60209383613b84565b810103126105be57515f610e56565b3d9150610f5d565b6040513d8d823e3d90fd5b90506020813d602011610fb6575b81610fa760209383613b84565b810103126105be57515f610e22565b3d9150610f9a565b6040513d8c823e3d90fd5b506001600160a01b0382161515610bcc565b610fe59288614e91565b505f8085610bc3565b90506020813d602011611018575b8161100960209383613b84565b810103126105be57515f610bbb565b3d9150610ffc565b6040513d8e823e3d90fd5b6110359289614e91565b505f808a610b84565b90506020813d602011611068575b8161105960209383613b84565b810103126105be57515f610b7c565b3d915061104c565b6040513d8f823e3d90fd5b61108490613aea565b61108f578b5f610b46565b8b80fd5b8280fd5b827ff8e6e0bb33e12f1f8e97919c28e4df84e2aebf737d4bf32534deb9e737f228e69293604051602081019063dbceb00560e01b8252866024820152602481526110e081613b4e565b519082855af1906110ef613c16565b506040805194855291151560208501526001600160a01b031692a2610b49565b506001600160a01b0388161515610ad0565b925090506020823d602011611150575b8161113e60209383613b84565b810103126105be578d9151905f610a86565b3d9150611131565b6040513d85823e3d90fd5b611176903d805f833e6106768183613b84565b505f610a51565b91506020823d6020116111a9575b8161119860209383613b84565b810103126105be579051905f61099d565b3d915061118b565b6111c4903d805f833e6105e78183613b84565b505f61095d565b506001600160a01b03891615156107ac565b506001600160a01b03881615156107a6565b506001600160a01b038416151561078b565b506001600160a01b0383161515610785565b506001600160a01b038716151561076a565b9099506020813d602011611251575b8161124160209383613b84565b810103126105be5751985f6106eb565b3d9150611234565b5034610140576101c036600319011261014057611274613864565b61127c61387a565b6044351515604435036105be57611291613890565b9061129a6138a6565b9260a4356001600160a01b03811690036105be576112b66138bc565b926112bf6138d2565b946112c86138e8565b916112d16138ff565b956112da613916565b946112e361392d565b956112f860018060a01b038c54163314613a80565b6040516370a0823160e01b81523060048201529860208a6024816001600160a01b038d165afa998a15611020578c9a611a99575b5061133b610184351515613d1b565b6113636001600160a01b0384167337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b31461403b565b6001600160a01b038516151580611a87575b61137e90613d52565b6001600160a01b038916151580611a73575b80611a61575b61139f90613d92565b6001600160a01b038b16151580611a4f575b80611a3d575b6113c090613d92565b6113d3856001600160a01b038b16614bce565b6001600160a01b0385163b1561108f576040516301abf04560e71b81526001600160a01b0380881660048301528a1660248201526101843560448201528c90818180606481010381836001600160a01b038c165af18015610f3d57611a29575b50506040516101843581526001600160a01b038a811691888216918816907f96b6cd56b43ef9bd81ea4da2f5715eb8e6d0da9999e7cf964ae2932a20e0f0fd90602090a4602460208c604051928380926370a0823160e01b825230600483015260018060a01b03165afa8015611070578d906119f5575b6114ba9150610184351115613dc7565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038c165afa908115611070578d916119c1575b5061150f9161150461150992610184351115613e0a565b615016565b91615016565b906044351561198d57506115469061152e6101843560a4358d8b614e91565b611539811515613e98565b610184359185898b6150a6565b505b6040516370a0823160e01b815230600482015260208160248160a4356001600160a01b03165afa908115610f81578b9161195b575b506040516370a0823160e01b81523060048201526020816024816001600160a01b0388165afa908115611020578c91611929575b50808210156119215750915b82611850575b50505050506040516370a0823160e01b81523060048201526020816024817337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b35afa90811561180457879161181e575b508061180f575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b038a165afa9182156118045787926117d0575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215610de4578892611793575b506024966020959493928592841561176d57505061169493614e91565b505b6040516370a0823160e01b815230600482015293849182906001600160a01b03165afa801561115857839061172e575b5f8051602061578283398151915292506116f16001600160ff1b038083111590816117235750613ffb565b6117026101a435610cca8484613cc2565b6040805192835260208301919091526101a435908201528060608101610cee565b90508311155f610cb6565b506020823d602011611765575b8161174860209383613b84565b810103126105be575f8051602061578283398151915291516116c6565b3d915061173b565b9150809350611780575b50505050611696565b61178993614e91565b505f808281611777565b9094939291506020813d6020116117c8575b816117b260209383613b84565b810103126105be57519293919290916024611677565b3d91506117a5565b9091506020813d6020116117fc575b816117ec60209383613b84565b810103126105be5751905f611642565b3d91506117df565b6040513d89823e3d90fd5b61181890615244565b5f61160d565b90506020813d602011611848575b8161183960209383613b84565b810103126105be57515f611606565b3d915061182c565b61187990849061186b8260a4356001600160a01b0316614bce565b6001600160a01b0316614bce565b6001600160a01b0383163b15610f3957604051637abef8d160e01b81526001600160a01b03808616600483015282166024820152604481018390528a90818180606481010381836001600160a01b038a165af18015610f3d5761190d575b50506040519182526001600160a01b039081169381169216905f8051602061580283398151915290602090a45f808080806115c3565b61191690613aea565b610f3957895f6118d7565b9050916115bd565b90506020813d602011611953575b8161194460209383613b84565b810103126105be57515f6115b1565b3d9150611937565b90506020813d602011611985575b8161197660209383613b84565b810103126105be57515f61157d565b3d9150611969565b6119bb91506119a16101843585898b614e91565b6119ac811515613e4c565b610184359160a4358d8b6150a6565b50611548565b90506020813d6020116119ed575b816119dc60209383613b84565b810103126105be575161150f6114ed565b3d91506119cf565b506020813d602011611a21575b81611a0f60209383613b84565b810103126105be576114ba90516114aa565b3d9150611a02565b611a3290613aea565b61108f578b5f611433565b506001600160a01b03881615156113b7565b506001600160a01b03871615156113b1565b506001600160a01b0384161515611396565b5060a4356001600160a01b03161515611390565b506001600160a01b0386161515611375565b9099506020813d602011611ac5575b81611ab560209383613b84565b810103126105be5751985f61132c565b3d9150611aa8565b503461014057610220366003190112610140576004356001600160401b0381116125d157611aff903690600401613972565b60805260a052611b0d61387a565b6044356001600160a01b03811690036105be57611b28613890565b611b306138a6565b60a435151560a435036105be57611b456138bc565b611b4d6138d2565b93611b566138e8565b611b5e6138ff565b94611b67613916565b96611b7061392d565b94610184356001600160a01b03811690036105be576101a4356001600160a01b03811690036105be576101c4356001600160a01b03811690036105be57611bc160018060a01b038b54163314613a80565b6040516370a0823160e01b8152306004820152976020896024816001600160a01b038c165afa988915610f81578b99612a25575b50611c046101e4351515613d1b565b6001600160a01b038216151580612a13575b611c1f90613d52565b6001600160a01b038816151580612a01575b806129ef575b611c4090613d92565b6001600160a01b038a161515806129dd575b806129c8575b611c6190613d92565b611c74826001600160a01b038a16614bce565b6001600160a01b0382163b156124cb576040516301abf04560e71b81526001600160a01b038085166004830152891660248201526101e43560448201528b90818180606481010381836001600160a01b0389165af18015610f3d576129b4575b50506040516101e43581526001600160a01b0389811691858216918516907f96b6cd56b43ef9bd81ea4da2f5715eb8e6d0da9999e7cf964ae2932a20e0f0fd90602090a46040516370a0823160e01b81523060048201526020816024816001600160a01b038f165afa8015611020578c90612980575b611d5a91506101e4351115613dc7565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038c165afa8015611020578c9061294c575b611d9c91506101e4351115613e0a565b611da861018435615016565b8a611db56101a435615016565b9160a43515612914575090611dd6611df192886101e435916101c435614e91565b611de1811515613e98565b6101e43591848b6101c4356150a6565b505b6040516370a0823160e01b81523060048201526020816024816001600160a01b038a165afa908115611020578c916128e2575b506040516370a0823160e01b81523060048201526020816024816001600160a01b0387165afa908115611070578d916128b0575b50808210156128a85750945b856127e7575b5050505081612071575b50506040516370a0823160e01b815230600482015290506020816024816001600160a01b0389165afa908115612066578691612034575b506040516370a0823160e01b8152306004820152946020866024816001600160a01b0387165afa958615611804578796611ff8575b5060249560209493929184918315611fd15750611f0393506101c435614e91565b505b6040516370a0823160e01b815230600482015293849182906001600160a01b03165afa8015611158578390611f92575b5f805160206157828339815191529250611f606001600160ff1b038083111590816117235750613ffb565b611f7161020435610cca8484613cc2565b60408051928352602083019190915261020435908201528060608101610cee565b506020823d602011611fc9575b81611fac60209383613b84565b810103126105be575f805160206157828339815191529151611f35565b3d9150611f9f565b92505081611fe2575b505050611f05565b611fef926101c435614e91565b505f8082611fda565b95509291906020863d60201161202c575b8161201660209383613b84565b810103126105be57945194919290919083611ee2565b3d9150612009565b90506020813d60201161205e575b8161204f60209383613b84565b810103126105be57515f611ead565b3d9150612042565b6040513d88823e3d90fd5b6001600160a01b0381167337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b3036121295750506040516370a0823160e01b815230600482015290506020816024817337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b35afa9081156120665786916120f7575b50806120e8575b505b5f8080611e76565b6120f190615244565b5f6120de565b90506020813d602011612121575b8161211260209383613b84565b810103126105be57515f6120d7565b3d9150612105565b608051612139575b5050506120e0565b6001600160a01b038316156127ae5761215b836001600160a01b038316614449565b6044356001600160a01b0316612794575b6080516004116124cf57608060031960a051825160a051010301126124cf57600460a0510135906001600160401b03821161249d5760805160a0510160238360a0510101121561249d5760048260a051010135926121c984613ee4565b936121d76040519586613b84565b8085526020850190819460805160a0510160248360051b8360a051010101116124c75760248160a0510101925b60248360051b8360a05101010184106125d55750505050612229604460a05101613a73565b90606460a0510135926001600160401b03841161108f5760805160a0510160238560a0510101121561108f578b61226760048660a051010135613bfb565b946122756040519687613b84565b60048160a051010135865260805160a05101602460048360a0510101358360a051010101116125d15760a051602091600491810180830135906024018985013760a051010135860101528551156125a2576001600160a01b03818116906122db88613efb565b51511603612588575b5091849260406122f68d969497613efb565b51015260405194859363286f580d60e01b85526084850190608060048701525180915260a485019060a48160051b870101949187905b8282106124d3575050505091612362918493602460a0510135602486015215156044850152600319848303016064850152613fbd565b0381836001600160a01b0387165af18015611804576123c6575b507fde69c99d0290e9136275c349eb34d1087f4344a5eb3b4ce398f30cca48dacb0f6040519160018060a01b031691806123bb60805160a05183613c45565b0390a25f8080612131565b3d908188823e6123d68282613b84565b60608183810103126124cf5780516001600160401b03811161249d5761240190838301908301613f5c565b5060208101516001600160401b03811161249d57828201601f82840101121561249d5780820151602061243382613ee4565b6124406040519182613b84565b828152019184840160208360051b8387010101116124cb5791602083850101925b60208360051b828701010184106124a1575050505060408101516001600160401b03811161249d576124969282019101613f5c565b505f61237c565b8880fd5b8351916001600160a01b03831683036124c7576020818194829352019401939150612461565b8c80fd5b8a80fd5b8780fd5b929791949650929460a3198982030183528751608082019260018060a01b038251168352602082015193608060208501528451809152602060a08501950191905b80821061254c57505050600192602092826040859401516040830152606080910151910152980192019201928795938e97959361232c565b9091946020606060019260408951858060a01b038151168352858060a01b03858201511685840152015115156040820152019601920190612514565b6001600160a01b031661259a86613efb565b51525f6122e4565b60405162461bcd60e51b8152602060048201526007602482015266070617468733d360cc1b6044820152606490fd5b5080fd5b83356001600160401b038111612790576080602319828560a0510101825160a05101030112612790576040519061260b82613afd565b61261d6024828660a051010101613944565b82526044818560a051010101356001600160401b03811161278b5760805160a05101604382848860a05101010101121561278b57602481838760a05101010101359061266882613ee4565b916126766040519384613b84565b8083526020830160805160a0510160446060840285888c60a05101010101011161278357604483868a60a05101010101905b60446060840285888c60a051010101010182106126f9575050505060208084019190915260a08051860183016064013560408501525185019091016084013560608301529082529384019301612204565b60608260805160a05101031261277a576040518060608101106001600160401b036060830111176127665760609181836020930160405261273985613944565b8152612746838601613944565b8382015261275660408601613a73565b60408201528152019101906126a8565b634e487b7160e01b5f52604160045260245ffd5b50505050508f80fd5b505050508f80fd5b508f80fd5b8e80fd5b6127a96044356001600160a01b038316614bce565b61216c565b60405162461bcd60e51b8152602060048201526011602482015270062616c616e63657220726f757465723d3607c1b6044820152606490fd5b61280191839161186b9083906001600160a01b0316614bce565b6001600160a01b0381163b15610f3957604051637abef8d160e01b81526001600160a01b03808416600483015284166024820152604481018590528a90818180606481010381836001600160a01b0388165af18015610f3d57612894575b50506040518481526001600160a01b038481169381169216905f8051602061580283398151915290602090a45f808080611e6c565b61289d90613aea565b610f3957895f61285f565b905094611e66565b90506020813d6020116128da575b816128cb60209383613b84565b810103126105be57515f611e5a565b3d91506128be565b90506020813d60201161290c575b816128fd60209383613b84565b810103126105be57515f611e26565b3d91506128f0565b612946925061292b6101e435858c6101c435614e91565b90612937821515613e4c565b886101e435936101c4356150a6565b50611df3565b506020813d602011612978575b8161296660209383613b84565b810103126105be57611d9c9051611d8c565b3d9150612959565b506020813d6020116129ac575b8161299a60209383613b84565b810103126105be57611d5a9051611d4a565b3d915061298d565b6129bd90613aea565b6124cb578a5f611cd4565b506101c4356001600160a01b03161515611c58565b506001600160a01b0387161515611c52565b506001600160a01b0381161515611c37565b506001600160a01b0385161515611c31565b506001600160a01b0383161515611c16565b9098506020813d602011612a51575b81612a4160209383613b84565b810103126105be5751975f611bf5565b3d9150612a34565b50346105be57612a683661399f565b9d91989994939c600160a09d929c9d999794991b600190035f54163314612a8e90613a80565b6040516370a0823160e01b81523060048201529c8d806001600160a01b038e165a92602491602094fa9d8e156105c9575f9e613254575b506040518e81526001600160a01b038d16907fb2f03ce105b3cd1f9fccfa1de78c921cd3ad2f01048d3a832c7ebb893fd347b990602090a2612b10836001600160a01b038e16614449565b6001600160a01b03811661323b575b505f806040518386823780848101838152039082865af1612b3e613c16565b50156131f6577f039f1e3426eb05ff8263467f0ccd63de0af468a20960885b56ee6fbb53ac1be691612b7e60405192839260018060a01b03169583613c45565b0390a26040516370a0823160e01b81523060048201526020816024816001600160a01b0388165afa9081156105c9575f916131c4575b506040518181526001600160a01b038516907f7ea2559d46b5ca1045280b94e6bd226dc4c60c15c514f72d0fc10c788c80822d90602090a2612bf7811515613c6c565b6001600160a01b03851615159384806131b2575b1561313a57612c23866001600160a01b038316614bce565b6001600160a01b0386163b156105be576040516301abf04560e71b81526001600160a01b038089166004830152909116602482015260448101919091525f8180606481010381836001600160a01b038a165af180156105c957613127575b505b6040516370a0823160e01b81523060048201528d906020816024816001600160a01b0387165afa91821561311b57916130e9575b508b816130d6575b50506040516370a0823160e01b815230600482015290506020816024816001600160a01b0386165afa908115611070578d916130a4575b508581613091575b5050508061307f575b612ecb575b50506040516370a0823160e01b8152306004820152906020826024816001600160a01b038b165afa918215610da5578992612e97575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215610fbe578a92612e5a575b5060249760209594939285928415612e34575050612d9493614e91565b505b6040516370a0823160e01b815230600482015294859182906001600160a01b03165afa928315612e29578593612df1575b50610cd1610cee9185612dec5f8051602061578283398151915297610cca8789613cc2565b613cc2565b9392506020843d602011612e21575b81612e0d60209383613b84565b810103126105be5792519192610cd1612dc7565b3d9150612e00565b6040513d87823e3d90fd5b9150809350612e47575b50505050612d96565b612e5093614e91565b505f808281612e3e565b9094939291506020813d602011612e8f575b81612e7960209383613b84565b810103126105be57519293919290916024612d77565b3d9150612e6c565b9091506020813d602011612ec3575b81612eb360209383613b84565b810103126105be5751905f612d42565b3d9150612ea6565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038d165afa908115610f81578b9161304d575b506040516370a0823160e01b81523060048201526001600160a01b0385169190602081602481865afa908115611070578d9161301b575b50808210156130135750905b81612f4e575b5050612d0c565b612f6c908390612f67826001600160a01b038e16614bce565b614bce565b6001600160a01b0382163b156124cb57604051637abef8d160e01b81526001600160a01b03808516600483015287166024820152604481018290528b90818180606481010381836001600160a01b0389165af18015610f3d57612fff575b50506040519081526001600160a01b038681169381169216905f8051602061580283398151915290602090a45f808080612f47565b61300890613aea565b6124cb578a5f612fca565b905090612f41565b90506020813d602011613045575b8161303660209383613b84565b810103126105be57515f612f35565b3d9150613029565b90506020813d602011613077575b8161306860209383613b84565b810103126105be57515f612efe565b3d915061305b565b506001600160a01b0382161515612d07565b61309b9288614e91565b505f8085612cfe565b90506020813d6020116130ce575b816130bf60209383613b84565b810103126105be57515f612cf6565b3d91506130b2565b6130e09289614e91565b505f808b612cbf565b90506020813d602011613113575b8161310460209383613b84565b810103126105be57515f612cb7565b3d91506130f7565b604051903d90823e3d90fd5b613132919d50613aea565b5f9b5f612c81565b7ff8e6e0bb33e12f1f8e97919c28e4df84e2aebf737d4bf32534deb9e737f228e6905f80604051602081019063dbceb00560e01b82528660248201526024815261318381613b4e565b519082855af190613192613c16565b506040805194855291151560208501526001600160a01b031692a2612c83565b506001600160a01b0387161515612c0b565b90506020813d6020116131ee575b816131df60209383613b84565b810103126105be57515f612bb4565b3d91506131d2565b60405162461bcd60e51b815260206004820152601860248201527f42616c616e636572206275792073776170206661696c656400000000000000006044820152606490fd5b61324e906001600160a01b038d16614bce565b5f612b1f565b9b9d5060208c3d602011613281575b8161327060209383613b84565b810103126105be578d9b519d612ac5565b3d9150613263565b346105be5761329736613958565b6132ab60018060a01b035f54163314613a80565b6132b6831515613d1b565b6132be61475a565b6132c66156ab565b906132cf614073565b935f604051936132de85613b33565b8185526040516132ed81613b18565b5f805160206157c28339815191528152602095838783015260036040830152846060830152608082015261332088613efb565b5261332a87613efb565b5060405161333781613b33565b8281526040519061334782613b18565b5f805160206157e2833981519152825260038783015260046040830152836060830152608082015261337888613f1c565b5261338287613f1c565b5060405161338f81613b33565b8281526040519061339f82613b18565b5f805160206157a283398151915282526004878301526002604083015283606083015260808201526133d088613f2c565b526133da87613f2c565b506133e58151614125565b926133ef84613efb565b5285151596876135b0575b6134396040519461340a86613afd565b3086528488870152306040870152846060870152604051958694859463945bcec960e01b86526004860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156105c957613596575b506040516370a0823160e01b815230600482015292736a023ccd1ff6f2045c3309768ead9e68f978f6e1908385602481855afa9485156105c9575f95613567575b5084956134ae5f961515614347565b613555575b506134bc6149bb565b60408051936134ca85613b4e565b6002855236908501376134dc83613efb565b527337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b36134fb83613f1c565b5261351c60405194859384936338ed173960e01b8552309260048601614420565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af180156105c95761354257005b610018903d805f833e6106768183613b84565b6135619086101561437d565b856134b3565b94508385813d831161358f575b61357e8183613b84565b810103126105be575f94519461349f565b503d613574565b6135a9903d805f833e6105e78183613b84565b508461345e565b6135b987614157565b6135c285613f2c565b526133fa565b346105be575f3660031901126105be575f546040516001600160a01b039091168152602090f35b346105be5760403660031901126105be576004356001600160a01b03818116918290036105be575f80809361362982948354163314613a80565b613634811515613ab8565b602435905af1613642613c16565b501561364a57005b60405162461bcd60e51b815260206004820152600f60248201526e195d1a081cd95b990819985a5b1959608a1b6044820152606490fd5b346105be5760403660031901126105be5761369a613864565b6136a261387a565b5f5490916001600160a01b03916136bc9083163314613a80565b6136c98284161515613ab8565b166040516370a0823160e01b81523060048201526020928382602481865afa9081156105c95784925f92613773575b5060405163a9059cbb60e01b81526001600160a01b0390911660048201526024810191909152918290815f81604481015b03925af19081156105c957610018925f92613746575b5050613bbd565b6137659250803d1061376c575b61375d8183613b84565b810190613ba5565b828061373f565b503d613753565b8381949293503d831161379f575b61378b8183613b84565b810103126105be57905183916137296136f8565b503d613781565b346105be5760603660031901126105be576137bf613864565b60206138296137cc61387a565b5f546001600160a01b039491906137e69086163314613a80565b6137f38582161515613ab8565b60405163a9059cbb60e01b81526001600160a01b0390911660048201526044803560248301529094859384925f92918491820190565b0393165af180156105c957610018915f91613845575b50613bbd565b61385e915060203d60201161376c5761375d8183613b84565b8261383f565b600435906001600160a01b03821682036105be57565b602435906001600160a01b03821682036105be57565b606435906001600160a01b03821682036105be57565b608435906001600160a01b03821682036105be57565b60c435906001600160a01b03821682036105be57565b60e435906001600160a01b03821682036105be57565b61010435906001600160a01b03821682036105be57565b61012435906001600160a01b03821682036105be57565b61014435906001600160a01b03821682036105be57565b61016435906001600160a01b03821682036105be57565b35906001600160a01b03821682036105be57565b60609060031901126105be57600435906024359060443590565b9181601f840112156105be578235916001600160401b0383116105be57602083818601950101116105be57565b6101c06003198201126105be57600435906001600160401b0382116105be576139ca91600401613972565b90916001600160a01b0360243581811681036105be579160443582811681036105be579160643581811681036105be579160843582811681036105be579160a43581811681036105be579160c43582811681036105be579160e43581811681036105be57916101043582811681036105be57916101243581811681036105be57916101443582811681036105be57916101643590811681036105be579061018435906101a43590565b359081151582036105be57565b15613a8757565b60405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b6044820152606490fd5b15613abf57565b606460405162461bcd60e51b81526020600482015260046024820152630746f3d360e41b6044820152fd5b6001600160401b03811161276657604052565b608081019081106001600160401b0382111761276657604052565b60a081019081106001600160401b0382111761276657604052565b602081019081106001600160401b0382111761276657604052565b606081019081106001600160401b0382111761276657604052565b60c081019081106001600160401b0382111761276657604052565b90601f801991011681019081106001600160401b0382111761276657604052565b908160209103126105be575180151581036105be5790565b15613bc457565b60405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b6001600160401b03811161276657601f01601f191660200190565b3d15613c40573d90613c2782613bfb565b91613c356040519384613b84565b82523d5f602084013e565b606090565b90918060409360208452816020850152848401375f828201840152601f01601f1916010190565b15613c7357565b60405162461bcd60e51b815260206004820152602160248201527f4661696c656420746f206163717569726520636f6d706f7369746520746f6b656044820152603760f91b6064820152608490fd5b81810392915f13801582851316918412161761060e57565b15613ce157565b60405162461bcd60e51b81526020600482015260126024820152711b5a5b881c1c9bd99a5d081b9bdd081b595d60721b6044820152606490fd5b15613d2257565b60405162461bcd60e51b81526020600482015260086024820152670616d6f756e743d360c41b6044820152606490fd5b15613d5957565b60405162461bcd60e51b81526020600482015260116024820152700726f757465722f70726f706f73616c3d3607c1b6044820152606490fd5b15613d9957565b60405162461bcd60e51b81526020600482015260066024820152650616464723d360d41b6044820152606490fd5b15613dce57565b60405162461bcd60e51b815260206004820152601460248201527334b739bab33334b1b4b2b73a102ca2a9afb1bab960611b6044820152606490fd5b15613e1157565b60405162461bcd60e51b815260206004820152601360248201527234b739bab33334b1b4b2b73a102727afb1bab960691b6044820152606490fd5b15613e5357565b60405162461bcd60e51b815260206004820152601960248201527f4e4f2065786163742d696e2070726f6475636564207a65726f000000000000006044820152606490fd5b15613e9f57565b60405162461bcd60e51b815260206004820152601a60248201527f5945532065786163742d696e2070726f6475636564207a65726f0000000000006044820152606490fd5b6001600160401b0381116127665760051b60200190565b805115613f085760200190565b634e487b7160e01b5f52603260045260245ffd5b805160011015613f085760400190565b805160021015613f085760600190565b805160031015613f085760800190565b805160041015613f085760a00190565b9080601f830112156105be57815190602091613f7781613ee4565b93613f856040519586613b84565b81855260208086019260051b8201019283116105be57602001905b828210613fae575050505090565b81518152908301908301613fa0565b91908251928382525f5b848110613fe7575050825f602080949584010152601f8019910116010190565b602081830181015184830182015201613fc7565b1561400257565b60405162461bcd60e51b815260206004820152601160248201527062616c616e636520746f6f206c6172676560781b6044820152606490fd5b1561404257565b60405162461bcd60e51b8152602060048201526009602482015268636f6d70213d504e4b60b81b6044820152606490fd5b604080519161408183613afd565b6003835282915f5b6060808210156140c6578251602092916140a282613b18565b5f825283905f828401525f868401525f818401526080830152828801015201614089565b505050909150565b604090604051916140de83613b69565b60058352825f5b60a081106140f257505050565b602090835161410081613b18565b5f8152825f818301525f8683015260605f8184015260808301528285010152016140e5565b9061412f82613ee4565b61413c6040519182613b84565b828152809261414d601f1991613ee4565b0190602036910137565b600160ff1b811461060e575f0390565b60209081818403126105be578051906001600160401b0382116105be57019180601f840112156105be57825161419c81613ee4565b936141aa6040519586613b84565b818552838086019260051b8201019283116105be578301905b8282106141d1575050505090565b815181529083019083016141c3565b9081518082526020808093019301915f5b8281106141ff575050505090565b83516001600160a01b0316855293810193928101926001016141f1565b94939290610120928387015f88526020948589015282518091526101409085828a01928260051b8b01019401915f905b8a8383106142e55791505084606095935061426e9492500360408a01526141e0565b82516001600160a01b0390811688840152848401511515608089015260408401511660a0880152910151151560c086015284810360e08601528251808252908201928201915f5b8281106142d15750505050610100661fffffffffffff91930152565b8351855293810193928101926001016142b5565b978061433660019394959698829a9b61013f1990820301865289519060a090825181528483015185820152604080840151908201526060808401519082015281608080940151938201520190613fbd565b97019201920190929196959661424c565b1561434e57565b60405162461bcd60e51b81526020600482015260076024820152660dcde40ae8aa8960cb1b6044820152606490fd5b1561438457565b60405162461bcd60e51b815260206004820152601060248201526f1b5a5b8815d15512081b9bdd081b595d60821b6044820152606490fd5b906020828203126105be5781516001600160401b0381116105be576143e19201613f5c565b90565b61440c63d141dd849360809396959683525f602084015260a0604084015260a08301906141e0565b6001600160a01b0390951660608201520152565b9063d141dd849360809361440c929796978452602084015260a0604084015260a08301906141e0565b91909160018060a01b038091166040805192636eb1769f60e11b9586855260049630888701526e22d473030f116ddee9f6b43ac78ba3916024968388820152602092604491848184818c5afa90811561467c578587858f8c8f958f905f98614720575b505f1997600181016145de575b50509550505050505051908152308b8201528489820152838183818b5afa9081156145d4578486928a925f91614592575b50905f80516020615762833981519152918a51908152a3833b156105be578480928888519c8d6387517c4560e01b90528d01521680988b01528901525f886084818365ffffffffffff968760648401525af1978815614588577f4871c6f66188da2f442cdab9920447df48710c721ba67e79f01001ebfa3d4ae995969798614579575b508351928352820152a3565b61458290613aea565b5f61456d565b84513d5f823e3d90fd5b935050905081813d83116145cd575b6145ab8183613b84565b810103126105be57875f805160206157628339815191528587935190916144ea565b503d6145a1565b87513d5f823e3d90fd5b614686575b50945050505050519063095ea7b360e01b8252868d8301528a820152848184815f8d5af190811561467c575f9161465f575b5015614629575f898587858f8c8e876144b9565b865162461bcd60e51b8152808c018590526012818b015271185c1c1c9bdd99481cd95d0819985a5b195960721b81840152606490fd5b6146769150853d871161376c5761375d8183613b84565b5f614615565b88513d5f823e3d90fd5b5f809251978896879563095ea7b360e01b87528601528401525af1908115614716575f916146f9575b50156146c157898587858f8c8e6145e3565b875162461bcd60e51b8152808d018690526014818c015273185c1c1c9bdd99481c995cd95d0819985a5b195960621b81850152606490fd5b6147109150863d881161376c5761375d8183613b84565b5f6146af565b89513d5f823e3d90fd5b97505050505050905081813d8311614753575b61473d8183613b84565b810103126105be5751898587858f8c8e5f6144ac565b503d614733565b60408051636eb1769f60e11b808252600490308284015273ba12222222228d8ba445958a75a0704d566bf2c893602491858386015260209260449073af204776c7245bf4147c2612bf6e5972ee48370196858184818b5afa9081156148ef57918991879594935f91614989575b505f199060018101614853575b505085519788948552309085015283015281875afa90811561484a575f9161480e575b5f80516020615762833981519152935051908152a3565b90508183813d8311614843575b6148258183613b84565b810103126105be575f805160206157628339815191529251906147f7565b503d61481b565b513d5f823e3d90fd5b919394955091506148f9575b84519063095ea7b360e01b8252898883015282820152858184815f8c5af19081156148ef575f916148d2575b501561489d5790878593925f806147d4565b71185c1c1c9bdd99481cd95d0819985a5b195960721b606492601288938888519562461bcd60e51b8752860152840152820152fd5b6148e99150863d881161376c5761375d8183613b84565b5f61488b565b85513d5f823e3d90fd5b845163095ea7b360e01b815289888201525f83820152868185815f8d5af190811561497f575f91614962575b5061485f57845162461bcd60e51b815280880187905260148184015273185c1c1c9bdd99481c995cd95d0819985a5b195960621b81850152606490fd5b6149799150873d891161376c5761375d8183613b84565b5f614925565b86513d5f823e3d90fd5b9250509381813d83116149b4575b6149a18183613b84565b810103126105be5785938991515f6147c7565b503d614997565b60408051636eb1769f60e11b808252600490308284015273e43e60736b1cb4a75ad25240e2f9a62bff65c0c0936024918583860152602092604490736a023ccd1ff6f2045c3309768ead9e68f978f6e196858184818b5afa9081156148ef57918991879594935f9161498957505f19906001810161485357505085519788948552309085015283015281875afa90811561484a575f9161480e575f80516020615762833981519152935051908152a3565b60408051636eb1769f60e11b808252600490308284015273e43e60736b1cb4a75ad25240e2f9a62bff65c0c09360249185838601526020926044907337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b396858184818b5afa9081156148ef57918991879594935f9161498957505f19906001810161485357505085519788948552309085015283015281875afa90811561484a575f9161480e575f80516020615762833981519152935051908152a3565b60408051636eb1769f60e11b808252600490308284015273ba12222222228d8ba445958a75a0704d566bf2c8936024918583860152602092604490736a023ccd1ff6f2045c3309768ead9e68f978f6e196858184818b5afa9081156148ef57918991879594935f9161498957505f19906001810161485357505085519788948552309085015283015281875afa90811561484a575f9161480e575f80516020615762833981519152935051908152a3565b60408051636eb1769f60e11b808252306004808401919091526001600160a01b0386811660248501529395948416936020939092908481604481895afa90811561467c579187939186935f91614dea575b505f199060018101614cbd575b50508851908152309181019182526001600160a01b039097166020820152869081906040010381875afa94851561497f575f95614c7f575b505f80516020615762833981519152939495519586521693a3565b9394508284813d8311614cb6575b614c978183613b84565b810103126105be575f8051602061576283398151915293519493614c64565b503d614c8d565b919350919350614d5e575b87519063095ea7b360e01b825284881684830152602482015284816044815f8a5af190811561467c575f91614d41575b5015614d0957859184915f80614c2c565b865162461bcd60e51b81528083018590526012602482015271185c1c1c9bdd99481cd95d0819985a5b195960721b6044820152606490fd5b614d589150853d871161376c5761375d8183613b84565b5f614cf8565b875163095ea7b360e01b8152848816848201525f602482015285816044815f8b5af1908115614716575f91614dcd575b50614cc857875162461bcd60e51b81528084018690526014602482015273185c1c1c9bdd99481c995cd95d0819985a5b195960621b6044820152606490fd5b614de49150863d881161376c5761375d8183613b84565b5f614d8e565b93809295508491503d8311614e17575b614e048183613b84565b810103126105be5786928592515f614c1f565b503d614dfa565b15614e2557565b60405162461bcd60e51b815260206004820152600e60248201526d0737761707220726f757465723d360941b6044820152606490fd5b15614e6257565b60405162461bcd60e51b81526020600482015260076024820152660746f6b656e3d360cc1b6044820152606490fd5b6001600160a01b039493909185831691908690614eaf841515614e1e565b16928315158061500b575b614ec390614e5b565b811561500157614ed39084614bce565b604080519160e083018381106001600160401b03821117612766578252848352602097808985019716968781528385013081526060860142815260808701908582528460a08901935f85528160c08b01965f8852818b519c8d63178ca23160e31b9052511660048d0152511660248b0152511660448901525160648801525160848701525160a4860152511660c4840152878360e4815f885af18015614ff7575f90614faa575b7f5daa39fce4745a2a9e6137131383e8405e80edb12e37c562f590c5f294ed19d5935080988351928352820152a4565b508783813d8311614ff0575b614fc08183613b84565b810103126105be577f5daa39fce4745a2a9e6137131383e8405e80edb12e37c562f590c5f294ed19d59251614f7a565b503d614fb6565b82513d5f823e3d90fd5b505f955050505050565b508487161515614eba565b6001600160a01b031680156150a05760206004916040519283809263ddca3f4360e01b82525afa5f9181615060575b506150505750606490565b62ffffff81166143e15750606490565b9091506020813d602011615098575b8161507c60209383613b84565b810103126105be575162ffffff811681036105be57905f615045565b3d915061506f565b50606490565b919594929391926001600160a01b0380851693909283906150c8861515614e1e565b169485151580615239575b6150dc90614e5b565b811561522d576150ec9086614bce565b60409182516101008101918183106001600160401b03841117612766578592855287825260209a838c84019116998a8252848785019162ffffff8091168352606086019030825260808701934285528360a08901968b885260c08a0198895260e08a01995f8b528d519e8f91631b67c43360e31b835251169060040152511660248d0152511660448b0152511660648901525160848801525160a48701525160c4860152511660e4840152878385815a610104925f91f18015614ff7575f906151e0575b7fcb3796b31ba09ffbc48bd2abe64550ce61698c9e170bed66c7f6c556118af6a3935080988351928352820152a4565b508783813d8311615226575b6151f68183613b84565b810103126105be577fcb3796b31ba09ffbc48bd2abe64550ce61698c9e170bed66c7f6c556118af6a392516151b0565b503d6151ec565b505f9750505050505050565b5088841615156150d3565b61524f811515613d1b565b615257614a6c565b60409081519161526683613b4e565b600283526020918136848601377337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b361529185613efb565b526152d45f736a023ccd1ff6f2045c3309768ead9e68f978f6e192836152b688613f1c565b528451809381926338ed173960e01b835260049930918b85016143e4565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af1801561564757615691575b50815183816024816370a0823160e01b95868252308a8301525afa908115615647575f91615664575b5061532e811515614347565b615336614b1d565b61533e6156ab565b6153466140ce565b8260011c92838103818111615651575f93929161557091885161536881613b33565b86815289519061537782613b18565b7f7e5870ac540adfd01a213c829f2231c309623eb10002000000000000000000e9825260028c83015260018b8301526060988983015260808201526153bb85613efb565b526153c584613efb565b5088516153d181613b33565b8681528951906153e082613b18565b7fa91c413d8516164868f6cca19573fe38f88f5982000200000000000000000157825260018c830152878b8301528789830152608082015261542185613f1c565b5261542b84613f1c565b50885161543781613b33565b86815289519161544683613b18565b5f805160206157a2833981519152835260028c8401528c8b84015288830152608082015261547384613f2c565b5261547d83613f2c565b50875161548981613b33565b85815288519061549882613b18565b5f805160206157e283398151915282528b8b83015260038a830152868883015260808201526154c684613f3c565b526154d083613f3c565b5087516154dc81613b33565b8581528851906154eb82613b18565b5f805160206157c2833981519152825260038b830152868a8301528688830152608082015261551984613f4c565b5261552383613f4c565b5061552e8451614125565b9061553882613f2c565b528488519661554688613afd565b308089528b89018390528a890152870152875163945bcec960e01b815295869485948c860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156156475761562d575b5081519081523084820152828160248173af204776c7245bf4147c2612bf6e5972ee4837015afa908115614ff7575f91615600575b50156155d557505050565b5162461bcd60e51b81529182015260076024820152666e6f207344414960c81b604482015260649150fd5b90508281813d8311615626575b6156178183613b84565b810103126105be57515f6155ca565b503d61560d565b615640903d805f833e6105e78183613b84565b505f615595565b83513d5f823e3d90fd5b601189634e487b7160e01b5f525260245ffd5b90508381813d831161568a575b61567b8183613b84565b810103126105be57515f615322565b503d615671565b6156a4903d805f833e6106768183613b84565b505f6152f9565b604051906156b882613b69565b6005825260a0366020840137739c58bacc331c9aa871afd802db6379a98e80cedb61575e8373af204776c7245bf4147c2612bf6e5972ee4837016156fb82613efb565b5273c0d871bd13ebdf5c4ff059d8243fb38210608bd661571a82613f1c565b52736a023ccd1ff6f2045c3309768ead9e68f978f6e161573982613f2c565b5273e0ed85f76d9c552478929fab44693e03f0899f2361575882613f3c565b52613f4c565b5256feb6174191c8a1b8338dcc8711e5edf88685ae0a57f03b361e2bdf8979f6288bd5318296ace369901373a62c2153c5e87356175630ec782af9e8b7c9385f3d1e80a99fd9950b5d5dceeaf4939e221dca8ca9b938ab00010000000000000000002540d2cbc586dd8df50001cdba3f65cd4bbc32d596000200000000000000000154480d4f66cc41a1b6784a53a10890e5ece31d75c000020000000000000000014edc43ce728a1135c1396673372fa69f30fe424cb172093e4198538d75e54f3c2ba264697066735822122041b33bb4b1d53333712e272022b62ced2cb435c7762e56e1d42b67bee10ca51d64736f6c63430008180033

Deployed Bytecode

0x60c0604052600436101561001a575b3615610018575f80fd5b005b5f803560e01c806301e33667146137a6578063258836fe146136815780634782f779146135ef5780638da5cb5b146135c8578063ce12e70d14613289578063d4b21c3314612a59578063de309fc314611acd578063de57a0ae14611259578063e7610d6814610685578063ea9f3f09146101435763f2fde38b1461009e575061000e565b34610140576020366003190112610140576100b7613864565b81546001600160a01b03808216926100d0338514613a80565b1691821561010e5782907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08580a36001600160a01b03191617815580f35b60405162461bcd60e51b815260206004820152600a60248201526906e65774f776e65723d360b41b6044820152606490fd5b80fd5b50346101405761015236613958565b9061016760018060a01b038554163314613a80565b610172831515613d1b565b61017a614a6c565b6040519061018782613b4e565b600282526101f85f602095604036888701377337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b36101b786613efb565b52736a023ccd1ff6f2045c3309768ead9e68f978f6e194856101d882613f1c565b526040516338ed173960e01b815293849283923091889060048601614420565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af180156105c957610663575b506040519084826024816370a0823160e01b968782523060048301525afa9182156105c9575f92610634575b50610255821515614347565b80610622575b50610264614b1d565b61026c6156ab565b6102746140ce565b8260011c918284039184831161060e575f9260405161029281613b33565b848152604051906102a282613b18565b7f7e5870ac540adfd01a213c829f2231c309623eb10002000000000000000000e9825260028b830152600160408301526060968783015260808201526102e783613efb565b526102f182613efb565b506040516102fe81613b33565b8481526040519061030e82613b18565b7fa91c413d8516164868f6cca19573fe38f88f5982000200000000000000000157825260018b8301528560408301528587830152608082015261035083613f1c565b5261035a82613f1c565b5060405161036781613b33565b8481526040519161037783613b18565b5f805160206157a2833981519152835260028b840152600460408401528683015260808201526103a682613f2c565b526103b081613f2c565b506040516103bd81613b33565b838152604051906103cd82613b18565b5f805160206157e2833981519152825260048a83015260036040830152848683015260808201526103fd82613f3c565b5261040781613f3c565b5060405161041481613b33565b8381526040519061042482613b18565b5f805160206157c2833981519152825260038a8301528460408301528486830152608082015261045382613f4c565b5261045d81613f4c565b506104688251614125565b9461047286613f2c565b526104ba87151595866105f6575b846040519661048e88613afd565b308852818c890152306040890152870152604051958694859463945bcec960e01b86526004860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156105c9576105d4575b50604051918252306004830152838260248173af204776c7245bf4147c2612bf6e5972ee4837015afa9182156105c9575f92610596575b50811561056757610525578380f35b106105305780808380f35b6064906040519062461bcd60e51b82526004820152601060248201526f1b5a5b881cd11052481b9bdd081b595d60821b6044820152fd5b60405162461bcd60e51b81526004810185905260076024820152666e6f207344414960c81b6044820152606490fd5b9091508381813d83116105c2575b6105ae8183613b84565b810103126105be5751905f610516565b5f80fd5b503d6105a4565b6040513d5f823e3d90fd5b6105ef903d805f833e6105e78183613b84565b810190614167565b505f6104df565b6105ff89614157565b61060882613efb565b52610480565b634e487b7160e01b5f52601160045260245ffd5b61062e9082101561437d565b5f61025b565b9091508481813d831161065c575b61064c8183613b84565b810103126105be5751905f610249565b503d610642565b61067e903d805f833e6106768183613b84565b8101906143bc565b505f61021d565b5034610140576106943661399f565b9d5094929b509799509597506106b760018060a09796971b038d54163314613a80565b6040516370a0823160e01b81523060048201529860208a6024816001600160a01b038d165afa998a15611070578d9a611225575b506040518a81526001600160a01b038a16907fb2f03ce105b3cd1f9fccfa1de78c921cd3ad2f01048d3a832c7ebb893fd347b990602090a261072e841515613d1b565b6107566001600160a01b0382167337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b31461403b565b6001600160a01b0385161515938480611213575b61077390613d52565b6001600160a01b038a16151580611201575b806111ef575b61079490613d92565b6001600160a01b038c161515806111dd575b806111cb575b6107b590613d92565b6107c0811515613d1b565b6107c861475a565b5f6107d16156ab565b6107d9614073565b6040516107e581613b33565b838152604051906107f582613b18565b5f805160206157c2833981519152825284602083015260036040830152856060830152608082015261082682613efb565b5261083081613efb565b5060405161083d81613b33565b8381526040519061084d82613b18565b5f805160206157e283398151915282526003602083015260046040830152846060830152608082015261087f82613f1c565b5261088981613f1c565b5060405161089681613b33565b838152604051906108a682613b18565b5f805160206157a28339815191528252600460208301526002604083015284606083015260808201526108d882613f2c565b526108e281613f2c565b506108ed8251614125565b936108f785613efb565b526109386040519461090886613afd565b308652846020870152306040870152846060870152604051958694859463945bcec960e01b86526004860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156105c9576111b1575b506040516370a0823160e01b815230600482015290602082602481736a023ccd1ff6f2045c3309768ead9e68f978f6e15afa9182156105c9575f9261117d575b505f826109ae610a29941515614347565b6109b66149bb565b6040516109c281613b4e565b600281526040366020830137736a023ccd1ff6f2045c3309768ead9e68f978f6e16109ec82613efb565b527337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b3610a0b82613f1c565b526040516338ed173960e01b815294859283923091600485016143e4565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af19182156105c9578e92611163575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215611158578392611121575b506040518281526001600160a01b038216907f7ea2559d46b5ca1045280b94e6bd226dc4c60c15c514f72d0fc10c788c80822d90602090a2610ac9821515613c6c565b858061110f575b1561109757610ae8876001600160a01b038316614bce565b6001600160a01b0387163b15611093576040516301abf04560e71b81526001600160a01b03808a16600483015290911660248201526044810191909152818180606481010381836001600160a01b038b165af18015610f3d5761107b575b50505b6040516370a0823160e01b81523060048201526020816024816001600160a01b0386165afa908115611070578d9161103e575b508a8161102b575b50506040516370a0823160e01b815230600482015290506020816024816001600160a01b0386165afa908115611020578c91610fee575b508581610fdb575b50505080610fc9575b610def575b50506040516370a0823160e01b8152306004820152906020826024816001600160a01b038a165afa918215610de4578892610db0575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215610da5578992610d68575b5060249660209594939285928415610d42575050610c5993614e91565b505b6040516370a0823160e01b815230600482015293849182906001600160a01b03165afa918215610d37578492610cff575b505f8051602061578283398151915292610cee90610cbc6001600160ff1b03808611159081610cf4575b50613ffb565b610cd181610cca8587613cc2565b1215613cda565b604051938493846040919493926060820195825260208201520152565b0390a180f35b90508411155f610cb6565b9291506020833d602011610d2f575b81610d1b60209383613b84565b810103126105be5791519091610cee610c8c565b3d9150610d0e565b6040513d86823e3d90fd5b9150809350610d55575b50505050610c5b565b610d5e93614e91565b505f808281610d4c565b9094939291506020813d602011610d9d575b81610d8760209383613b84565b810103126105be57519293919290916024610c3c565b3d9150610d7a565b6040513d8b823e3d90fd5b9091506020813d602011610ddc575b81610dcc60209383613b84565b810103126105be5751905f610c07565b3d9150610dbf565b6040513d8a823e3d90fd5b6040516370a0823160e01b81523060048201526020816024816001600160a01b038c165afa908115610fbe578a91610f8c575b506040516370a0823160e01b81523060048201526020816024816001600160a01b0389165afa908115610f81578b91610f4f575b5080821015610f4857505b80610e6d575b50610bd1565b610e80826001600160a01b038a16614bce565b610e93826001600160a01b038616614bce565b6001600160a01b0382163b15610f3957604051637abef8d160e01b81526001600160a01b03808516600483015287166024820152604481018290528a90818180606481010381836001600160a01b0389165af18015610f3d57610f25575b50506040519081526001600160a01b038681169381169216905f8051602061580283398151915290602090a45f8080610e67565b610f2e90613aea565b610f3957895f610ef1565b8980fd5b6040513d84823e3d90fd5b9050610e61565b90506020813d602011610f79575b81610f6a60209383613b84565b810103126105be57515f610e56565b3d9150610f5d565b6040513d8d823e3d90fd5b90506020813d602011610fb6575b81610fa760209383613b84565b810103126105be57515f610e22565b3d9150610f9a565b6040513d8c823e3d90fd5b506001600160a01b0382161515610bcc565b610fe59288614e91565b505f8085610bc3565b90506020813d602011611018575b8161100960209383613b84565b810103126105be57515f610bbb565b3d9150610ffc565b6040513d8e823e3d90fd5b6110359289614e91565b505f808a610b84565b90506020813d602011611068575b8161105960209383613b84565b810103126105be57515f610b7c565b3d915061104c565b6040513d8f823e3d90fd5b61108490613aea565b61108f578b5f610b46565b8b80fd5b8280fd5b827ff8e6e0bb33e12f1f8e97919c28e4df84e2aebf737d4bf32534deb9e737f228e69293604051602081019063dbceb00560e01b8252866024820152602481526110e081613b4e565b519082855af1906110ef613c16565b506040805194855291151560208501526001600160a01b031692a2610b49565b506001600160a01b0388161515610ad0565b925090506020823d602011611150575b8161113e60209383613b84565b810103126105be578d9151905f610a86565b3d9150611131565b6040513d85823e3d90fd5b611176903d805f833e6106768183613b84565b505f610a51565b91506020823d6020116111a9575b8161119860209383613b84565b810103126105be579051905f61099d565b3d915061118b565b6111c4903d805f833e6105e78183613b84565b505f61095d565b506001600160a01b03891615156107ac565b506001600160a01b03881615156107a6565b506001600160a01b038416151561078b565b506001600160a01b0383161515610785565b506001600160a01b038716151561076a565b9099506020813d602011611251575b8161124160209383613b84565b810103126105be5751985f6106eb565b3d9150611234565b5034610140576101c036600319011261014057611274613864565b61127c61387a565b6044351515604435036105be57611291613890565b9061129a6138a6565b9260a4356001600160a01b03811690036105be576112b66138bc565b926112bf6138d2565b946112c86138e8565b916112d16138ff565b956112da613916565b946112e361392d565b956112f860018060a01b038c54163314613a80565b6040516370a0823160e01b81523060048201529860208a6024816001600160a01b038d165afa998a15611020578c9a611a99575b5061133b610184351515613d1b565b6113636001600160a01b0384167337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b31461403b565b6001600160a01b038516151580611a87575b61137e90613d52565b6001600160a01b038916151580611a73575b80611a61575b61139f90613d92565b6001600160a01b038b16151580611a4f575b80611a3d575b6113c090613d92565b6113d3856001600160a01b038b16614bce565b6001600160a01b0385163b1561108f576040516301abf04560e71b81526001600160a01b0380881660048301528a1660248201526101843560448201528c90818180606481010381836001600160a01b038c165af18015610f3d57611a29575b50506040516101843581526001600160a01b038a811691888216918816907f96b6cd56b43ef9bd81ea4da2f5715eb8e6d0da9999e7cf964ae2932a20e0f0fd90602090a4602460208c604051928380926370a0823160e01b825230600483015260018060a01b03165afa8015611070578d906119f5575b6114ba9150610184351115613dc7565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038c165afa908115611070578d916119c1575b5061150f9161150461150992610184351115613e0a565b615016565b91615016565b906044351561198d57506115469061152e6101843560a4358d8b614e91565b611539811515613e98565b610184359185898b6150a6565b505b6040516370a0823160e01b815230600482015260208160248160a4356001600160a01b03165afa908115610f81578b9161195b575b506040516370a0823160e01b81523060048201526020816024816001600160a01b0388165afa908115611020578c91611929575b50808210156119215750915b82611850575b50505050506040516370a0823160e01b81523060048201526020816024817337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b35afa90811561180457879161181e575b508061180f575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b038a165afa9182156118045787926117d0575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215610de4578892611793575b506024966020959493928592841561176d57505061169493614e91565b505b6040516370a0823160e01b815230600482015293849182906001600160a01b03165afa801561115857839061172e575b5f8051602061578283398151915292506116f16001600160ff1b038083111590816117235750613ffb565b6117026101a435610cca8484613cc2565b6040805192835260208301919091526101a435908201528060608101610cee565b90508311155f610cb6565b506020823d602011611765575b8161174860209383613b84565b810103126105be575f8051602061578283398151915291516116c6565b3d915061173b565b9150809350611780575b50505050611696565b61178993614e91565b505f808281611777565b9094939291506020813d6020116117c8575b816117b260209383613b84565b810103126105be57519293919290916024611677565b3d91506117a5565b9091506020813d6020116117fc575b816117ec60209383613b84565b810103126105be5751905f611642565b3d91506117df565b6040513d89823e3d90fd5b61181890615244565b5f61160d565b90506020813d602011611848575b8161183960209383613b84565b810103126105be57515f611606565b3d915061182c565b61187990849061186b8260a4356001600160a01b0316614bce565b6001600160a01b0316614bce565b6001600160a01b0383163b15610f3957604051637abef8d160e01b81526001600160a01b03808616600483015282166024820152604481018390528a90818180606481010381836001600160a01b038a165af18015610f3d5761190d575b50506040519182526001600160a01b039081169381169216905f8051602061580283398151915290602090a45f808080806115c3565b61191690613aea565b610f3957895f6118d7565b9050916115bd565b90506020813d602011611953575b8161194460209383613b84565b810103126105be57515f6115b1565b3d9150611937565b90506020813d602011611985575b8161197660209383613b84565b810103126105be57515f61157d565b3d9150611969565b6119bb91506119a16101843585898b614e91565b6119ac811515613e4c565b610184359160a4358d8b6150a6565b50611548565b90506020813d6020116119ed575b816119dc60209383613b84565b810103126105be575161150f6114ed565b3d91506119cf565b506020813d602011611a21575b81611a0f60209383613b84565b810103126105be576114ba90516114aa565b3d9150611a02565b611a3290613aea565b61108f578b5f611433565b506001600160a01b03881615156113b7565b506001600160a01b03871615156113b1565b506001600160a01b0384161515611396565b5060a4356001600160a01b03161515611390565b506001600160a01b0386161515611375565b9099506020813d602011611ac5575b81611ab560209383613b84565b810103126105be5751985f61132c565b3d9150611aa8565b503461014057610220366003190112610140576004356001600160401b0381116125d157611aff903690600401613972565b60805260a052611b0d61387a565b6044356001600160a01b03811690036105be57611b28613890565b611b306138a6565b60a435151560a435036105be57611b456138bc565b611b4d6138d2565b93611b566138e8565b611b5e6138ff565b94611b67613916565b96611b7061392d565b94610184356001600160a01b03811690036105be576101a4356001600160a01b03811690036105be576101c4356001600160a01b03811690036105be57611bc160018060a01b038b54163314613a80565b6040516370a0823160e01b8152306004820152976020896024816001600160a01b038c165afa988915610f81578b99612a25575b50611c046101e4351515613d1b565b6001600160a01b038216151580612a13575b611c1f90613d52565b6001600160a01b038816151580612a01575b806129ef575b611c4090613d92565b6001600160a01b038a161515806129dd575b806129c8575b611c6190613d92565b611c74826001600160a01b038a16614bce565b6001600160a01b0382163b156124cb576040516301abf04560e71b81526001600160a01b038085166004830152891660248201526101e43560448201528b90818180606481010381836001600160a01b0389165af18015610f3d576129b4575b50506040516101e43581526001600160a01b0389811691858216918516907f96b6cd56b43ef9bd81ea4da2f5715eb8e6d0da9999e7cf964ae2932a20e0f0fd90602090a46040516370a0823160e01b81523060048201526020816024816001600160a01b038f165afa8015611020578c90612980575b611d5a91506101e4351115613dc7565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038c165afa8015611020578c9061294c575b611d9c91506101e4351115613e0a565b611da861018435615016565b8a611db56101a435615016565b9160a43515612914575090611dd6611df192886101e435916101c435614e91565b611de1811515613e98565b6101e43591848b6101c4356150a6565b505b6040516370a0823160e01b81523060048201526020816024816001600160a01b038a165afa908115611020578c916128e2575b506040516370a0823160e01b81523060048201526020816024816001600160a01b0387165afa908115611070578d916128b0575b50808210156128a85750945b856127e7575b5050505081612071575b50506040516370a0823160e01b815230600482015290506020816024816001600160a01b0389165afa908115612066578691612034575b506040516370a0823160e01b8152306004820152946020866024816001600160a01b0387165afa958615611804578796611ff8575b5060249560209493929184918315611fd15750611f0393506101c435614e91565b505b6040516370a0823160e01b815230600482015293849182906001600160a01b03165afa8015611158578390611f92575b5f805160206157828339815191529250611f606001600160ff1b038083111590816117235750613ffb565b611f7161020435610cca8484613cc2565b60408051928352602083019190915261020435908201528060608101610cee565b506020823d602011611fc9575b81611fac60209383613b84565b810103126105be575f805160206157828339815191529151611f35565b3d9150611f9f565b92505081611fe2575b505050611f05565b611fef926101c435614e91565b505f8082611fda565b95509291906020863d60201161202c575b8161201660209383613b84565b810103126105be57945194919290919083611ee2565b3d9150612009565b90506020813d60201161205e575b8161204f60209383613b84565b810103126105be57515f611ead565b3d9150612042565b6040513d88823e3d90fd5b6001600160a01b0381167337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b3036121295750506040516370a0823160e01b815230600482015290506020816024817337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b35afa9081156120665786916120f7575b50806120e8575b505b5f8080611e76565b6120f190615244565b5f6120de565b90506020813d602011612121575b8161211260209383613b84565b810103126105be57515f6120d7565b3d9150612105565b608051612139575b5050506120e0565b6001600160a01b038316156127ae5761215b836001600160a01b038316614449565b6044356001600160a01b0316612794575b6080516004116124cf57608060031960a051825160a051010301126124cf57600460a0510135906001600160401b03821161249d5760805160a0510160238360a0510101121561249d5760048260a051010135926121c984613ee4565b936121d76040519586613b84565b8085526020850190819460805160a0510160248360051b8360a051010101116124c75760248160a0510101925b60248360051b8360a05101010184106125d55750505050612229604460a05101613a73565b90606460a0510135926001600160401b03841161108f5760805160a0510160238560a0510101121561108f578b61226760048660a051010135613bfb565b946122756040519687613b84565b60048160a051010135865260805160a05101602460048360a0510101358360a051010101116125d15760a051602091600491810180830135906024018985013760a051010135860101528551156125a2576001600160a01b03818116906122db88613efb565b51511603612588575b5091849260406122f68d969497613efb565b51015260405194859363286f580d60e01b85526084850190608060048701525180915260a485019060a48160051b870101949187905b8282106124d3575050505091612362918493602460a0510135602486015215156044850152600319848303016064850152613fbd565b0381836001600160a01b0387165af18015611804576123c6575b507fde69c99d0290e9136275c349eb34d1087f4344a5eb3b4ce398f30cca48dacb0f6040519160018060a01b031691806123bb60805160a05183613c45565b0390a25f8080612131565b3d908188823e6123d68282613b84565b60608183810103126124cf5780516001600160401b03811161249d5761240190838301908301613f5c565b5060208101516001600160401b03811161249d57828201601f82840101121561249d5780820151602061243382613ee4565b6124406040519182613b84565b828152019184840160208360051b8387010101116124cb5791602083850101925b60208360051b828701010184106124a1575050505060408101516001600160401b03811161249d576124969282019101613f5c565b505f61237c565b8880fd5b8351916001600160a01b03831683036124c7576020818194829352019401939150612461565b8c80fd5b8a80fd5b8780fd5b929791949650929460a3198982030183528751608082019260018060a01b038251168352602082015193608060208501528451809152602060a08501950191905b80821061254c57505050600192602092826040859401516040830152606080910151910152980192019201928795938e97959361232c565b9091946020606060019260408951858060a01b038151168352858060a01b03858201511685840152015115156040820152019601920190612514565b6001600160a01b031661259a86613efb565b51525f6122e4565b60405162461bcd60e51b8152602060048201526007602482015266070617468733d360cc1b6044820152606490fd5b5080fd5b83356001600160401b038111612790576080602319828560a0510101825160a05101030112612790576040519061260b82613afd565b61261d6024828660a051010101613944565b82526044818560a051010101356001600160401b03811161278b5760805160a05101604382848860a05101010101121561278b57602481838760a05101010101359061266882613ee4565b916126766040519384613b84565b8083526020830160805160a0510160446060840285888c60a05101010101011161278357604483868a60a05101010101905b60446060840285888c60a051010101010182106126f9575050505060208084019190915260a08051860183016064013560408501525185019091016084013560608301529082529384019301612204565b60608260805160a05101031261277a576040518060608101106001600160401b036060830111176127665760609181836020930160405261273985613944565b8152612746838601613944565b8382015261275660408601613a73565b60408201528152019101906126a8565b634e487b7160e01b5f52604160045260245ffd5b50505050508f80fd5b505050508f80fd5b508f80fd5b8e80fd5b6127a96044356001600160a01b038316614bce565b61216c565b60405162461bcd60e51b8152602060048201526011602482015270062616c616e63657220726f757465723d3607c1b6044820152606490fd5b61280191839161186b9083906001600160a01b0316614bce565b6001600160a01b0381163b15610f3957604051637abef8d160e01b81526001600160a01b03808416600483015284166024820152604481018590528a90818180606481010381836001600160a01b0388165af18015610f3d57612894575b50506040518481526001600160a01b038481169381169216905f8051602061580283398151915290602090a45f808080611e6c565b61289d90613aea565b610f3957895f61285f565b905094611e66565b90506020813d6020116128da575b816128cb60209383613b84565b810103126105be57515f611e5a565b3d91506128be565b90506020813d60201161290c575b816128fd60209383613b84565b810103126105be57515f611e26565b3d91506128f0565b612946925061292b6101e435858c6101c435614e91565b90612937821515613e4c565b886101e435936101c4356150a6565b50611df3565b506020813d602011612978575b8161296660209383613b84565b810103126105be57611d9c9051611d8c565b3d9150612959565b506020813d6020116129ac575b8161299a60209383613b84565b810103126105be57611d5a9051611d4a565b3d915061298d565b6129bd90613aea565b6124cb578a5f611cd4565b506101c4356001600160a01b03161515611c58565b506001600160a01b0387161515611c52565b506001600160a01b0381161515611c37565b506001600160a01b0385161515611c31565b506001600160a01b0383161515611c16565b9098506020813d602011612a51575b81612a4160209383613b84565b810103126105be5751975f611bf5565b3d9150612a34565b50346105be57612a683661399f565b9d91989994939c600160a09d929c9d999794991b600190035f54163314612a8e90613a80565b6040516370a0823160e01b81523060048201529c8d806001600160a01b038e165a92602491602094fa9d8e156105c9575f9e613254575b506040518e81526001600160a01b038d16907fb2f03ce105b3cd1f9fccfa1de78c921cd3ad2f01048d3a832c7ebb893fd347b990602090a2612b10836001600160a01b038e16614449565b6001600160a01b03811661323b575b505f806040518386823780848101838152039082865af1612b3e613c16565b50156131f6577f039f1e3426eb05ff8263467f0ccd63de0af468a20960885b56ee6fbb53ac1be691612b7e60405192839260018060a01b03169583613c45565b0390a26040516370a0823160e01b81523060048201526020816024816001600160a01b0388165afa9081156105c9575f916131c4575b506040518181526001600160a01b038516907f7ea2559d46b5ca1045280b94e6bd226dc4c60c15c514f72d0fc10c788c80822d90602090a2612bf7811515613c6c565b6001600160a01b03851615159384806131b2575b1561313a57612c23866001600160a01b038316614bce565b6001600160a01b0386163b156105be576040516301abf04560e71b81526001600160a01b038089166004830152909116602482015260448101919091525f8180606481010381836001600160a01b038a165af180156105c957613127575b505b6040516370a0823160e01b81523060048201528d906020816024816001600160a01b0387165afa91821561311b57916130e9575b508b816130d6575b50506040516370a0823160e01b815230600482015290506020816024816001600160a01b0386165afa908115611070578d916130a4575b508581613091575b5050508061307f575b612ecb575b50506040516370a0823160e01b8152306004820152906020826024816001600160a01b038b165afa918215610da5578992612e97575b506040516370a0823160e01b8152306004820152906020826024816001600160a01b0385165afa918215610fbe578a92612e5a575b5060249760209594939285928415612e34575050612d9493614e91565b505b6040516370a0823160e01b815230600482015294859182906001600160a01b03165afa928315612e29578593612df1575b50610cd1610cee9185612dec5f8051602061578283398151915297610cca8789613cc2565b613cc2565b9392506020843d602011612e21575b81612e0d60209383613b84565b810103126105be5792519192610cd1612dc7565b3d9150612e00565b6040513d87823e3d90fd5b9150809350612e47575b50505050612d96565b612e5093614e91565b505f808281612e3e565b9094939291506020813d602011612e8f575b81612e7960209383613b84565b810103126105be57519293919290916024612d77565b3d9150612e6c565b9091506020813d602011612ec3575b81612eb360209383613b84565b810103126105be5751905f612d42565b3d9150612ea6565b6040516370a0823160e01b81523060048201526020816024816001600160a01b038d165afa908115610f81578b9161304d575b506040516370a0823160e01b81523060048201526001600160a01b0385169190602081602481865afa908115611070578d9161301b575b50808210156130135750905b81612f4e575b5050612d0c565b612f6c908390612f67826001600160a01b038e16614bce565b614bce565b6001600160a01b0382163b156124cb57604051637abef8d160e01b81526001600160a01b03808516600483015287166024820152604481018290528b90818180606481010381836001600160a01b0389165af18015610f3d57612fff575b50506040519081526001600160a01b038681169381169216905f8051602061580283398151915290602090a45f808080612f47565b61300890613aea565b6124cb578a5f612fca565b905090612f41565b90506020813d602011613045575b8161303660209383613b84565b810103126105be57515f612f35565b3d9150613029565b90506020813d602011613077575b8161306860209383613b84565b810103126105be57515f612efe565b3d915061305b565b506001600160a01b0382161515612d07565b61309b9288614e91565b505f8085612cfe565b90506020813d6020116130ce575b816130bf60209383613b84565b810103126105be57515f612cf6565b3d91506130b2565b6130e09289614e91565b505f808b612cbf565b90506020813d602011613113575b8161310460209383613b84565b810103126105be57515f612cb7565b3d91506130f7565b604051903d90823e3d90fd5b613132919d50613aea565b5f9b5f612c81565b7ff8e6e0bb33e12f1f8e97919c28e4df84e2aebf737d4bf32534deb9e737f228e6905f80604051602081019063dbceb00560e01b82528660248201526024815261318381613b4e565b519082855af190613192613c16565b506040805194855291151560208501526001600160a01b031692a2612c83565b506001600160a01b0387161515612c0b565b90506020813d6020116131ee575b816131df60209383613b84565b810103126105be57515f612bb4565b3d91506131d2565b60405162461bcd60e51b815260206004820152601860248201527f42616c616e636572206275792073776170206661696c656400000000000000006044820152606490fd5b61324e906001600160a01b038d16614bce565b5f612b1f565b9b9d5060208c3d602011613281575b8161327060209383613b84565b810103126105be578d9b519d612ac5565b3d9150613263565b346105be5761329736613958565b6132ab60018060a01b035f54163314613a80565b6132b6831515613d1b565b6132be61475a565b6132c66156ab565b906132cf614073565b935f604051936132de85613b33565b8185526040516132ed81613b18565b5f805160206157c28339815191528152602095838783015260036040830152846060830152608082015261332088613efb565b5261332a87613efb565b5060405161333781613b33565b8281526040519061334782613b18565b5f805160206157e2833981519152825260038783015260046040830152836060830152608082015261337888613f1c565b5261338287613f1c565b5060405161338f81613b33565b8281526040519061339f82613b18565b5f805160206157a283398151915282526004878301526002604083015283606083015260808201526133d088613f2c565b526133da87613f2c565b506133e58151614125565b926133ef84613efb565b5285151596876135b0575b6134396040519461340a86613afd565b3086528488870152306040870152846060870152604051958694859463945bcec960e01b86526004860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156105c957613596575b506040516370a0823160e01b815230600482015292736a023ccd1ff6f2045c3309768ead9e68f978f6e1908385602481855afa9485156105c9575f95613567575b5084956134ae5f961515614347565b613555575b506134bc6149bb565b60408051936134ca85613b4e565b6002855236908501376134dc83613efb565b527337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b36134fb83613f1c565b5261351c60405194859384936338ed173960e01b8552309260048601614420565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af180156105c95761354257005b610018903d805f833e6106768183613b84565b6135619086101561437d565b856134b3565b94508385813d831161358f575b61357e8183613b84565b810103126105be575f94519461349f565b503d613574565b6135a9903d805f833e6105e78183613b84565b508461345e565b6135b987614157565b6135c285613f2c565b526133fa565b346105be575f3660031901126105be575f546040516001600160a01b039091168152602090f35b346105be5760403660031901126105be576004356001600160a01b03818116918290036105be575f80809361362982948354163314613a80565b613634811515613ab8565b602435905af1613642613c16565b501561364a57005b60405162461bcd60e51b815260206004820152600f60248201526e195d1a081cd95b990819985a5b1959608a1b6044820152606490fd5b346105be5760403660031901126105be5761369a613864565b6136a261387a565b5f5490916001600160a01b03916136bc9083163314613a80565b6136c98284161515613ab8565b166040516370a0823160e01b81523060048201526020928382602481865afa9081156105c95784925f92613773575b5060405163a9059cbb60e01b81526001600160a01b0390911660048201526024810191909152918290815f81604481015b03925af19081156105c957610018925f92613746575b5050613bbd565b6137659250803d1061376c575b61375d8183613b84565b810190613ba5565b828061373f565b503d613753565b8381949293503d831161379f575b61378b8183613b84565b810103126105be57905183916137296136f8565b503d613781565b346105be5760603660031901126105be576137bf613864565b60206138296137cc61387a565b5f546001600160a01b039491906137e69086163314613a80565b6137f38582161515613ab8565b60405163a9059cbb60e01b81526001600160a01b0390911660048201526044803560248301529094859384925f92918491820190565b0393165af180156105c957610018915f91613845575b50613bbd565b61385e915060203d60201161376c5761375d8183613b84565b8261383f565b600435906001600160a01b03821682036105be57565b602435906001600160a01b03821682036105be57565b606435906001600160a01b03821682036105be57565b608435906001600160a01b03821682036105be57565b60c435906001600160a01b03821682036105be57565b60e435906001600160a01b03821682036105be57565b61010435906001600160a01b03821682036105be57565b61012435906001600160a01b03821682036105be57565b61014435906001600160a01b03821682036105be57565b61016435906001600160a01b03821682036105be57565b35906001600160a01b03821682036105be57565b60609060031901126105be57600435906024359060443590565b9181601f840112156105be578235916001600160401b0383116105be57602083818601950101116105be57565b6101c06003198201126105be57600435906001600160401b0382116105be576139ca91600401613972565b90916001600160a01b0360243581811681036105be579160443582811681036105be579160643581811681036105be579160843582811681036105be579160a43581811681036105be579160c43582811681036105be579160e43581811681036105be57916101043582811681036105be57916101243581811681036105be57916101443582811681036105be57916101643590811681036105be579061018435906101a43590565b359081151582036105be57565b15613a8757565b60405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b6044820152606490fd5b15613abf57565b606460405162461bcd60e51b81526020600482015260046024820152630746f3d360e41b6044820152fd5b6001600160401b03811161276657604052565b608081019081106001600160401b0382111761276657604052565b60a081019081106001600160401b0382111761276657604052565b602081019081106001600160401b0382111761276657604052565b606081019081106001600160401b0382111761276657604052565b60c081019081106001600160401b0382111761276657604052565b90601f801991011681019081106001600160401b0382111761276657604052565b908160209103126105be575180151581036105be5790565b15613bc457565b60405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b6001600160401b03811161276657601f01601f191660200190565b3d15613c40573d90613c2782613bfb565b91613c356040519384613b84565b82523d5f602084013e565b606090565b90918060409360208452816020850152848401375f828201840152601f01601f1916010190565b15613c7357565b60405162461bcd60e51b815260206004820152602160248201527f4661696c656420746f206163717569726520636f6d706f7369746520746f6b656044820152603760f91b6064820152608490fd5b81810392915f13801582851316918412161761060e57565b15613ce157565b60405162461bcd60e51b81526020600482015260126024820152711b5a5b881c1c9bd99a5d081b9bdd081b595d60721b6044820152606490fd5b15613d2257565b60405162461bcd60e51b81526020600482015260086024820152670616d6f756e743d360c41b6044820152606490fd5b15613d5957565b60405162461bcd60e51b81526020600482015260116024820152700726f757465722f70726f706f73616c3d3607c1b6044820152606490fd5b15613d9957565b60405162461bcd60e51b81526020600482015260066024820152650616464723d360d41b6044820152606490fd5b15613dce57565b60405162461bcd60e51b815260206004820152601460248201527334b739bab33334b1b4b2b73a102ca2a9afb1bab960611b6044820152606490fd5b15613e1157565b60405162461bcd60e51b815260206004820152601360248201527234b739bab33334b1b4b2b73a102727afb1bab960691b6044820152606490fd5b15613e5357565b60405162461bcd60e51b815260206004820152601960248201527f4e4f2065786163742d696e2070726f6475636564207a65726f000000000000006044820152606490fd5b15613e9f57565b60405162461bcd60e51b815260206004820152601a60248201527f5945532065786163742d696e2070726f6475636564207a65726f0000000000006044820152606490fd5b6001600160401b0381116127665760051b60200190565b805115613f085760200190565b634e487b7160e01b5f52603260045260245ffd5b805160011015613f085760400190565b805160021015613f085760600190565b805160031015613f085760800190565b805160041015613f085760a00190565b9080601f830112156105be57815190602091613f7781613ee4565b93613f856040519586613b84565b81855260208086019260051b8201019283116105be57602001905b828210613fae575050505090565b81518152908301908301613fa0565b91908251928382525f5b848110613fe7575050825f602080949584010152601f8019910116010190565b602081830181015184830182015201613fc7565b1561400257565b60405162461bcd60e51b815260206004820152601160248201527062616c616e636520746f6f206c6172676560781b6044820152606490fd5b1561404257565b60405162461bcd60e51b8152602060048201526009602482015268636f6d70213d504e4b60b81b6044820152606490fd5b604080519161408183613afd565b6003835282915f5b6060808210156140c6578251602092916140a282613b18565b5f825283905f828401525f868401525f818401526080830152828801015201614089565b505050909150565b604090604051916140de83613b69565b60058352825f5b60a081106140f257505050565b602090835161410081613b18565b5f8152825f818301525f8683015260605f8184015260808301528285010152016140e5565b9061412f82613ee4565b61413c6040519182613b84565b828152809261414d601f1991613ee4565b0190602036910137565b600160ff1b811461060e575f0390565b60209081818403126105be578051906001600160401b0382116105be57019180601f840112156105be57825161419c81613ee4565b936141aa6040519586613b84565b818552838086019260051b8201019283116105be578301905b8282106141d1575050505090565b815181529083019083016141c3565b9081518082526020808093019301915f5b8281106141ff575050505090565b83516001600160a01b0316855293810193928101926001016141f1565b94939290610120928387015f88526020948589015282518091526101409085828a01928260051b8b01019401915f905b8a8383106142e55791505084606095935061426e9492500360408a01526141e0565b82516001600160a01b0390811688840152848401511515608089015260408401511660a0880152910151151560c086015284810360e08601528251808252908201928201915f5b8281106142d15750505050610100661fffffffffffff91930152565b8351855293810193928101926001016142b5565b978061433660019394959698829a9b61013f1990820301865289519060a090825181528483015185820152604080840151908201526060808401519082015281608080940151938201520190613fbd565b97019201920190929196959661424c565b1561434e57565b60405162461bcd60e51b81526020600482015260076024820152660dcde40ae8aa8960cb1b6044820152606490fd5b1561438457565b60405162461bcd60e51b815260206004820152601060248201526f1b5a5b8815d15512081b9bdd081b595d60821b6044820152606490fd5b906020828203126105be5781516001600160401b0381116105be576143e19201613f5c565b90565b61440c63d141dd849360809396959683525f602084015260a0604084015260a08301906141e0565b6001600160a01b0390951660608201520152565b9063d141dd849360809361440c929796978452602084015260a0604084015260a08301906141e0565b91909160018060a01b038091166040805192636eb1769f60e11b9586855260049630888701526e22d473030f116ddee9f6b43ac78ba3916024968388820152602092604491848184818c5afa90811561467c578587858f8c8f958f905f98614720575b505f1997600181016145de575b50509550505050505051908152308b8201528489820152838183818b5afa9081156145d4578486928a925f91614592575b50905f80516020615762833981519152918a51908152a3833b156105be578480928888519c8d6387517c4560e01b90528d01521680988b01528901525f886084818365ffffffffffff968760648401525af1978815614588577f4871c6f66188da2f442cdab9920447df48710c721ba67e79f01001ebfa3d4ae995969798614579575b508351928352820152a3565b61458290613aea565b5f61456d565b84513d5f823e3d90fd5b935050905081813d83116145cd575b6145ab8183613b84565b810103126105be57875f805160206157628339815191528587935190916144ea565b503d6145a1565b87513d5f823e3d90fd5b614686575b50945050505050519063095ea7b360e01b8252868d8301528a820152848184815f8d5af190811561467c575f9161465f575b5015614629575f898587858f8c8e876144b9565b865162461bcd60e51b8152808c018590526012818b015271185c1c1c9bdd99481cd95d0819985a5b195960721b81840152606490fd5b6146769150853d871161376c5761375d8183613b84565b5f614615565b88513d5f823e3d90fd5b5f809251978896879563095ea7b360e01b87528601528401525af1908115614716575f916146f9575b50156146c157898587858f8c8e6145e3565b875162461bcd60e51b8152808d018690526014818c015273185c1c1c9bdd99481c995cd95d0819985a5b195960621b81850152606490fd5b6147109150863d881161376c5761375d8183613b84565b5f6146af565b89513d5f823e3d90fd5b97505050505050905081813d8311614753575b61473d8183613b84565b810103126105be5751898587858f8c8e5f6144ac565b503d614733565b60408051636eb1769f60e11b808252600490308284015273ba12222222228d8ba445958a75a0704d566bf2c893602491858386015260209260449073af204776c7245bf4147c2612bf6e5972ee48370196858184818b5afa9081156148ef57918991879594935f91614989575b505f199060018101614853575b505085519788948552309085015283015281875afa90811561484a575f9161480e575b5f80516020615762833981519152935051908152a3565b90508183813d8311614843575b6148258183613b84565b810103126105be575f805160206157628339815191529251906147f7565b503d61481b565b513d5f823e3d90fd5b919394955091506148f9575b84519063095ea7b360e01b8252898883015282820152858184815f8c5af19081156148ef575f916148d2575b501561489d5790878593925f806147d4565b71185c1c1c9bdd99481cd95d0819985a5b195960721b606492601288938888519562461bcd60e51b8752860152840152820152fd5b6148e99150863d881161376c5761375d8183613b84565b5f61488b565b85513d5f823e3d90fd5b845163095ea7b360e01b815289888201525f83820152868185815f8d5af190811561497f575f91614962575b5061485f57845162461bcd60e51b815280880187905260148184015273185c1c1c9bdd99481c995cd95d0819985a5b195960621b81850152606490fd5b6149799150873d891161376c5761375d8183613b84565b5f614925565b86513d5f823e3d90fd5b9250509381813d83116149b4575b6149a18183613b84565b810103126105be5785938991515f6147c7565b503d614997565b60408051636eb1769f60e11b808252600490308284015273e43e60736b1cb4a75ad25240e2f9a62bff65c0c0936024918583860152602092604490736a023ccd1ff6f2045c3309768ead9e68f978f6e196858184818b5afa9081156148ef57918991879594935f9161498957505f19906001810161485357505085519788948552309085015283015281875afa90811561484a575f9161480e575f80516020615762833981519152935051908152a3565b60408051636eb1769f60e11b808252600490308284015273e43e60736b1cb4a75ad25240e2f9a62bff65c0c09360249185838601526020926044907337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b396858184818b5afa9081156148ef57918991879594935f9161498957505f19906001810161485357505085519788948552309085015283015281875afa90811561484a575f9161480e575f80516020615762833981519152935051908152a3565b60408051636eb1769f60e11b808252600490308284015273ba12222222228d8ba445958a75a0704d566bf2c8936024918583860152602092604490736a023ccd1ff6f2045c3309768ead9e68f978f6e196858184818b5afa9081156148ef57918991879594935f9161498957505f19906001810161485357505085519788948552309085015283015281875afa90811561484a575f9161480e575f80516020615762833981519152935051908152a3565b60408051636eb1769f60e11b808252306004808401919091526001600160a01b0386811660248501529395948416936020939092908481604481895afa90811561467c579187939186935f91614dea575b505f199060018101614cbd575b50508851908152309181019182526001600160a01b039097166020820152869081906040010381875afa94851561497f575f95614c7f575b505f80516020615762833981519152939495519586521693a3565b9394508284813d8311614cb6575b614c978183613b84565b810103126105be575f8051602061576283398151915293519493614c64565b503d614c8d565b919350919350614d5e575b87519063095ea7b360e01b825284881684830152602482015284816044815f8a5af190811561467c575f91614d41575b5015614d0957859184915f80614c2c565b865162461bcd60e51b81528083018590526012602482015271185c1c1c9bdd99481cd95d0819985a5b195960721b6044820152606490fd5b614d589150853d871161376c5761375d8183613b84565b5f614cf8565b875163095ea7b360e01b8152848816848201525f602482015285816044815f8b5af1908115614716575f91614dcd575b50614cc857875162461bcd60e51b81528084018690526014602482015273185c1c1c9bdd99481c995cd95d0819985a5b195960621b6044820152606490fd5b614de49150863d881161376c5761375d8183613b84565b5f614d8e565b93809295508491503d8311614e17575b614e048183613b84565b810103126105be5786928592515f614c1f565b503d614dfa565b15614e2557565b60405162461bcd60e51b815260206004820152600e60248201526d0737761707220726f757465723d360941b6044820152606490fd5b15614e6257565b60405162461bcd60e51b81526020600482015260076024820152660746f6b656e3d360cc1b6044820152606490fd5b6001600160a01b039493909185831691908690614eaf841515614e1e565b16928315158061500b575b614ec390614e5b565b811561500157614ed39084614bce565b604080519160e083018381106001600160401b03821117612766578252848352602097808985019716968781528385013081526060860142815260808701908582528460a08901935f85528160c08b01965f8852818b519c8d63178ca23160e31b9052511660048d0152511660248b0152511660448901525160648801525160848701525160a4860152511660c4840152878360e4815f885af18015614ff7575f90614faa575b7f5daa39fce4745a2a9e6137131383e8405e80edb12e37c562f590c5f294ed19d5935080988351928352820152a4565b508783813d8311614ff0575b614fc08183613b84565b810103126105be577f5daa39fce4745a2a9e6137131383e8405e80edb12e37c562f590c5f294ed19d59251614f7a565b503d614fb6565b82513d5f823e3d90fd5b505f955050505050565b508487161515614eba565b6001600160a01b031680156150a05760206004916040519283809263ddca3f4360e01b82525afa5f9181615060575b506150505750606490565b62ffffff81166143e15750606490565b9091506020813d602011615098575b8161507c60209383613b84565b810103126105be575162ffffff811681036105be57905f615045565b3d915061506f565b50606490565b919594929391926001600160a01b0380851693909283906150c8861515614e1e565b169485151580615239575b6150dc90614e5b565b811561522d576150ec9086614bce565b60409182516101008101918183106001600160401b03841117612766578592855287825260209a838c84019116998a8252848785019162ffffff8091168352606086019030825260808701934285528360a08901968b885260c08a0198895260e08a01995f8b528d519e8f91631b67c43360e31b835251169060040152511660248d0152511660448b0152511660648901525160848801525160a48701525160c4860152511660e4840152878385815a610104925f91f18015614ff7575f906151e0575b7fcb3796b31ba09ffbc48bd2abe64550ce61698c9e170bed66c7f6c556118af6a3935080988351928352820152a4565b508783813d8311615226575b6151f68183613b84565b810103126105be577fcb3796b31ba09ffbc48bd2abe64550ce61698c9e170bed66c7f6c556118af6a392516151b0565b503d6151ec565b505f9750505050505050565b5088841615156150d3565b61524f811515613d1b565b615257614a6c565b60409081519161526683613b4e565b600283526020918136848601377337b60f4e9a31a64ccc0024dce7d0fd07eaa0f7b361529185613efb565b526152d45f736a023ccd1ff6f2045c3309768ead9e68f978f6e192836152b688613f1c565b528451809381926338ed173960e01b835260049930918b85016143e4565b03818373e43e60736b1cb4a75ad25240e2f9a62bff65c0c05af1801561564757615691575b50815183816024816370a0823160e01b95868252308a8301525afa908115615647575f91615664575b5061532e811515614347565b615336614b1d565b61533e6156ab565b6153466140ce565b8260011c92838103818111615651575f93929161557091885161536881613b33565b86815289519061537782613b18565b7f7e5870ac540adfd01a213c829f2231c309623eb10002000000000000000000e9825260028c83015260018b8301526060988983015260808201526153bb85613efb565b526153c584613efb565b5088516153d181613b33565b8681528951906153e082613b18565b7fa91c413d8516164868f6cca19573fe38f88f5982000200000000000000000157825260018c830152878b8301528789830152608082015261542185613f1c565b5261542b84613f1c565b50885161543781613b33565b86815289519161544683613b18565b5f805160206157a2833981519152835260028c8401528c8b84015288830152608082015261547384613f2c565b5261547d83613f2c565b50875161548981613b33565b85815288519061549882613b18565b5f805160206157e283398151915282528b8b83015260038a830152868883015260808201526154c684613f3c565b526154d083613f3c565b5087516154dc81613b33565b8581528851906154eb82613b18565b5f805160206157c2833981519152825260038b830152868a8301528688830152608082015261551984613f4c565b5261552383613f4c565b5061552e8451614125565b9061553882613f2c565b528488519661554688613afd565b308089528b89018390528a890152870152875163945bcec960e01b815295869485948c860161421c565b03818373ba12222222228d8ba445958a75a0704d566bf2c85af180156156475761562d575b5081519081523084820152828160248173af204776c7245bf4147c2612bf6e5972ee4837015afa908115614ff7575f91615600575b50156155d557505050565b5162461bcd60e51b81529182015260076024820152666e6f207344414960c81b604482015260649150fd5b90508281813d8311615626575b6156178183613b84565b810103126105be57515f6155ca565b503d61560d565b615640903d805f833e6105e78183613b84565b505f615595565b83513d5f823e3d90fd5b601189634e487b7160e01b5f525260245ffd5b90508381813d831161568a575b61567b8183613b84565b810103126105be57515f615322565b503d615671565b6156a4903d805f833e6106768183613b84565b505f6152f9565b604051906156b882613b69565b6005825260a0366020840137739c58bacc331c9aa871afd802db6379a98e80cedb61575e8373af204776c7245bf4147c2612bf6e5972ee4837016156fb82613efb565b5273c0d871bd13ebdf5c4ff059d8243fb38210608bd661571a82613f1c565b52736a023ccd1ff6f2045c3309768ead9e68f978f6e161573982613f2c565b5273e0ed85f76d9c552478929fab44693e03f0899f2361575882613f3c565b52613f4c565b5256feb6174191c8a1b8338dcc8711e5edf88685ae0a57f03b361e2bdf8979f6288bd5318296ace369901373a62c2153c5e87356175630ec782af9e8b7c9385f3d1e80a99fd9950b5d5dceeaf4939e221dca8ca9b938ab00010000000000000000002540d2cbc586dd8df50001cdba3f65cd4bbc32d596000200000000000000000154480d4f66cc41a1b6784a53a10890e5ece31d75c000020000000000000000014edc43ce728a1135c1396673372fa69f30fe424cb172093e4198538d75e54f3c2ba264697066735822122041b33bb4b1d53333712e272022b62ced2cb435c7762e56e1d42b67bee10ca51d64736f6c63430008180033

Block Transaction Gas Used Reward
view all blocks validated

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.