ETH Price: $2,405.43 (-4.13%)

Contract

0xf855C0C7BBb9C9094Fea6A10e052953C8fCa985b
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Convert ETH And ...204140442024-07-29 18:33:5936 days ago1722278039IN
0xf855C0C7...C8fCa985b
0.09494221 ETH0.001425134.35695886
Convert ETH And ...204108652024-07-29 7:56:3537 days ago1722239795IN
0xf855C0C7...C8fCa985b
0.09446686 ETH0.000753342.30306568
Convert ETH And ...204100912024-07-29 5:21:2337 days ago1722230483IN
0xf855C0C7...C8fCa985b
0.09484749 ETH0.000604131.84682473
Convert ETH And ...203661892024-07-23 2:16:3543 days ago1721700995IN
0xf855C0C7...C8fCa985b
0.09013515 ETH0.000923682.81956076
Convert ETH And ...203050442024-07-14 13:28:4751 days ago1720963727IN
0xf855C0C7...C8fCa985b
0.09166953 ETH0.001058142.67739838
Convert ETH And ...202855132024-07-11 19:59:2354 days ago1720727963IN
0xf855C0C7...C8fCa985b
0.09122279 ETH0.00152024.6469412
Mint Bulk202670762024-07-09 6:13:4757 days ago1720505627IN
0xf855C0C7...C8fCa985b
0 ETH0.001044122.79186371
Convert ETH And ...202621402024-07-08 13:38:2357 days ago1720445903IN
0xf855C0C7...C8fCa985b
0.08974551 ETH0.001810925.536351
Convert ETH And ...202463102024-07-06 8:34:5960 days ago1720254899IN
0xf855C0C7...C8fCa985b
0.08657271 ETH0.000961992.11112819
Convert ETH And ...202416202024-07-05 16:52:4760 days ago1720198367IN
0xf855C0C7...C8fCa985b
0.08490695 ETH0.002887598.81801875
Convert ETH And ...202408902024-07-05 14:26:1160 days ago1720189571IN
0xf855C0C7...C8fCa985b
0.08520488 ETH0.002614447.98442746
Mint Bulk202302152024-07-04 2:38:2362 days ago1720060703IN
0xf855C0C7...C8fCa985b
0 ETH0.002497526.62846745
Convert ETH And ...202298072024-07-04 1:16:2362 days ago1720055783IN
0xf855C0C7...C8fCa985b
0.08628324 ETH0.001456594.41104856
Convert ETH And ...202297342024-07-04 1:01:4762 days ago1720054907IN
0xf855C0C7...C8fCa985b
0.17242 ETH0.001335472.80714384
Convert ETH And ...202230712024-07-03 2:42:3563 days ago1719974555IN
0xf855C0C7...C8fCa985b
0.08475991 ETH0.001327694.05474759
Convert ETH And ...202205362024-07-02 18:11:4763 days ago1719943907IN
0xf855C0C7...C8fCa985b
0.08431426 ETH0.00192445.8771874
Convert And Mint202182012024-07-02 10:21:2364 days ago1719915683IN
0xf855C0C7...C8fCa985b
0 ETH0.001211043.61155643
Convert And Mint202175982024-07-02 8:20:3564 days ago1719908435IN
0xf855C0C7...C8fCa985b
0 ETH0.001644284.10803198
Convert ETH And ...202155832024-07-02 1:34:3564 days ago1719884075IN
0xf855C0C7...C8fCa985b
0.08459115 ETH0.000698182.11398932
Convert ETH And ...202109962024-07-01 10:13:2365 days ago1719828803IN
0xf855C0C7...C8fCa985b
0.08372998 ETH0.001114713.40460309
Convert ETH And ...202100892024-07-01 7:10:2365 days ago1719817823IN
0xf855C0C7...C8fCa985b
0.08409951 ETH0.000943252.85627355
Convert ETH And ...202100812024-07-01 7:08:4765 days ago1719817727IN
0xf855C0C7...C8fCa985b
0.08405251 ETH0.000957192.89837905
Convert ETH And ...201736532024-06-26 5:04:2370 days ago1719378263IN
0xf855C0C7...C8fCa985b
0.09133485 ETH0.000703452.13201184
Convert ETH And ...201733362024-06-26 4:00:5970 days ago1719374459IN
0xf855C0C7...C8fCa985b
0.09133485 ETH0.001122132.86388764
Mint Bulk201378642024-06-21 5:00:1175 days ago1718946011IN
0xf855C0C7...C8fCa985b
0 ETH0.001315832.51960777
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
204140442024-07-29 18:33:5936 days ago1722278039
0xf855C0C7...C8fCa985b
0.00047234 ETH
204140442024-07-29 18:33:5936 days ago1722278039
0xf855C0C7...C8fCa985b
0.00047234 ETH
204140442024-07-29 18:33:5936 days ago1722278039
0xf855C0C7...C8fCa985b
0.09494221 ETH
204108652024-07-29 7:56:3537 days ago1722239795
0xf855C0C7...C8fCa985b
0.00093531 ETH
204108652024-07-29 7:56:3537 days ago1722239795
0xf855C0C7...C8fCa985b
0.00093531 ETH
204108652024-07-29 7:56:3537 days ago1722239795
0xf855C0C7...C8fCa985b
0.09446686 ETH
204100912024-07-29 5:21:2337 days ago1722230483
0xf855C0C7...C8fCa985b
0.00047187 ETH
204100912024-07-29 5:21:2337 days ago1722230483
0xf855C0C7...C8fCa985b
0.00047187 ETH
204100912024-07-29 5:21:2337 days ago1722230483
0xf855C0C7...C8fCa985b
0.09484749 ETH
203661892024-07-23 2:16:3543 days ago1721700995
0xf855C0C7...C8fCa985b
0.00089242 ETH
203661892024-07-23 2:16:3543 days ago1721700995
0xf855C0C7...C8fCa985b
0.00089242 ETH
203661892024-07-23 2:16:3543 days ago1721700995
0xf855C0C7...C8fCa985b
0.09013515 ETH
203050442024-07-14 13:28:4751 days ago1720963727
0xf855C0C7...C8fCa985b
0.00044587 ETH
203050442024-07-14 13:28:4751 days ago1720963727
0xf855C0C7...C8fCa985b
0.00044587 ETH
203050442024-07-14 13:28:4751 days ago1720963727
0xf855C0C7...C8fCa985b
0.09166953 ETH
202855132024-07-11 19:59:2354 days ago1720727963
0xf855C0C7...C8fCa985b
0.00045384 ETH
202855132024-07-11 19:59:2354 days ago1720727963
0xf855C0C7...C8fCa985b
0.00045384 ETH
202855132024-07-11 19:59:2354 days ago1720727963
0xf855C0C7...C8fCa985b
0.09122279 ETH
202621402024-07-08 13:38:2357 days ago1720445903
0xf855C0C7...C8fCa985b
0.00088856 ETH
202621402024-07-08 13:38:2357 days ago1720445903
0xf855C0C7...C8fCa985b
0.00088856 ETH
202621402024-07-08 13:38:2357 days ago1720445903
0xf855C0C7...C8fCa985b
0.08974551 ETH
202463102024-07-06 8:34:5960 days ago1720254899
0xf855C0C7...C8fCa985b
0.00043071 ETH
202463102024-07-06 8:34:5960 days ago1720254899
0xf855C0C7...C8fCa985b
0.00043071 ETH
202463102024-07-06 8:34:5960 days ago1720254899
0xf855C0C7...C8fCa985b
0.08657271 ETH
202416202024-07-05 16:52:4760 days ago1720198367
0xf855C0C7...C8fCa985b
0.00042242 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TownHallZap

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion
File 1 of 7 : TownHallZap.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol";
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
import "solidity-bytes-utils/contracts/BytesLib.sol";

interface ITownHall {
    function mint(address to) external;
}

interface IWETH {
    function deposit() external payable;
    function withdraw(uint) external;
}

contract TownHallZap {
    using BytesLib for bytes;

    error TownHallZap__InvalidMintingCount();
    error TownHallZap__InvalidInputToken();
    error TownHallZap__InvalidOutputToken();
    error TownHallZap__InvalidETHSent();

    ITownHall public immutable townHall;
    IERC20 public immutable huntToken;
    ISwapRouter public immutable uniswapV3Router;
    // IQuoter public immutable uniswapV3Quoter;

    address private constant WETH_CONTRACT = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address private constant UNISWAP_V3_ROUTER = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
    // address private constant UNISWAP_V3_QUOTER = 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6;
    uint24 private constant UNISWAP_FEE = 3000; // The fee of the token pool to consider for the pair

    uint256 public constant LOCK_UP_AMOUNT = 1e21; // 1,000 HUNT per NFT minting
    uint256 public constant MAX_MINTING_COUNT = 200;

    constructor(address townHall_, address huntToken_) {
        townHall = ITownHall(townHall_);
        huntToken = IERC20(huntToken_);
        uniswapV3Router = ISwapRouter(UNISWAP_V3_ROUTER);
        // uniswapV3Quoter = IQuoter(UNISWAP_V3_QUOTER);

        // Approve infinite HUNT tokens to TownHall contract to save gas on each calls
        huntToken.approve(address(townHall), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
    }

    receive() external payable {}

    /**
     *  @notice Bulk minting interface for gas saving
     * (~25% reduced gas cost compared to multiple minting calls)
     */
    function mintBulk(address to, uint256 count) external {
        if (count < 1 || count > MAX_MINTING_COUNT) revert TownHallZap__InvalidMintingCount();

        uint256 totalHuntAmount = LOCK_UP_AMOUNT * count;
        huntToken.transferFrom(msg.sender, address(this), totalHuntAmount);
        // huntToken.approve(address(townHall), totalHuntAmount); // gas saving - approved infinitely on construction

        unchecked {
            for (uint256 i = 0; i < count; ++i) {
                townHall.mint(to);
            }
        }
    }

    /**
     * @notice Get the first token (output token) address from the Swap Path (exactOutput path should be reversed)
     * @dev Ref: https://uniswapv3book.com/docs/milestone_4/path/
     */
    function getOutputToken(bytes calldata path) public pure returns (address firstAddress) {
        bytes memory firstSlice = path.slice(0, 20);
        assembly {
          firstAddress := mload(add(firstSlice, 20))
        }
    }

    /**
     * @notice Get the last token (input token) address from the Swap Path (exactOutput path should be reversed)
     * @dev Ref: https://uniswapv3book.com/docs/milestone_4/path/
     */
    function getInputToken(bytes calldata path) public pure returns (address lastAddres) {
        bytes memory lastSlice = path.slice(path.length - 20, 20);
        assembly {
          lastAddres := mload(add(lastSlice, 20))
        }
    }

    // @notice Convert inputToken to HUNT and mint Building NFTs in one trasaction
    function convertAndMint(bytes calldata path, address mintTo, uint256 count, uint256 amountInMaximum) external {
        address inputToken = getInputToken(path);
        address outputToken = getOutputToken(path);

        if (inputToken == address(huntToken)) revert TownHallZap__InvalidInputToken();
        if (outputToken != address(huntToken)) revert TownHallZap__InvalidOutputToken();
        if (count < 1 || count > MAX_MINTING_COUNT) revert TownHallZap__InvalidMintingCount();

        TransferHelper.safeTransferFrom(inputToken, msg.sender, address(this), amountInMaximum);

        uint256 amountIn = _convertAndMint(path, mintTo, count, amountInMaximum);

        // For exactOutput swaps, the amountInMaximum may not have all been spent.
        // If the actual amount spent (amountIn) is less than the specified maximum amount,
        // we must refund the msg.sender and approve the uniswapV3Router to spend 0.
        if (amountIn < amountInMaximum) {
            TransferHelper.safeApprove(inputToken, address(uniswapV3Router), 0);
            TransferHelper.safeTransfer(inputToken, msg.sender, amountInMaximum - amountIn);
        }
    }

    function _convertAndMint(bytes calldata path, address mintTo, uint256 count, uint256 amountInMaximum) private returns (uint256 amountIn) {
        uint256 lockUpAmount = LOCK_UP_AMOUNT * count;
        address inputToken = getInputToken(path);

        // assert(IERC20(inputToken).balanceOf(address(this)) == amountInMaximum);
        TransferHelper.safeApprove(inputToken, address(uniswapV3Router), amountInMaximum);

        amountIn = uniswapV3Router.exactOutput(ISwapRouter.ExactOutputParams({
            path: path,
            recipient: address(this),
            deadline: block.timestamp,
            amountOut: lockUpAmount,
            amountInMaximum: amountInMaximum
        }));

        // huntToken.approve(address(townHall), lockUpAmount); // gas saving - approved infinitely on construction

        if (count == 1) {
            townHall.mint(mintTo);
        } else {
            unchecked {
                for (uint256 i = 0; i < count; ++i) {
                    townHall.mint(mintTo);
                }
            }
        }
    }

    // @notice Convert ETH to HUNT and mint Building NFTs in one trasaction
    // @dev `path` should starts with WETH address
    function convertETHAndMint(bytes calldata path, address mintTo, uint256 count, uint256 amountInMaximum) external payable {
        address inputToken = getInputToken(path);
        address outputToken = getOutputToken(path);

        if (inputToken == address(huntToken)) revert TownHallZap__InvalidInputToken();
        if (inputToken != WETH_CONTRACT) revert TownHallZap__InvalidInputToken();
        if (outputToken != address(huntToken)) revert TownHallZap__InvalidOutputToken();
        if (count < 1 || count > MAX_MINTING_COUNT) revert TownHallZap__InvalidMintingCount();
        if (msg.value != amountInMaximum) revert TownHallZap__InvalidETHSent();

        IWETH(WETH_CONTRACT).deposit{ value: msg.value }();

        uint256 amountIn = _convertAndMint(path, mintTo, count, amountInMaximum);

        // For exactOutput swaps, the amountInMaximum may not have all been spent.
        // If the actual amount spent (amountIn) is less than the specified maximum amount,
        // we must refund the msg.sender and approve the uniswapV3Router to spend 0.
        if (amountIn < amountInMaximum) {
            TransferHelper.safeApprove(WETH_CONTRACT, address(uniswapV3Router), 0);

            uint256 refundAMount = amountInMaximum - amountIn;
            IWETH(WETH_CONTRACT).withdraw(refundAMount);
            TransferHelper.safeTransferETH(msg.sender, refundAMount);
        }
    }
}

File 2 of 7 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 3 of 7 : BytesLib.sol
// SPDX-License-Identifier: Unlicense
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity >=0.8.0 <0.9.0;


library BytesLib {
    function concat(
        bytes memory _preBytes,
        bytes memory _postBytes
    )
        internal
        pure
        returns (bytes memory)
    {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    )
        internal
        pure
        returns (bytes memory)
    {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(
        bytes storage _preBytes,
        bytes memory _postBytes
    )
        internal
        view
        returns (bool)
    {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

File 4 of 7 : ISwapRouter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouter is IUniswapV3SwapCallback {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);

    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}

File 5 of 7 : IQuoter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

/// @title Quoter Interface
/// @notice Supports quoting the calculated amounts from exact input or exact output swaps
/// @dev These functions are not marked view because they rely on calling non-view functions and reverting
/// to compute the result. They are also not gas efficient and should not be called on-chain.
interface IQuoter {
    /// @notice Returns the amount out received for a given exact input swap without executing the swap
    /// @param path The path of the swap, i.e. each token pair and the pool fee
    /// @param amountIn The amount of the first token to swap
    /// @return amountOut The amount of the last token that would be received
    function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut);

    /// @notice Returns the amount out received for a given exact input but for a swap of a single pool
    /// @param tokenIn The token being swapped in
    /// @param tokenOut The token being swapped out
    /// @param fee The fee of the token pool to consider for the pair
    /// @param amountIn The desired input amount
    /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
    /// @return amountOut The amount of `tokenOut` that would be received
    function quoteExactInputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountIn,
        uint160 sqrtPriceLimitX96
    ) external returns (uint256 amountOut);

    /// @notice Returns the amount in required for a given exact output swap without executing the swap
    /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order
    /// @param amountOut The amount of the last token to receive
    /// @return amountIn The amount of first token required to be paid
    function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn);

    /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool
    /// @param tokenIn The token being swapped in
    /// @param tokenOut The token being swapped out
    /// @param fee The fee of the token pool to consider for the pair
    /// @param amountOut The desired output amount
    /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
    /// @return amountIn The amount required as the input for the swap in order to receive `amountOut`
    function quoteExactOutputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountOut,
        uint160 sqrtPriceLimitX96
    ) external returns (uint256 amountIn);
}

File 6 of 7 : TransferHelper.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'STE');
    }
}

File 7 of 7 : IUniswapV3SwapCallback.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
interface IUniswapV3SwapCallback {
    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
    /// @dev In the implementation you must pay the pool tokens owed for the swap.
    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
    function uniswapV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata data
    ) external;
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"townHall_","type":"address"},{"internalType":"address","name":"huntToken_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"TownHallZap__InvalidETHSent","type":"error"},{"inputs":[],"name":"TownHallZap__InvalidInputToken","type":"error"},{"inputs":[],"name":"TownHallZap__InvalidMintingCount","type":"error"},{"inputs":[],"name":"TownHallZap__InvalidOutputToken","type":"error"},{"inputs":[],"name":"LOCK_UP_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MINTING_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"mintTo","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"name":"convertAndMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"mintTo","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"name":"convertETHAndMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"}],"name":"getInputToken","outputs":[{"internalType":"address","name":"lastAddres","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"}],"name":"getOutputToken","outputs":[{"internalType":"address","name":"firstAddress","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"huntToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintBulk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"townHall","outputs":[{"internalType":"contract ITownHall","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV3Router","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040523480156200001157600080fd5b50604051620018af380380620018af8339810160408190526200003491620000f7565b6001600160a01b03828116608081905290821660a081905273e592427a0aece92de3edee1f18e0157c0586156460c05260405163095ea7b360e01b8152600481019290925260001960248301529063095ea7b3906044016020604051808303816000875af1158015620000ab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d191906200012f565b5050506200015a565b80516001600160a01b0381168114620000f257600080fd5b919050565b600080604083850312156200010b57600080fd5b6200011683620000da565b91506200012660208401620000da565b90509250929050565b6000602082840312156200014257600080fd5b815180151581146200015357600080fd5b9392505050565b60805160a05160c0516116d2620001dd60003960008181610131015281816103f3015281816106e701528181610bdb0152610c0201526000818161021a0152818161027a015281816102ff015281816104550152818161053d015261084801526000818160d30152818161091b01528181610d680152610e1901526116d26000f3fe6080604052600436106100b55760003560e01c8063bca4d16611610069578063cc6b8b271161004e578063cc6b8b27146101e8578063fa03a4c414610208578063fdd5aa371461023c57600080fd5b8063bca4d166146101ab578063c8fc7c13146101cb57600080fd5b8063433f5d651161009a578063433f5d6514610153578063517b7bf314610176578063722277d61461019857600080fd5b80631d4e1981146100c15780632c76d7a61461011f57600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100f57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561012b57600080fd5b506100f57f000000000000000000000000000000000000000000000000000000000000000081565b34801561015f57600080fd5b5061016860c881565b604051908152602001610116565b34801561018257600080fd5b5061019661019136600461143b565b61025c565b005b6101966101a636600461143b565b610437565b3480156101b757600080fd5b506101966101c63660046114a1565b6107af565b3480156101d757600080fd5b50610168683635c9adc5dea0000081565b3480156101f457600080fd5b506100f56102033660046114cb565b610988565b34801561021457600080fd5b506100f57f000000000000000000000000000000000000000000000000000000000000000081565b34801561024857600080fd5b506100f56102573660046114cb565b6109e7565b60006102688686610988565b9050600061027687876109e7565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036102fd576040517f6f1c7c0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610382576040517f5237765f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001841080610391575060c884115b156103c8576040517f9475d0e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d482333086610a31565b60006103e38888888888610baf565b90508381101561042d57610419837f00000000000000000000000000000000000000000000000000000000000000006000610e8d565b61042d8333610428848861153c565b610ffd565b5050505050505050565b60006104438686610988565b9050600061045187876109e7565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104d8576040517f6f1c7c0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21461053b576040517f6f1c7c0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105c0576040517f5237765f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018410806105cf575060c884115b15610606576040517f9475d0e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82341461063f576040517fb4bb2ded00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069b57600080fd5b505af11580156106af573d6000803e3d6000fd5b505050505060006106c38888888888610baf565b90508381101561042d5761070d73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f00000000000000000000000000000000000000000000000000000000000000006000610e8d565b6000610719828661153c565b6040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905290915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b505050506107a43382611166565b505050505050505050565b60018110806107be575060c881115b156107f5576040517f9475d0e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061080a82683635c9adc5dea00000611555565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018290529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156108a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ca919061156c565b5060005b82811015610982576040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a62784290602401600060405180830381600087803b15801561095f57600080fd5b505af1158015610973573d6000803e3d6000fd5b505050508060010190506108ce565b50505050565b6000806109db61099960148561153c565b601486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092949392505061124f9050565b60140151949350505050565b6000806109db6000601486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092949392505061124f9050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691610ad091906115b9565b6000604051808303816000865af19150503d8060008114610b0d576040519150601f19603f3d011682016040523d82523d6000602084013e610b12565b606091505b5091509150818015610b3c575080511580610b3c575080806020019051810190610b3c919061156c565b610ba7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f535446000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b505050505050565b600080610bc584683635c9adc5dea00000611555565b90506000610bd38888610988565b9050610c00817f000000000000000000000000000000000000000000000000000000000000000086610e8d565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f28c04986040518060a001604052808b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525030602082015242604080830191909152606082018790526080909101889052517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b168152610cd691906004016115d5565b6020604051808303816000875af1158015610cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d199190611670565b925084600103610dc9576040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a62784290602401600060405180830381600087803b158015610dac57600080fd5b505af1158015610dc0573d6000803e3d6000fd5b50505050610e82565b60005b85811015610e80576040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a62784290602401600060405180830381600087803b158015610e5d57600080fd5b505af1158015610e71573d6000803e3d6000fd5b50505050806001019050610dcc565b505b505095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691610f2491906115b9565b6000604051808303816000865af19150503d8060008114610f61576040519150601f19603f3d011682016040523d82523d6000602084013e610f66565b606091505b5091509150818015610f90575080511580610f90575080806020019051810190610f90919061156c565b610ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f53410000000000000000000000000000000000000000000000000000000000006044820152606401610b9e565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161109491906115b9565b6000604051808303816000865af19150503d80600081146110d1576040519150601f19603f3d011682016040523d82523d6000602084013e6110d6565b606091505b5091509150818015611100575080511580611100575080806020019051810190611100919061156c565b610ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f53540000000000000000000000000000000000000000000000000000000000006044820152606401610b9e565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161119d91906115b9565b60006040518083038185875af1925050503d80600081146111da576040519150601f19603f3d011682016040523d82523d6000602084013e6111df565b606091505b505090508061124a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53544500000000000000000000000000000000000000000000000000000000006044820152606401610b9e565b505050565b60608161125d81601f611689565b10156112c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610b9e565b6112cf8284611689565b84511015611339576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610b9e565b60608215801561135857604051915060008252602082016040526113c0565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015611391578051835260209283019201611379565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60008083601f8401126113db57600080fd5b50813567ffffffffffffffff8111156113f357600080fd5b60208301915083602082850101111561140b57600080fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461143657600080fd5b919050565b60008060008060006080868803121561145357600080fd5b853567ffffffffffffffff81111561146a57600080fd5b611476888289016113c9565b9096509450611489905060208701611412565b94979396509394604081013594506060013592915050565b600080604083850312156114b457600080fd5b6114bd83611412565b946020939093013593505050565b600080602083850312156114de57600080fd5b823567ffffffffffffffff8111156114f557600080fd5b611501858286016113c9565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561154f5761154f61150d565b92915050565b808202811582820484141761154f5761154f61150d565b60006020828403121561157e57600080fd5b8151801515811461158e57600080fd5b9392505050565b60005b838110156115b0578181015183820152602001611598565b50506000910152565b600082516115cb818460208701611595565b9190910192915050565b602081526000825160a0602084015280518060c08501526115fd8160e0860160208501611595565b73ffffffffffffffffffffffffffffffffffffffff60208601511660408501526040850151606085015260608501516080850152608085015160a085015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561168257600080fd5b5051919050565b8082018082111561154f5761154f61150d56fea26469706673582212205badf8cf88d81577fbf23f944669615395ddf6365fa75e8ebd870140c19807e864736f6c63430008110033000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b6389071930000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa5

Deployed Bytecode

0x6080604052600436106100b55760003560e01c8063bca4d16611610069578063cc6b8b271161004e578063cc6b8b27146101e8578063fa03a4c414610208578063fdd5aa371461023c57600080fd5b8063bca4d166146101ab578063c8fc7c13146101cb57600080fd5b8063433f5d651161009a578063433f5d6514610153578063517b7bf314610176578063722277d61461019857600080fd5b80631d4e1981146100c15780632c76d7a61461011f57600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100f57f000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b63890719381565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561012b57600080fd5b506100f57f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481565b34801561015f57600080fd5b5061016860c881565b604051908152602001610116565b34801561018257600080fd5b5061019661019136600461143b565b61025c565b005b6101966101a636600461143b565b610437565b3480156101b757600080fd5b506101966101c63660046114a1565b6107af565b3480156101d757600080fd5b50610168683635c9adc5dea0000081565b3480156101f457600080fd5b506100f56102033660046114cb565b610988565b34801561021457600080fd5b506100f57f0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa581565b34801561024857600080fd5b506100f56102573660046114cb565b6109e7565b60006102688686610988565b9050600061027687876109e7565b90507f0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036102fd576040517f6f1c7c0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610382576040517f5237765f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001841080610391575060c884115b156103c8576040517f9475d0e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d482333086610a31565b60006103e38888888888610baf565b90508381101561042d57610419837f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615646000610e8d565b61042d8333610428848861153c565b610ffd565b5050505050505050565b60006104438686610988565b9050600061045187876109e7565b90507f0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104d8576040517f6f1c7c0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21461053b576040517f6f1c7c0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105c0576040517f5237765f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018410806105cf575060c884115b15610606576040517f9475d0e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82341461063f576040517fb4bb2ded00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069b57600080fd5b505af11580156106af573d6000803e3d6000fd5b505050505060006106c38888888888610baf565b90508381101561042d5761070d73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615646000610e8d565b6000610719828661153c565b6040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905290915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b505050506107a43382611166565b505050505050505050565b60018110806107be575060c881115b156107f5576040517f9475d0e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061080a82683635c9adc5dea00000611555565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018290529091507f0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa573ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156108a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ca919061156c565b5060005b82811015610982576040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527f000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b6389071931690636a62784290602401600060405180830381600087803b15801561095f57600080fd5b505af1158015610973573d6000803e3d6000fd5b505050508060010190506108ce565b50505050565b6000806109db61099960148561153c565b601486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092949392505061124f9050565b60140151949350505050565b6000806109db6000601486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092949392505061124f9050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691610ad091906115b9565b6000604051808303816000865af19150503d8060008114610b0d576040519150601f19603f3d011682016040523d82523d6000602084013e610b12565b606091505b5091509150818015610b3c575080511580610b3c575080806020019051810190610b3c919061156c565b610ba7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f535446000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b505050505050565b600080610bc584683635c9adc5dea00000611555565b90506000610bd38888610988565b9050610c00817f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156486610e8d565b7f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663f28c04986040518060a001604052808b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525030602082015242604080830191909152606082018790526080909101889052517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b168152610cd691906004016115d5565b6020604051808303816000875af1158015610cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d199190611670565b925084600103610dc9576040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301527f000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b6389071931690636a62784290602401600060405180830381600087803b158015610dac57600080fd5b505af1158015610dc0573d6000803e3d6000fd5b50505050610e82565b60005b85811015610e80576040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301527f000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b6389071931690636a62784290602401600060405180830381600087803b158015610e5d57600080fd5b505af1158015610e71573d6000803e3d6000fd5b50505050806001019050610dcc565b505b505095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691610f2491906115b9565b6000604051808303816000865af19150503d8060008114610f61576040519150601f19603f3d011682016040523d82523d6000602084013e610f66565b606091505b5091509150818015610f90575080511580610f90575080806020019051810190610f90919061156c565b610ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f53410000000000000000000000000000000000000000000000000000000000006044820152606401610b9e565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161109491906115b9565b6000604051808303816000865af19150503d80600081146110d1576040519150601f19603f3d011682016040523d82523d6000602084013e6110d6565b606091505b5091509150818015611100575080511580611100575080806020019051810190611100919061156c565b610ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f53540000000000000000000000000000000000000000000000000000000000006044820152606401610b9e565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161119d91906115b9565b60006040518083038185875af1925050503d80600081146111da576040519150601f19603f3d011682016040523d82523d6000602084013e6111df565b606091505b505090508061124a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53544500000000000000000000000000000000000000000000000000000000006044820152606401610b9e565b505050565b60608161125d81601f611689565b10156112c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610b9e565b6112cf8284611689565b84511015611339576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610b9e565b60608215801561135857604051915060008252602082016040526113c0565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015611391578051835260209283019201611379565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60008083601f8401126113db57600080fd5b50813567ffffffffffffffff8111156113f357600080fd5b60208301915083602082850101111561140b57600080fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461143657600080fd5b919050565b60008060008060006080868803121561145357600080fd5b853567ffffffffffffffff81111561146a57600080fd5b611476888289016113c9565b9096509450611489905060208701611412565b94979396509394604081013594506060013592915050565b600080604083850312156114b457600080fd5b6114bd83611412565b946020939093013593505050565b600080602083850312156114de57600080fd5b823567ffffffffffffffff8111156114f557600080fd5b611501858286016113c9565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561154f5761154f61150d565b92915050565b808202811582820484141761154f5761154f61150d565b60006020828403121561157e57600080fd5b8151801515811461158e57600080fd5b9392505050565b60005b838110156115b0578181015183820152602001611598565b50506000910152565b600082516115cb818460208701611595565b9190910192915050565b602081526000825160a0602084015280518060c08501526115fd8160e0860160208501611595565b73ffffffffffffffffffffffffffffffffffffffff60208601511660408501526040850151606085015260608501516080850152608085015160a085015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561168257600080fd5b5051919050565b8082018082111561154f5761154f61150d56fea26469706673582212205badf8cf88d81577fbf23f944669615395ddf6365fa75e8ebd870140c19807e864736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b6389071930000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa5

-----Decoded View---------------
Arg [0] : townHall_ (address): 0xb09A1410cF4C49F92482F5cd2CbF19b638907193
Arg [1] : huntToken_ (address): 0x9AAb071B4129B083B01cB5A0Cb513Ce7ecA26fa5

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b09a1410cf4c49f92482f5cd2cbf19b638907193
Arg [1] : 0000000000000000000000009aab071b4129b083b01cb5a0cb513ce7eca26fa5


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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  ]
[ 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.