ETH Price: $3,648.67 (-2.53%)

Contract

0x000000000000feA5F4B241F9E77B4D43B76798a9
 
Transaction Hash
Method
Block
From
To
Snipe_2572234525213175002024-12-02 21:26:475 hrs ago1733174807IN
MEV Bot: 0x000...8a9
0 ETH0.0127899954.26458318
Deposit Self213169582024-12-02 19:37:237 hrs ago1733168243IN
MEV Bot: 0x000...8a9
0.16 ETH0.0009905533.05497242
Snipe_2572234525213168772024-12-02 19:20:597 hrs ago1733167259IN
MEV Bot: 0x000...8a9
0 ETH0.003181128.41748147
Snipe_2572234525213168712024-12-02 19:19:477 hrs ago1733167187IN
MEV Bot: 0x000...8a9
0 ETH0.0031930828.52450008
Snipe_2572234525213168562024-12-02 19:16:477 hrs ago1733167007IN
MEV Bot: 0x000...8a9
0 ETH0.0029084225.98153944
Snipe_2572234525213168552024-12-02 19:16:357 hrs ago1733166995IN
MEV Bot: 0x000...8a9
0 ETH0.0033250725.7673871
Snipe_2572234525213162842024-12-02 17:22:119 hrs ago1733160131IN
MEV Bot: 0x000...8a9
0 ETH0.0092584943.31421184
Snipe_2572234525213161882024-12-02 17:02:599 hrs ago1733158979IN
MEV Bot: 0x000...8a9
0 ETH0.0050711135.28637667
Snipe_2572234525213161312024-12-02 16:51:3510 hrs ago1733158295IN
MEV Bot: 0x000...8a9
0 ETH0.0084326739.97662945
Snipe_2572234525213161182024-12-02 16:48:5910 hrs ago1733158139IN
MEV Bot: 0x000...8a9
0 ETH0.0052352837.1652982
Snipe_2572234525213160972024-12-02 16:44:4710 hrs ago1733157887IN
MEV Bot: 0x000...8a9
0 ETH0.0056405140.02831774
Deposit Self213152792024-12-02 14:00:1112 hrs ago1733148011IN
MEV Bot: 0x000...8a9
3.5 ETH0.0006221120.75984185
Snipe_2572234525213147922024-12-02 12:21:4714 hrs ago1733142107IN
MEV Bot: 0x000...8a9
0 ETH0.001845813.12740588
Snipe_2572234525213144452024-12-02 11:11:3515 hrs ago1733137895IN
MEV Bot: 0x000...8a9
0 ETH0.0032566614.06086942
Snipe_2572234525213141112024-12-02 10:04:2316 hrs ago1733133863IN
MEV Bot: 0x000...8a9
0 ETH0.0036616814.39743549
Snipe_2572234525213138492024-12-02 9:11:4717 hrs ago1733130707IN
MEV Bot: 0x000...8a9
0 ETH0.0017149915.31876173
Snipe_2572234525213136882024-12-02 8:39:3518 hrs ago1733128775IN
MEV Bot: 0x000...8a9
0 ETH0.003914417.44323901
Snipe_2572234525213135132024-12-02 8:04:2318 hrs ago1733126663IN
MEV Bot: 0x000...8a9
0 ETH0.0029269810.51105308
Snipe_2572234525213131802024-12-02 6:57:2319 hrs ago1733122643IN
MEV Bot: 0x000...8a9
0 ETH0.001342311.98461606
Snipe_2572234525213098432024-12-01 19:46:4731 hrs ago1733082407IN
MEV Bot: 0x000...8a9
0 ETH0.0025337517.99850392
Snipe_2572234525213088932024-12-01 16:35:3534 hrs ago1733070935IN
MEV Bot: 0x000...8a9
0 ETH0.0060353523.02032291
Snipe_2572234525213083312024-12-01 14:42:5936 hrs ago1733064179IN
MEV Bot: 0x000...8a9
0 ETH0.0088664917.18528667
Deposit Self213078252024-12-01 13:01:4737 hrs ago1733058107IN
MEV Bot: 0x000...8a9
0.555 ETH0.0003889112.97799659
Deposit Self213078202024-12-01 13:00:4737 hrs ago1733058047IN
MEV Bot: 0x000...8a9
0.06 ETH0.000362512.09685843
Snipe_2572234525213075412024-12-01 12:04:4738 hrs ago1733054687IN
MEV Bot: 0x000...8a9
0 ETH0.002516119.79143184
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
213175002024-12-02 21:26:475 hrs ago1733174807
MEV Bot: 0x000...8a9
0.02641956 ETH
213175002024-12-02 21:26:475 hrs ago1733174807
MEV Bot: 0x000...8a9
0.01948043 ETH
213175002024-12-02 21:26:475 hrs ago1733174807
MEV Bot: 0x000...8a9
0.3775 ETH
213175002024-12-02 21:26:475 hrs ago1733174807
MEV Bot: 0x000...8a9
0.42339999 ETH
213168772024-12-02 19:20:597 hrs ago1733167259
MEV Bot: 0x000...8a9
0.28947593 ETH
213168772024-12-02 19:20:597 hrs ago1733167259
MEV Bot: 0x000...8a9
0.00332444 ETH
213168772024-12-02 19:20:597 hrs ago1733167259
MEV Bot: 0x000...8a9
0.29280038 ETH
213168712024-12-02 19:19:477 hrs ago1733167187
MEV Bot: 0x000...8a9
0.32578295 ETH
213168712024-12-02 19:19:477 hrs ago1733167187
MEV Bot: 0x000...8a9
0.02306062 ETH
213168712024-12-02 19:19:477 hrs ago1733167187
MEV Bot: 0x000...8a9
0.34884357 ETH
213168562024-12-02 19:16:477 hrs ago1733167007
MEV Bot: 0x000...8a9
0.31775741 ETH
213168562024-12-02 19:16:477 hrs ago1733167007
MEV Bot: 0x000...8a9
0.0021763 ETH
213168562024-12-02 19:16:477 hrs ago1733167007
MEV Bot: 0x000...8a9
0.31993371 ETH
213168552024-12-02 19:16:357 hrs ago1733166995
MEV Bot: 0x000...8a9
0.31775741 ETH
213168552024-12-02 19:16:357 hrs ago1733166995
MEV Bot: 0x000...8a9
0.0021763 ETH
213168552024-12-02 19:16:357 hrs ago1733166995
MEV Bot: 0x000...8a9
0.31993371 ETH
213162842024-12-02 17:22:119 hrs ago1733160131
MEV Bot: 0x000...8a9
0.01895294 ETH
213162842024-12-02 17:22:119 hrs ago1733160131
MEV Bot: 0x000...8a9
0.00674705 ETH
213162842024-12-02 17:22:119 hrs ago1733160131
MEV Bot: 0x000...8a9
0.35 ETH
213161882024-12-02 17:02:599 hrs ago1733158979
MEV Bot: 0x000...8a9
0.25353894 ETH
213161882024-12-02 17:02:599 hrs ago1733158979
MEV Bot: 0x000...8a9
0.01426105 ETH
213161882024-12-02 17:02:599 hrs ago1733158979
MEV Bot: 0x000...8a9
0.2678 ETH
213161312024-12-02 16:51:3510 hrs ago1733158295
MEV Bot: 0x000...8a9
0.02466126 ETH
213161312024-12-02 16:51:3510 hrs ago1733158295
MEV Bot: 0x000...8a9
0.03097873 ETH
213161312024-12-02 16:51:3510 hrs ago1733158295
MEV Bot: 0x000...8a9
0.4 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AutoSniper

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 7 : AutoSniper.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {SniperState} from "./helpers/SniperStructs.sol";
import {IERC721} from "forge-std/interfaces/IERC721.sol";
import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {IERC1155} from "forge-std/interfaces/IERC1155.sol";
import {Ownable} from "solady/auth/Ownable.sol";

/**
 * @title AutoSniper 4.0 for @oSnipeNFT
 * @author 0xQuit
 */
/*

        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*+=--::::::--=+*#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*=:.       ......        :=*%@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#=.    .-+*%@@@@@@@@@@@@%#+=:    -@@@@@@=:::=#@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@%+.   :=#@@@@@@@@@@@@@@@@@@@@@@@@#+#@@@@@%**+-:::-%@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@#-   :+%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%******+-::=@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@%:   =%@@@@@@@@@@@@@@@@%%%%@@@@@@@@@@@@@@%*++++++***+=+@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@=   -@@@@@@@@@@@@#+-:.         :-+%@@@@@%*+++++++++*#@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@#.  :%@@@@@@@@@%+:      ..:::::.  .*@@@%*+++++++++++#@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@*   =@@@@@@@@@#:    .=*%@@@@@@@@@@%@@@%+----======+#@@@@@%@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@+   *@@@@@@@@#:   .+%@@@@@@@@@@@@@@@@@@=-------==+#@@@@@%- -@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@#   #@@@@@@@@=   .*@@@@@@@@@#=.    .-+#+=--------*@@@@@@@%   +@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@.  =@@@@@@@@-   =@@@@@@@@@@:  -+**+-   .--=----+%@@@@@@@@@#   %@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@+  .@@@@@@@@-   +@@@@@@@@@@-  #@@@@%+-:.  :=*@#%@@@*%@@@@@@@=  -@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@.  #@@@@@@@+   =@@@@@@@@@@@:  @@@%=-----.  #@@@@@*. -@@@@@@@@   %@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@#   @@@@@@@@.  .@@@@@@@@@@@@%  :#=:::::--*+=@@@@@@-   %@@@@@@@-  +@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@+  :@@@@@@@%   =@@@@@@@@@@@@@%-:--::::-*@@@@@@@@@@*   *@@@@@@@+  :@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@=  -@@@@@@@#   +@@@@@@@@@@@@@#-:---:-*@@@@@@@@@@@@#   +@@@@@@@+  :@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@+  -@@@@@@@%   =@@@@@@*#@@@#-::---=. -@@@@@@@@@@@@*   +@@@@@@@+  :@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@#  .@@@@@@@@   .@@@@@+  #*-:::--*@@#  -@@@@@@@@@@@-   %@@@@@@@-  =@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@   #@@@@@@@+  =@@@@@%  .--:--+@@@@@=  %@@@@@@@@@#   :@@@@@@@@   %@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@=  :@@@@@@@@=%@@@@@@*:   :-*@@@@@@%. .@@@@@@@@@%    %@@@@@@@=  :@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@   +@@@@@@@@@@@@#+---:.  .=*###*-  :%@@@@@@@@#   .%@@@@@@@#   #@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@*   %@@@@@@@@@#=------*%+-      .-#@@@@@@@@%=   .%@@@@@@@@.  =@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@= .*@@@@@@@@+------=%@@@@@@%%%@@@@@@@@@@#-    +@@@@@@@@@:  :@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@#@@@@@@@@*===---=#@@@@@@@@@@@@@@@@@%*-     +@@@@@@@@@#   -@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@*=====+#%@@@@@%= .:--==--:.     .-*@@@@@@@@@@+   +@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@+--==+#@@@@@@@@=:.           :=*%@@@@@@@@@@@*.  .#@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@*===+-*@@@@@@@@@@@@@@%%#####%@@@@@@@@@@@@@@@*.   +@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@#+==#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#=   .+@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@+==+%@@@@@@@@@%*%@@@@@@@@@@@@@@@@@@@@@@@@@*-    -*@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@#=%@@@@@@@@@+    -=*%@@@@@@@@@@@@@@%*+-.    :+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%+-.      ..:::::::.      .-+#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*+=-:........:-=+*#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

*/

contract AutoSniper is Ownable {
    error InsufficientBalance();
    error FailedToWithdraw();
    error FailedToPayAutosniper();
    error FailedToPayValidator();
    error OrderFailed();
    error CallerNotFulfiller();
    error MigrationNotEnabled();
    error ArrayLengthMismatch();
    error SniperIsPaused();
    error FulfillerCannotHaveBalance();

    event Deposit(address sniper, uint256 amount);
    event Withdrawal(address sniper, uint256 amount);

    address private fulfillerAddress = 0x7D79Bd0E4B3dC90665A3ed30Aa6C6c06c89D224E;
    address public nextContractVersionAddress;
    bool public migrationEnabled;
    mapping(address => SniperState) public sniperStates;

    constructor() {
        _initializeOwner(tx.origin);
    }

    // only the fulfiller can call this function
    modifier onlyFulfiller() {
        if (msg.sender != fulfillerAddress) revert CallerNotFulfiller();
        _;
    }

    // allow the contract to receive Ether
    receive() external payable {}

    /**
     * @dev Generalized function for fulfilling orders
     * @param contractAddresses a list of contract addresses that will be called
     * @param calls a matching array to contractAddresses, each index being a call to make to a given contract
     * @param values a matching array to contractAddresses, each index being the value to send with the call
     * @param sniper the address of the sniper
     * @param validatorTip the amount to send to block.coinbase. Reverts if this is 0.
     * @param fulfillerTip the amount to send to fulfillerAddress. Reverts if this is 0.
     */
    function snipe_2572234525(
        address[] calldata contractAddresses,
        bytes[] calldata calls,
        uint256[] calldata values,
        address sniper,
        uint256 validatorTip,
        uint256 fulfillerTip
    ) external onlyFulfiller {
        if (contractAddresses.length != calls.length) revert ArrayLengthMismatch();
        if (calls.length != values.length) revert ArrayLengthMismatch();
        if (sniperStates[sniper].isPaused) revert SniperIsPaused();

        uint256 balanceBefore = address(this).balance;

        for (uint256 i = 0; i < contractAddresses.length; ++i) {
            (bool success,) = contractAddresses[i].call{value: values[i]}(calls[i]);
            if (!success) revert OrderFailed();
        }

        (bool validatorPaid,) = block.coinbase.call{value: validatorTip}("");
        if (!validatorPaid) revert FailedToPayValidator();
        (bool fulfillerPaid,) = fulfillerAddress.call{value: fulfillerTip}("");
        if (!fulfillerPaid) revert FailedToPayAutosniper();

        uint256 balanceAfter = address(this).balance;

        if (balanceAfter < balanceBefore) {
            uint128 spent = uint128(balanceBefore - balanceAfter);
            if (sniperStates[sniper].ethBalance < spent) revert InsufficientBalance();
            unchecked {
                sniperStates[sniper].ethBalance -= spent;
            }
            emit Withdrawal(sniper, spent);
        } else if (balanceAfter > balanceBefore) {
            unchecked {
                sniperStates[sniper].ethBalance += uint128(balanceAfter - balanceBefore);
            }
            emit Deposit(sniper, balanceAfter - balanceBefore);
        }
    }

    /**
     * @dev deposit Ether into the contract.
     * @param sniper is the address who's balance is affected.
     */
    function deposit(address sniper) public payable {
        if (tx.origin == fulfillerAddress) revert FulfillerCannotHaveBalance();
        unchecked {
            sniperStates[sniper].ethBalance += uint128(msg.value);
        }

        emit Deposit(sniper, msg.value);
    }

    /**
     * @dev deposit Ether into your own contract balance.
     */
    function depositSelf() external payable {
        deposit(msg.sender);
    }

    /**
     * @dev withdraw Ether from your contract balance
     * @param amount the amount of Ether to be withdrawn
     */
    function withdraw(uint256 amount) external {
        if (tx.origin == fulfillerAddress) revert FulfillerCannotHaveBalance();

        if (sniperStates[msg.sender].ethBalance < amount) revert InsufficientBalance();
        unchecked {
            sniperStates[msg.sender].ethBalance -= uint128(amount);
        }

        (bool success,) = payable(msg.sender).call{value: amount}("");
        if (!success) revert FailedToWithdraw();

        emit Withdrawal(msg.sender, amount);
    }

    function setUserIsPaused(bool isPaused) external {
        sniperStates[msg.sender].isPaused = isPaused;
    }

    /**
     * @dev Owner function to change fulfiller address if needed.
     */
    function setFulfillerAddress(address _fulfiller) external onlyOwner {
        fulfillerAddress = _fulfiller;
    }

    /**
     * Enables migration and sets a destination address (the new contract)
     * @param _destination the new AutoSniper version to allow migration to.
     */
    function setMigrationAddress(address _destination) external onlyOwner {
        migrationEnabled = true;
        nextContractVersionAddress = _destination;
    }

    /**
     * @dev in the event of a future contract upgrade, this function allows snipers to
     * easily move their ether balance to the new contract. This can only be called by
     * the sniper to move their personal balance - the contract owner or anybody else
     * does not have the power to migrate balances for users.
     */
    function migrateBalance() external {
        if (!migrationEnabled) revert MigrationNotEnabled();
        uint256 balanceToMigrate = sniperStates[msg.sender].ethBalance;
        sniperStates[msg.sender].ethBalance = 0;

        (bool success,) = nextContractVersionAddress.call{value: balanceToMigrate}(
            abi.encodeWithSelector(this.deposit.selector, msg.sender)
        );
        if (!success) revert FailedToWithdraw();
    }

    function sniperBalance(address sniper) external view returns (uint128) {
        return sniperStates[sniper].ethBalance;
    }

    function onERC1155Received(address, address, uint256, uint256, bytes calldata) public virtual returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata)
        public
        virtual
        returns (bytes4)
    {
        return this.onERC1155BatchReceived.selector;
    }

    function onERC721Received(address, address, uint256, bytes calldata) external virtual returns (bytes4) {
        return 0x150b7a02;
    }

    // Used by ERC721BasicToken.sol
    function onERC721Received(address, uint256, bytes calldata) external virtual returns (bytes4) {
        return 0xf0b9e5ba;
    }

    function supportsInterface(bytes4 interfaceId) external view virtual returns (bool) {
        return interfaceId == this.supportsInterface.selector;
    }

    // Emergency function: In case any ERC20 tokens get stuck in the contract unintentionally
    // Only owner can retrieve the asset balance to a recipient address
    function rescueERC20(address asset, address recipient) external onlyOwner {
        IERC20 token = IERC20(asset);
        token.transfer(recipient, token.balanceOf(address(this)));
    }

    // Emergency function: In case any ERC721 tokens get stuck in the contract unintentionally
    // Only owner can retrieve the asset balance to a recipient address
    function rescueERC721(address asset, uint256[] calldata ids, address recipient) external onlyOwner {
        for (uint256 i = 0; i < ids.length; i++) {
            IERC721(asset).transferFrom(address(this), recipient, ids[i]);
        }
    }

    // Emergency function: In case any ERC1155 tokens get stuck in the contract unintentionally
    // Only owner can retrieve the asset balance to a recipient address
    function rescueERC1155(address asset, uint256[] calldata ids, uint256[] calldata amounts, address recipient)
        external
        onlyOwner
    {
        for (uint256 i = 0; i < ids.length; i++) {
            IERC1155(asset).safeTransferFrom(address(this), recipient, ids[i], amounts[i], "");
        }
    }
}

File 2 of 7 : SniperStructs.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.24;

struct SniperState {
    uint128 ethBalance;
    bool isPaused;
}

File 3 of 7 : IERC721.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

import "./IERC165.sol";

/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x80ac58cd.
interface IERC721 is IERC165 {
    /// @dev This emits when ownership of any NFT changes by any mechanism.
    /// This event emits when NFTs are created (`from` == 0) and destroyed
    /// (`to` == 0). Exception: during contract creation, any number of NFTs
    /// may be created and assigned without emitting Transfer. At the time of
    /// any transfer, the approved address for that NFT (if any) is reset to none.
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

    /// @dev This emits when the approved address for an NFT is changed or
    /// reaffirmed. The zero address indicates there is no approved address.
    /// When a Transfer event emits, this also indicates that the approved
    /// address for that NFT (if any) is reset to none.
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

    /// @dev This emits when an operator is enabled or disabled for an owner.
    /// The operator can manage all NFTs of the owner.
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    /// @notice Count all NFTs assigned to an owner
    /// @dev NFTs assigned to the zero address are considered invalid, and this
    /// function throws for queries about the zero address.
    /// @param _owner An address for whom to query the balance
    /// @return The number of NFTs owned by `_owner`, possibly zero
    function balanceOf(address _owner) external view returns (uint256);

    /// @notice Find the owner of an NFT
    /// @dev NFTs assigned to zero address are considered invalid, and queries
    /// about them do throw.
    /// @param _tokenId The identifier for an NFT
    /// @return The address of the owner of the NFT
    function ownerOf(uint256 _tokenId) external view returns (address);

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    /// operator, or the approved address for this NFT. Throws if `_from` is
    /// not the current owner. Throws if `_to` is the zero address. Throws if
    /// `_tokenId` is not a valid NFT. When transfer is complete, this function
    /// checks if `_to` is a smart contract (code size > 0). If so, it calls
    /// `onERC721Received` on `_to` and throws if the return value is not
    /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param data Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable;

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    /// except this function just sets data to "".
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    /// THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    /// operator, or the approved address for this NFT. Throws if `_from` is
    /// not the current owner. Throws if `_to` is the zero address. Throws if
    /// `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

    /// @notice Change or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    /// Throws unless `msg.sender` is the current NFT owner, or an authorized
    /// operator of the current owner.
    /// @param _approved The new approved NFT controller
    /// @param _tokenId The NFT to approve
    function approve(address _approved, uint256 _tokenId) external payable;

    /// @notice Enable or disable approval for a third party ("operator") to manage
    /// all of `msg.sender`'s assets
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
    /// multiple operators per owner.
    /// @param _operator Address to add to the set of authorized operators
    /// @param _approved True if the operator is approved, false to revoke approval
    function setApprovalForAll(address _operator, bool _approved) external;

    /// @notice Get the approved address for a single NFT
    /// @dev Throws if `_tokenId` is not a valid NFT.
    /// @param _tokenId The NFT to find the approved address for
    /// @return The approved address for this NFT, or the zero address if there is none
    function getApproved(uint256 _tokenId) external view returns (address);

    /// @notice Query if an address is an authorized operator for another address
    /// @param _owner The address that owns the NFTs
    /// @param _operator The address that acts on behalf of the owner
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
interface IERC721TokenReceiver {
    /// @notice Handle the receipt of an NFT
    /// @dev The ERC721 smart contract calls this function on the recipient
    /// after a `transfer`. This function MAY throw to revert and reject the
    /// transfer. Return of other than the magic value MUST result in the
    /// transaction being reverted.
    /// Note: the contract address is always the message sender.
    /// @param _operator The address which called `safeTransferFrom` function
    /// @param _from The address which previously owned the token
    /// @param _tokenId The NFT identifier which is being transferred
    /// @param _data Additional data with no specified format
    /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    ///  unless throwing
    function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data)
        external
        returns (bytes4);
}

/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x5b5e139f.
interface IERC721Metadata is IERC721 {
    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external view returns (string memory _name);

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external view returns (string memory _symbol);

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    /// 3986. The URI may point to a JSON file that conforms to the "ERC721
    /// Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) external view returns (string memory);
}

/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x780e9d63.
interface IERC721Enumerable is IERC721 {
    /// @notice Count NFTs tracked by this contract
    /// @return A count of valid NFTs tracked by this contract, where each one of
    /// them has an assigned and queryable owner not equal to the zero address
    function totalSupply() external view returns (uint256);

    /// @notice Enumerate valid NFTs
    /// @dev Throws if `_index` >= `totalSupply()`.
    /// @param _index A counter less than `totalSupply()`
    /// @return The token identifier for the `_index`th NFT,
    /// (sort order not specified)
    function tokenByIndex(uint256 _index) external view returns (uint256);

    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    /// `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner An address where we are interested in NFTs owned by them
    /// @param _index A counter less than `balanceOf(_owner)`
    /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
    /// (sort order not specified)
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}

File 4 of 7 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @dev This includes the optional name, symbol, and decimals metadata.
interface IERC20 {
    /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`
    /// is the new allowance.
    event Approval(address indexed owner, address indexed spender, uint256 value);

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

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

    /// @notice Moves `amount` tokens from the caller's account to `to`.
    function transfer(address to, uint256 amount) external returns (bool);

    /// @notice Returns the remaining number of tokens that `spender` is allowed
    /// to spend on behalf of `owner`
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
    /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    function approve(address spender, uint256 amount) external returns (bool);

    /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.
    /// `amount` is then deducted from the caller's allowance.
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /// @notice Returns the name of the token.
    function name() external view returns (string memory);

    /// @notice Returns the symbol of the token.
    function symbol() external view returns (string memory);

    /// @notice Returns the decimals places of the token.
    function decimals() external view returns (uint8);
}

File 5 of 7 : IERC1155.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

import "./IERC165.sol";

/// @title ERC-1155 Multi Token Standard
/// @dev See https://eips.ethereum.org/EIPS/eip-1155
/// Note: The ERC-165 identifier for this interface is 0xd9b67a26.
interface IERC1155 is IERC165 {
    /// @dev
    /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard).
    /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender).
    /// - The `_from` argument MUST be the address of the holder whose balance is decreased.
    /// - The `_to` argument MUST be the address of the recipient whose balance is increased.
    /// - The `_id` argument MUST be the token type being transferred.
    /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.
    /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).
    /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
    event TransferSingle(
        address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value
    );

    /// @dev
    /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard).
    /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender).
    /// - The `_from` argument MUST be the address of the holder whose balance is decreased.
    /// - The `_to` argument MUST be the address of the recipient whose balance is increased.
    /// - The `_ids` argument MUST be the list of tokens being transferred.
    /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by.
    /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).
    /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
    event TransferBatch(
        address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values
    );

    /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled).
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986.
    /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema".
    event URI(string _value, uint256 indexed _id);

    /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call).
    /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
    /// - MUST revert if `_to` is the zero address.
    /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent.
    /// - MUST revert on any other error.
    /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
    /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
    /// @param _from Source address
    /// @param _to Target address
    /// @param _id ID of the token type
    /// @param _value Transfer amount
    /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
    function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;

    /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call).
    /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
    /// - MUST revert if `_to` is the zero address.
    /// - MUST revert if length of `_ids` is not the same as length of `_values`.
    /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
    /// - MUST revert on any other error.
    /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard).
    /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
    /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
    /// @param _from Source address
    /// @param _to Target address
    /// @param _ids IDs of each token type (order and length must match _values array)
    /// @param _values Transfer amounts per token type (order and length must match _ids array)
    /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
    function safeBatchTransferFrom(
        address _from,
        address _to,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data
    ) external;

    /// @notice Get the balance of an account's tokens.
    /// @param _owner The address of the token holder
    /// @param _id ID of the token
    /// @return The _owner's balance of the token type requested
    function balanceOf(address _owner, uint256 _id) external view returns (uint256);

    /// @notice Get the balance of multiple account/token pairs
    /// @param _owners The addresses of the token holders
    /// @param _ids ID of the tokens
    /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair)
    function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids)
        external
        view
        returns (uint256[] memory);

    /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
    /// @dev MUST emit the ApprovalForAll event on success.
    /// @param _operator Address to add to the set of authorized operators
    /// @param _approved True if the operator is approved, false to revoke approval
    function setApprovalForAll(address _operator, bool _approved) external;

    /// @notice Queries the approval status of an operator for a given owner.
    /// @param _owner The owner of the tokens
    /// @param _operator Address of authorized operator
    /// @return True if the operator is approved, false if not
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

File 6 of 7 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev Cannot double-initialize.
    error AlreadyInitialized();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by:
    /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    bytes32 internal constant _OWNER_SLOT =
        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                if sload(ownerSlot) {
                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
                    revert(0x1c, 0x04)
                }
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(_OWNER_SLOT, newOwner)
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, newOwner)
            }
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(_OWNER_SLOT))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(_OWNER_SLOT)
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 7 of 7 : IERC165.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

interface IERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    /// uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    /// `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "solady/=lib/solady/src/",
    "soladytest/=lib/solady/test/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ArrayLengthMismatch","type":"error"},{"inputs":[],"name":"CallerNotFulfiller","type":"error"},{"inputs":[],"name":"FailedToPayAutosniper","type":"error"},{"inputs":[],"name":"FailedToPayValidator","type":"error"},{"inputs":[],"name":"FailedToWithdraw","type":"error"},{"inputs":[],"name":"FulfillerCannotHaveBalance","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"MigrationNotEnabled","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"OrderFailed","type":"error"},{"inputs":[],"name":"SniperIsPaused","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sniper","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sniper","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sniper","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositSelf","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"migrateBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextContractVersionAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fulfiller","type":"address"}],"name":"setFulfillerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_destination","type":"address"}],"name":"setMigrationAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isPaused","type":"bool"}],"name":"setUserIsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contractAddresses","type":"address[]"},{"internalType":"bytes[]","name":"calls","type":"bytes[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"address","name":"sniper","type":"address"},{"internalType":"uint256","name":"validatorTip","type":"uint256"},{"internalType":"uint256","name":"fulfillerTip","type":"uint256"}],"name":"snipe_2572234525","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sniper","type":"address"}],"name":"sniperBalance","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sniperStates","outputs":[{"internalType":"uint128","name":"ethBalance","type":"uint128"},{"internalType":"bool","name":"isPaused","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600080546001600160a01b031916737d79bd0e4b3dc90665a3ed30aa6c6c06c89d224e17905534801561003657600080fd5b5061004032610045565b610081565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b611736806100906000396000f3fe6080604052600436106101a05760003560e01c80635d799f87116100ec578063e339d9f11161008a578063f23a6e6111610064578063f23a6e6114610527578063f2fde38b14610554578063f340fa0114610567578063fee81cf41461057a57600080fd5b8063e339d9f114610492578063f04e283e146104e9578063f0b9e5ba146104fc57600080fd5b8063b00b1e50116100c6578063b00b1e5014610403578063b7ce33a214610423578063bc197c8114610443578063c9c50e231461047257600080fd5b80635d799f87146103ae578063715018a6146103ce5780638da5cb5b146103d657600080fd5b8063270a6231116101595780634732a7dc116101335780634732a7dc1461035e5780634c412aa31461037e57806354d1f13d1461039e57806357323648146103a657600080fd5b8063270a6231146103085780632e1a7d4d1461031d57806335b944bf1461033d57600080fd5b806301ffc9a7146101ac578063115b7940146101f2578063150b7a021461023a5780631a21241c1461027f57806325692962146102e057806326e2dca2146102e857600080fd5b366101a757005b600080fd5b3480156101b857600080fd5b506101dd6101c73660046110ec565b6001600160e01b0319166301ffc9a760e01b1490565b60405190151581526020015b60405180910390f35b3480156101fe57600080fd5b5061023861020d36600461112b565b3360009081526002602052604090208054911515600160801b0260ff60801b19909216919091179055565b005b34801561024657600080fd5b506102666102553660046111ad565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016101e9565b34801561028b57600080fd5b506102c161029a36600461121c565b6002602052600090815260409020546001600160801b03811690600160801b900460ff1682565b604080516001600160801b0390931683529015156020830152016101e9565b6102386105bb565b3480156102f457600080fd5b5061023861030336600461127c565b61060b565b34801561031457600080fd5b506102386106c3565b34801561032957600080fd5b506102386103383660046112e1565b6107d3565b34801561034957600080fd5b506001546101dd90600160a01b900460ff1681565b34801561036a57600080fd5b5061023861037936600461121c565b610909565b34801561038a57600080fd5b5061023861039936600461121c565b61093a565b610238610964565b6102386109a0565b3480156103ba57600080fd5b506102386103c93660046112fa565b6109ab565b610238610a9c565b3480156103e257600080fd5b50638b78c6d819545b6040516001600160a01b0390911681526020016101e9565b34801561040f57600080fd5b5061023861041e36600461132d565b610aae565b34801561042f57600080fd5b5061023861043e3660046113ea565b610ea3565b34801561044f57600080fd5b5061026661045e36600461147a565b63bc197c8160e01b98975050505050505050565b34801561047e57600080fd5b506001546103eb906001600160a01b031681565b34801561049e57600080fd5b506104d16104ad36600461121c565b6001600160a01b03166000908152600260205260409020546001600160801b031690565b6040516001600160801b0390911681526020016101e9565b6102386104f736600461121c565b610f8c565b34801561050857600080fd5b50610266610517366004611535565b63785cf2dd60e11b949350505050565b34801561053357600080fd5b5061026661054236600461158f565b63f23a6e6160e01b9695505050505050565b61023861056236600461121c565b610fcc565b61023861057536600461121c565b610ff3565b34801561058657600080fd5b506105ad61059536600461121c565b63389a75e1600c908152600091909152602090205490565b6040519081526020016101e9565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610613611093565b60005b828110156106bc57846001600160a01b03166323b872dd308487878681811061064157610641611607565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561069857600080fd5b505af11580156106ac573d6000803e3d6000fd5b5050600190920191506106169050565b5050505050565b600154600160a01b900460ff166106ed5760405163f6017bbd60e01b815260040160405180910390fd5b33600081815260026020908152604080832080546001600160801b03198116909155600154825160248082019790975283518082039097018752604401835292850180516001600160e01b031663f340fa0160e01b17905290516001600160801b03909116936001600160a01b0390921691849161076b919061161d565b60006040518083038185875af1925050503d80600081146107a8576040519150601f19603f3d011682016040523d82523d6000602084013e6107ad565b606091505b50509050806107cf57604051632684a07960e01b815260040160405180910390fd5b5050565b6000546001600160a01b031632036107fe57604051630d45e68960e21b815260040160405180910390fd5b336000908152600260205260409020546001600160801b031681111561083757604051631e9acf1760e31b815260040160405180910390fd5b3360008181526002602052604080822080546001600160801b03808216879003166001600160801b03199091161790555190919083908381818185875af1925050503d80600081146108a5576040519150601f19603f3d011682016040523d82523d6000602084013e6108aa565b606091505b50509050806108cc57604051632684a07960e01b815260040160405180910390fd5b60408051338152602081018490527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65910160405180910390a15050565b610911611093565b600180546001600160a01b039092166001600160a81b031990921691909117600160a01b179055565b610942611093565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b6109a933610ff3565b565b6109b3611093565b6040516370a0823160e01b815230600482015282906001600160a01b0382169063a9059cbb90849083906370a0823190602401602060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a27919061164c565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a969190611665565b50505050565b610aa4611093565b6109a960006110ae565b6000546001600160a01b03163314610ad9576040516319caaa0b60e01b815260040160405180910390fd5b878614610af95760405163512509d360e11b815260040160405180910390fd5b858414610b195760405163512509d360e11b815260040160405180910390fd5b6001600160a01b038316600090815260026020526040902054600160801b900460ff1615610b5a57604051634e2916b760e01b815260040160405180910390fd5b4760005b89811015610c505760008b8b83818110610b7a57610b7a611607565b9050602002016020810190610b8f919061121c565b6001600160a01b0316888884818110610baa57610baa611607565b905060200201358b8b85818110610bc357610bc3611607565b9050602002810190610bd59190611682565b604051610be39291906116c9565b60006040518083038185875af1925050503d8060008114610c20576040519150601f19603f3d011682016040523d82523d6000602084013e610c25565b606091505b5050905080610c475760405163e8d529f960e01b815260040160405180910390fd5b50600101610b5e565b50604051600090419085908381818185875af1925050503d8060008114610c93576040519150601f19603f3d011682016040523d82523d6000602084013e610c98565b606091505b5050905080610cba57604051632d66518f60e01b815260040160405180910390fd5b600080546040516001600160a01b039091169085908381818185875af1925050503d8060008114610d07576040519150601f19603f3d011682016040523d82523d6000602084013e610d0c565b606091505b5050905080610d2e576040516305676c7160e41b815260040160405180910390fd5b4783811015610e04576000610d4382866116d9565b6001600160a01b0389166000908152600260205260409020549091506001600160801b0380831691161015610d8b57604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b03881660008181526002602090815260409182902080546001600160801b031981166001600160801b0391821687900382161790915582519384528416908301527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65910160405180910390a150610e94565b83811115610e94576001600160a01b038716600090815260026020526040902080546001600160801b0380821687850301166001600160801b03199091161790557fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c87610e7186846116d9565b604080516001600160a01b03909316835260208301919091520160405180910390a15b50505050505050505050505050565b610eab611093565b60005b84811015610f8357866001600160a01b031663f242432a3084898986818110610ed957610ed9611607565b90506020020135888887818110610ef257610ef2611607565b6040516001600160e01b031960e089901b1681526001600160a01b03968716600482015295909416602486015250604484019190915260209091020135606482015260a06084820152600060a482015260c401600060405180830381600087803b158015610f5f57600080fd5b505af1158015610f73573d6000803e3d6000fd5b505060019092019150610eae9050565b50505050505050565b610f94611093565b63389a75e1600c52806000526020600c208054421115610fbc57636f5e88186000526004601cfd5b60009055610fc9816110ae565b50565b610fd4611093565b8060601b610fea57637448fbae6000526004601cfd5b610fc9816110ae565b6000546001600160a01b0316320361101e57604051630d45e68960e21b815260040160405180910390fd5b6001600160a01b03811660008181526002602090815260409182902080546001600160801b03198116346001600160801b039283168101909216179091558251938452908301527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c910160405180910390a150565b638b78c6d8195433146109a9576382b429006000526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b6000602082840312156110fe57600080fd5b81356001600160e01b03198116811461111657600080fd5b9392505050565b8015158114610fc957600080fd5b60006020828403121561113d57600080fd5b81356111168161111d565b80356001600160a01b038116811461115f57600080fd5b919050565b60008083601f84011261117657600080fd5b50813567ffffffffffffffff81111561118e57600080fd5b6020830191508360208285010111156111a657600080fd5b9250929050565b6000806000806000608086880312156111c557600080fd5b6111ce86611148565b94506111dc60208701611148565b935060408601359250606086013567ffffffffffffffff8111156111ff57600080fd5b61120b88828901611164565b969995985093965092949392505050565b60006020828403121561122e57600080fd5b61111682611148565b60008083601f84011261124957600080fd5b50813567ffffffffffffffff81111561126157600080fd5b6020830191508360208260051b85010111156111a657600080fd5b6000806000806060858703121561129257600080fd5b61129b85611148565b9350602085013567ffffffffffffffff8111156112b757600080fd5b6112c387828801611237565b90945092506112d6905060408601611148565b905092959194509250565b6000602082840312156112f357600080fd5b5035919050565b6000806040838503121561130d57600080fd5b61131683611148565b915061132460208401611148565b90509250929050565b600080600080600080600080600060c08a8c03121561134b57600080fd5b893567ffffffffffffffff8082111561136357600080fd5b61136f8d838e01611237565b909b50995060208c013591508082111561138857600080fd5b6113948d838e01611237565b909950975060408c01359150808211156113ad57600080fd5b506113ba8c828d01611237565b90965094506113cd905060608b01611148565b925060808a0135915060a08a013590509295985092959850929598565b6000806000806000806080878903121561140357600080fd5b61140c87611148565b9550602087013567ffffffffffffffff8082111561142957600080fd5b6114358a838b01611237565b9097509550604089013591508082111561144e57600080fd5b5061145b89828a01611237565b909450925061146e905060608801611148565b90509295509295509295565b60008060008060008060008060a0898b03121561149657600080fd5b61149f89611148565b97506114ad60208a01611148565b9650604089013567ffffffffffffffff808211156114ca57600080fd5b6114d68c838d01611237565b909850965060608b01359150808211156114ef57600080fd5b6114fb8c838d01611237565b909650945060808b013591508082111561151457600080fd5b506115218b828c01611164565b999c989b5096995094979396929594505050565b6000806000806060858703121561154b57600080fd5b61155485611148565b935060208501359250604085013567ffffffffffffffff81111561157757600080fd5b61158387828801611164565b95989497509550505050565b60008060008060008060a087890312156115a857600080fd5b6115b187611148565b95506115bf60208801611148565b94506040870135935060608701359250608087013567ffffffffffffffff8111156115e957600080fd5b6115f589828a01611164565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6000825160005b8181101561163e5760208186018101518583015201611624565b506000920191825250919050565b60006020828403121561165e57600080fd5b5051919050565b60006020828403121561167757600080fd5b81516111168161111d565b6000808335601e1984360301811261169957600080fd5b83018035915067ffffffffffffffff8211156116b457600080fd5b6020019150368190038213156111a657600080fd5b8183823760009101908152919050565b818103818111156116fa57634e487b7160e01b600052601160045260246000fd5b9291505056fea264697066735822122099f26400b19fe201093c3be496bdd2867f8be30cb5161aaec0711f3c99a6c1b064736f6c63430008180033

Deployed Bytecode

0x6080604052600436106101a05760003560e01c80635d799f87116100ec578063e339d9f11161008a578063f23a6e6111610064578063f23a6e6114610527578063f2fde38b14610554578063f340fa0114610567578063fee81cf41461057a57600080fd5b8063e339d9f114610492578063f04e283e146104e9578063f0b9e5ba146104fc57600080fd5b8063b00b1e50116100c6578063b00b1e5014610403578063b7ce33a214610423578063bc197c8114610443578063c9c50e231461047257600080fd5b80635d799f87146103ae578063715018a6146103ce5780638da5cb5b146103d657600080fd5b8063270a6231116101595780634732a7dc116101335780634732a7dc1461035e5780634c412aa31461037e57806354d1f13d1461039e57806357323648146103a657600080fd5b8063270a6231146103085780632e1a7d4d1461031d57806335b944bf1461033d57600080fd5b806301ffc9a7146101ac578063115b7940146101f2578063150b7a021461023a5780631a21241c1461027f57806325692962146102e057806326e2dca2146102e857600080fd5b366101a757005b600080fd5b3480156101b857600080fd5b506101dd6101c73660046110ec565b6001600160e01b0319166301ffc9a760e01b1490565b60405190151581526020015b60405180910390f35b3480156101fe57600080fd5b5061023861020d36600461112b565b3360009081526002602052604090208054911515600160801b0260ff60801b19909216919091179055565b005b34801561024657600080fd5b506102666102553660046111ad565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016101e9565b34801561028b57600080fd5b506102c161029a36600461121c565b6002602052600090815260409020546001600160801b03811690600160801b900460ff1682565b604080516001600160801b0390931683529015156020830152016101e9565b6102386105bb565b3480156102f457600080fd5b5061023861030336600461127c565b61060b565b34801561031457600080fd5b506102386106c3565b34801561032957600080fd5b506102386103383660046112e1565b6107d3565b34801561034957600080fd5b506001546101dd90600160a01b900460ff1681565b34801561036a57600080fd5b5061023861037936600461121c565b610909565b34801561038a57600080fd5b5061023861039936600461121c565b61093a565b610238610964565b6102386109a0565b3480156103ba57600080fd5b506102386103c93660046112fa565b6109ab565b610238610a9c565b3480156103e257600080fd5b50638b78c6d819545b6040516001600160a01b0390911681526020016101e9565b34801561040f57600080fd5b5061023861041e36600461132d565b610aae565b34801561042f57600080fd5b5061023861043e3660046113ea565b610ea3565b34801561044f57600080fd5b5061026661045e36600461147a565b63bc197c8160e01b98975050505050505050565b34801561047e57600080fd5b506001546103eb906001600160a01b031681565b34801561049e57600080fd5b506104d16104ad36600461121c565b6001600160a01b03166000908152600260205260409020546001600160801b031690565b6040516001600160801b0390911681526020016101e9565b6102386104f736600461121c565b610f8c565b34801561050857600080fd5b50610266610517366004611535565b63785cf2dd60e11b949350505050565b34801561053357600080fd5b5061026661054236600461158f565b63f23a6e6160e01b9695505050505050565b61023861056236600461121c565b610fcc565b61023861057536600461121c565b610ff3565b34801561058657600080fd5b506105ad61059536600461121c565b63389a75e1600c908152600091909152602090205490565b6040519081526020016101e9565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610613611093565b60005b828110156106bc57846001600160a01b03166323b872dd308487878681811061064157610641611607565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561069857600080fd5b505af11580156106ac573d6000803e3d6000fd5b5050600190920191506106169050565b5050505050565b600154600160a01b900460ff166106ed5760405163f6017bbd60e01b815260040160405180910390fd5b33600081815260026020908152604080832080546001600160801b03198116909155600154825160248082019790975283518082039097018752604401835292850180516001600160e01b031663f340fa0160e01b17905290516001600160801b03909116936001600160a01b0390921691849161076b919061161d565b60006040518083038185875af1925050503d80600081146107a8576040519150601f19603f3d011682016040523d82523d6000602084013e6107ad565b606091505b50509050806107cf57604051632684a07960e01b815260040160405180910390fd5b5050565b6000546001600160a01b031632036107fe57604051630d45e68960e21b815260040160405180910390fd5b336000908152600260205260409020546001600160801b031681111561083757604051631e9acf1760e31b815260040160405180910390fd5b3360008181526002602052604080822080546001600160801b03808216879003166001600160801b03199091161790555190919083908381818185875af1925050503d80600081146108a5576040519150601f19603f3d011682016040523d82523d6000602084013e6108aa565b606091505b50509050806108cc57604051632684a07960e01b815260040160405180910390fd5b60408051338152602081018490527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65910160405180910390a15050565b610911611093565b600180546001600160a01b039092166001600160a81b031990921691909117600160a01b179055565b610942611093565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b6109a933610ff3565b565b6109b3611093565b6040516370a0823160e01b815230600482015282906001600160a01b0382169063a9059cbb90849083906370a0823190602401602060405180830381865afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a27919061164c565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a969190611665565b50505050565b610aa4611093565b6109a960006110ae565b6000546001600160a01b03163314610ad9576040516319caaa0b60e01b815260040160405180910390fd5b878614610af95760405163512509d360e11b815260040160405180910390fd5b858414610b195760405163512509d360e11b815260040160405180910390fd5b6001600160a01b038316600090815260026020526040902054600160801b900460ff1615610b5a57604051634e2916b760e01b815260040160405180910390fd5b4760005b89811015610c505760008b8b83818110610b7a57610b7a611607565b9050602002016020810190610b8f919061121c565b6001600160a01b0316888884818110610baa57610baa611607565b905060200201358b8b85818110610bc357610bc3611607565b9050602002810190610bd59190611682565b604051610be39291906116c9565b60006040518083038185875af1925050503d8060008114610c20576040519150601f19603f3d011682016040523d82523d6000602084013e610c25565b606091505b5050905080610c475760405163e8d529f960e01b815260040160405180910390fd5b50600101610b5e565b50604051600090419085908381818185875af1925050503d8060008114610c93576040519150601f19603f3d011682016040523d82523d6000602084013e610c98565b606091505b5050905080610cba57604051632d66518f60e01b815260040160405180910390fd5b600080546040516001600160a01b039091169085908381818185875af1925050503d8060008114610d07576040519150601f19603f3d011682016040523d82523d6000602084013e610d0c565b606091505b5050905080610d2e576040516305676c7160e41b815260040160405180910390fd5b4783811015610e04576000610d4382866116d9565b6001600160a01b0389166000908152600260205260409020549091506001600160801b0380831691161015610d8b57604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b03881660008181526002602090815260409182902080546001600160801b031981166001600160801b0391821687900382161790915582519384528416908301527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65910160405180910390a150610e94565b83811115610e94576001600160a01b038716600090815260026020526040902080546001600160801b0380821687850301166001600160801b03199091161790557fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c87610e7186846116d9565b604080516001600160a01b03909316835260208301919091520160405180910390a15b50505050505050505050505050565b610eab611093565b60005b84811015610f8357866001600160a01b031663f242432a3084898986818110610ed957610ed9611607565b90506020020135888887818110610ef257610ef2611607565b6040516001600160e01b031960e089901b1681526001600160a01b03968716600482015295909416602486015250604484019190915260209091020135606482015260a06084820152600060a482015260c401600060405180830381600087803b158015610f5f57600080fd5b505af1158015610f73573d6000803e3d6000fd5b505060019092019150610eae9050565b50505050505050565b610f94611093565b63389a75e1600c52806000526020600c208054421115610fbc57636f5e88186000526004601cfd5b60009055610fc9816110ae565b50565b610fd4611093565b8060601b610fea57637448fbae6000526004601cfd5b610fc9816110ae565b6000546001600160a01b0316320361101e57604051630d45e68960e21b815260040160405180910390fd5b6001600160a01b03811660008181526002602090815260409182902080546001600160801b03198116346001600160801b039283168101909216179091558251938452908301527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c910160405180910390a150565b638b78c6d8195433146109a9576382b429006000526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b6000602082840312156110fe57600080fd5b81356001600160e01b03198116811461111657600080fd5b9392505050565b8015158114610fc957600080fd5b60006020828403121561113d57600080fd5b81356111168161111d565b80356001600160a01b038116811461115f57600080fd5b919050565b60008083601f84011261117657600080fd5b50813567ffffffffffffffff81111561118e57600080fd5b6020830191508360208285010111156111a657600080fd5b9250929050565b6000806000806000608086880312156111c557600080fd5b6111ce86611148565b94506111dc60208701611148565b935060408601359250606086013567ffffffffffffffff8111156111ff57600080fd5b61120b88828901611164565b969995985093965092949392505050565b60006020828403121561122e57600080fd5b61111682611148565b60008083601f84011261124957600080fd5b50813567ffffffffffffffff81111561126157600080fd5b6020830191508360208260051b85010111156111a657600080fd5b6000806000806060858703121561129257600080fd5b61129b85611148565b9350602085013567ffffffffffffffff8111156112b757600080fd5b6112c387828801611237565b90945092506112d6905060408601611148565b905092959194509250565b6000602082840312156112f357600080fd5b5035919050565b6000806040838503121561130d57600080fd5b61131683611148565b915061132460208401611148565b90509250929050565b600080600080600080600080600060c08a8c03121561134b57600080fd5b893567ffffffffffffffff8082111561136357600080fd5b61136f8d838e01611237565b909b50995060208c013591508082111561138857600080fd5b6113948d838e01611237565b909950975060408c01359150808211156113ad57600080fd5b506113ba8c828d01611237565b90965094506113cd905060608b01611148565b925060808a0135915060a08a013590509295985092959850929598565b6000806000806000806080878903121561140357600080fd5b61140c87611148565b9550602087013567ffffffffffffffff8082111561142957600080fd5b6114358a838b01611237565b9097509550604089013591508082111561144e57600080fd5b5061145b89828a01611237565b909450925061146e905060608801611148565b90509295509295509295565b60008060008060008060008060a0898b03121561149657600080fd5b61149f89611148565b97506114ad60208a01611148565b9650604089013567ffffffffffffffff808211156114ca57600080fd5b6114d68c838d01611237565b909850965060608b01359150808211156114ef57600080fd5b6114fb8c838d01611237565b909650945060808b013591508082111561151457600080fd5b506115218b828c01611164565b999c989b5096995094979396929594505050565b6000806000806060858703121561154b57600080fd5b61155485611148565b935060208501359250604085013567ffffffffffffffff81111561157757600080fd5b61158387828801611164565b95989497509550505050565b60008060008060008060a087890312156115a857600080fd5b6115b187611148565b95506115bf60208801611148565b94506040870135935060608701359250608087013567ffffffffffffffff8111156115e957600080fd5b6115f589828a01611164565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6000825160005b8181101561163e5760208186018101518583015201611624565b506000920191825250919050565b60006020828403121561165e57600080fd5b5051919050565b60006020828403121561167757600080fd5b81516111168161111d565b6000808335601e1984360301811261169957600080fd5b83018035915067ffffffffffffffff8211156116b457600080fd5b6020019150368190038213156111a657600080fd5b8183823760009101908152919050565b818103818111156116fa57634e487b7160e01b600052601160045260246000fd5b9291505056fea264697066735822122099f26400b19fe201093c3be496bdd2867f8be30cb5161aaec0711f3c99a6c1b064736f6c63430008180033

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.