ETH Price: $2,430.69 (-9.58%)

Contract

0x06f1afa00990A69cA03F82D4c1A3a64A45F45fCb

Overview

ETH Balance

2.398415952500000078 ETH

ETH Value

$5,829.79 (@ $2,430.69/ETH)

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Sell Passes3885681902025-10-11 23:56:16112 days ago1760226976IN
SankoTV: SankoTV Passes
0 ETH0.000000610.01
Sell Passes3885681832025-10-11 23:56:14112 days ago1760226974IN
SankoTV: SankoTV Passes
0 ETH0.000000720.01
Sell Passes3874935982025-10-08 21:27:06115 days ago1759958826IN
SankoTV: SankoTV Passes
0 ETH0.000000870.014617
Sell Passes3874935912025-10-08 21:27:04115 days ago1759958824IN
SankoTV: SankoTV Passes
0 ETH0.000001090.014702
Sell Passes3874935842025-10-08 21:27:02115 days ago1759958822IN
SankoTV: SankoTV Passes
0 ETH0.000001080.014658
Sell Passes3874935772025-10-08 21:27:01115 days ago1759958821IN
SankoTV: SankoTV Passes
0 ETH0.000001050.014726
Sell Passes3811762302025-09-20 15:27:57133 days ago1758382077IN
SankoTV: SankoTV Passes
0 ETH0.000000590.01
Sell Passes3811762162025-09-20 15:27:54133 days ago1758382074IN
SankoTV: SankoTV Passes
0 ETH0.000000760.01
Sell Passes3811760822025-09-20 15:27:20133 days ago1758382040IN
SankoTV: SankoTV Passes
0 ETH0.000000780.01
Sell Passes3758948242025-09-05 8:47:52148 days ago1757062072IN
SankoTV: SankoTV Passes
0 ETH0.000000610.01
Sell Passes3758948172025-09-05 8:47:50148 days ago1757062070IN
SankoTV: SankoTV Passes
0 ETH0.000000770.01
Sell Passes3733920802025-08-29 3:11:39156 days ago1756437099IN
SankoTV: SankoTV Passes
0 ETH0.000000720.01
Sell Passes3716403702025-08-24 1:45:08161 days ago1755999908IN
SankoTV: SankoTV Passes
0 ETH0.000000770.01
Sell Passes3390766902025-05-21 17:52:00255 days ago1747849920IN
SankoTV: SankoTV Passes
0 ETH0.000024690.382403
Sell Passes3390766742025-05-21 17:51:56255 days ago1747849916IN
SankoTV: SankoTV Passes
0 ETH0.000013150.38946
Sell Passes3390766392025-05-21 17:51:47255 days ago1747849907IN
SankoTV: SankoTV Passes
0 ETH0.000025580.397399
Sell Passes3390766222025-05-21 17:51:43255 days ago1747849903IN
SankoTV: SankoTV Passes
0 ETH0.00003070.403845
Sell Passes3363258622025-05-13 17:37:02263 days ago1747157822IN
SankoTV: SankoTV Passes
0 ETH0.000005610.071642
Sell Passes3363255302025-05-13 17:35:38263 days ago1747157738IN
SankoTV: SankoTV Passes
0 ETH0.000006180.076975
Sell Passes3144122462025-03-11 1:48:37327 days ago1741657717IN
SankoTV: SankoTV Passes
0 ETH0.000006020.067315
Sell Passes3144122282025-03-11 1:48:32327 days ago1741657712IN
SankoTV: SankoTV Passes
0 ETH0.000006090.068224
Sell Passes3137970122025-03-09 6:58:03328 days ago1741503483IN
SankoTV: SankoTV Passes
0 ETH0.000000790.01
Sell Passes3085408892025-02-21 23:54:21344 days ago1740182061IN
SankoTV: SankoTV Passes
0 ETH0.00000130.01
Sell Passes3025996262025-02-04 16:11:04361 days ago1738685464IN
SankoTV: SankoTV Passes
0 ETH0.000001980.01
Sell Passes3025995822025-02-04 16:10:53361 days ago1738685453IN
SankoTV: SankoTV Passes
0 ETH0.000001980.01
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
3885681832025-10-11 23:56:14112 days ago1760226974
SankoTV: SankoTV Passes
0.00561937 ETH
3885681832025-10-11 23:56:14112 days ago1760226974
SankoTV: SankoTV Passes
0.00000562 ETH
3874935912025-10-08 21:27:04115 days ago1759958824
SankoTV: SankoTV Passes
0.00006243 ETH
3874935912025-10-08 21:27:04115 days ago1759958824
SankoTV: SankoTV Passes
0.00000006 ETH
3874935842025-10-08 21:27:02115 days ago1759958822
SankoTV: SankoTV Passes
0.00024975 ETH
3874935842025-10-08 21:27:02115 days ago1759958822
SankoTV: SankoTV Passes
0.00000025 ETH
3874935772025-10-08 21:27:01115 days ago1759958821
SankoTV: SankoTV Passes
0.00056193 ETH
3874935772025-10-08 21:27:01115 days ago1759958821
SankoTV: SankoTV Passes
0.00000056 ETH
3811762162025-09-20 15:27:54133 days ago1758382074
SankoTV: SankoTV Passes
0.00056193 ETH
3811762162025-09-20 15:27:54133 days ago1758382074
SankoTV: SankoTV Passes
0.00000056 ETH
3811760822025-09-20 15:27:20133 days ago1758382040
SankoTV: SankoTV Passes
0.00187312 ETH
3811760822025-09-20 15:27:20133 days ago1758382040
SankoTV: SankoTV Passes
0.00000187 ETH
3758948172025-09-05 8:47:50148 days ago1757062070
SankoTV: SankoTV Passes
0.00031218 ETH
3758948172025-09-05 8:47:50148 days ago1757062070
SankoTV: SankoTV Passes
0.00000031 ETH
3733920802025-08-29 3:11:39156 days ago1756437099
SankoTV: SankoTV Passes
0.00024975 ETH
3733920802025-08-29 3:11:39156 days ago1756437099
SankoTV: SankoTV Passes
0.00000025 ETH
3716403702025-08-24 1:45:08161 days ago1755999908
SankoTV: SankoTV Passes
0.00006243 ETH
3716403702025-08-24 1:45:08161 days ago1755999908
SankoTV: SankoTV Passes
0.00000006 ETH
3390766222025-05-21 17:51:43255 days ago1747849903
SankoTV: SankoTV Passes
0.00024975 ETH
3390766222025-05-21 17:51:43255 days ago1747849903
SankoTV: SankoTV Passes
0.00000025 ETH
3363258622025-05-13 17:37:02263 days ago1747157822
SankoTV: SankoTV Passes
0.00006243 ETH
3363258622025-05-13 17:37:02263 days ago1747157822
SankoTV: SankoTV Passes
0.00000006 ETH
3363255302025-05-13 17:35:38263 days ago1747157738
SankoTV: SankoTV Passes
0.00024975 ETH
3363255302025-05-13 17:35:38263 days ago1747157738
SankoTV: SankoTV Passes
0.00000025 ETH
3144122462025-03-11 1:48:37327 days ago1741657717
SankoTV: SankoTV Passes
0.00006243 ETH
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SankoTVPasses

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

import {Ownable} from "@solady/auth/Ownable.sol";
import {IFeeConverter} from "./interfaces/IFeeConverter.sol";

error StreamerMustBuyFirstPass();
error CannotSellLastPass();
error InsufficientPayment();
error InsufficientPasses();
error FundsTransferFailed();
error NotLiveYet();
error NotUnlockedYet();
error UnlocksTooSoon();

contract SankoTVPasses is Ownable {
    struct PackedArgs {
        uint96 amount;
        address addy;
    }

    struct Fees {
        uint256 streamerFee;
        uint256 ethFee;
        uint256 dmtFee;
        uint256 referralFee;
    }

    struct PassesBalance {
        uint96 unlocked;
        uint96 locked;
        uint64 unlocksAt;
    }

    address public protocolFeeDestination;
    IFeeConverter public feeConverter;
    uint256 public ethFeePercent;
    uint256 public dmtFeePercent;
    uint256 public streamerFeePercent;
    uint256 public referralFeePercent;

    bool public live;

    event Trade(
        address indexed trader,
        address indexed streamer,
        address indexed referrer,
        bool isBuy,
        uint256 passAmount,
        uint256 ethAmount,
        uint256 protocolEthAmount,
        uint256 streamerEthAmount,
        uint256 referralEthAmount,
        uint256 supply
    );

    event Locked(
        address indexed trader,
        address indexed streamer,
        uint256 passAmount,
        uint256 unlocksAt
    );

    event Unlocked(
        address indexed trader, address indexed streamer, uint256 passAmount
    );

    mapping(address streamer => mapping(address fan => PassesBalance balance))
        public passesBalance;

    mapping(address streamer => uint256 supply) public passesSupply;

    modifier whenLive() {
        if (!live) {
            revert NotLiveYet();
        }
        _;
    }

    constructor() {
        _initializeOwner(msg.sender);
    }

    function setLive() external onlyOwner {
        live = true;
    }

    function setFeeDestination(address _feeDestination) external onlyOwner {
        protocolFeeDestination = _feeDestination;
    }

    function setEthFeePercent(uint256 _feePercent) external onlyOwner {
        ethFeePercent = _feePercent;
    }

    function setDmtFeePercent(uint256 _feePercent) external onlyOwner {
        dmtFeePercent = _feePercent;
    }

    function setFeeConverter(IFeeConverter _feeConverter) external onlyOwner {
        feeConverter = _feeConverter;
    }

    function setStreamerFeePercent(uint256 _feePercent) external onlyOwner {
        streamerFeePercent = _feePercent;
    }

    function setReferralFeePercent(uint256 _feePercent) external onlyOwner {
        referralFeePercent = _feePercent;
    }

    function buyPasses(address streamer, bytes32 packedArgs)
        external
        payable
        whenLive
    {
        PackedArgs memory args = unpackArgs(packedArgs);
        uint96 amount = args.amount;
        address referrer = args.addy;

        uint256 supply = passesSupply[streamer];
        if (supply == 0 && msg.sender != streamer) {
            revert StreamerMustBuyFirstPass();
        }

        uint256 price = getPrice(supply, amount);
        Fees memory fees = getFees(price, referrer);

        uint256 totalCost = price + fees.ethFee + fees.dmtFee + fees.streamerFee
            + fees.referralFee;

        if (msg.value < totalCost) {
            revert InsufficientPayment();
        }

        passesBalance[streamer][msg.sender].unlocked += amount;
        passesSupply[streamer] = supply + amount;
        emit Trade(
            msg.sender,
            streamer,
            referrer,
            true,
            amount,
            price,
            fees.ethFee + fees.dmtFee,
            fees.streamerFee,
            fees.referralFee,
            supply + amount
        );

        (bool streamerSend,) = streamer.call{value: fees.streamerFee}("");
        (bool protocolSend,) =
            protocolFeeDestination.call{value: fees.ethFee}("");

        bool feeSend = true;
        if (fees.dmtFee > 0) {
            feeSend = feeConverter.convertFees{value: fees.dmtFee}();
        }

        bool referrerSend = true;
        if (referrer != address(0)) {
            (referrerSend,) = referrer.call{value: fees.referralFee}("");
        }

        if (!(streamerSend && protocolSend && feeSend && referrerSend)) {
            revert FundsTransferFailed();
        }
    }

    function sellPasses(address streamer, bytes32 packedArgs)
        external
        payable
        whenLive
    {
        PackedArgs memory args = unpackArgs(packedArgs);
        uint96 amount = args.amount;
        address referrer = args.addy;

        uint256 supply = passesSupply[streamer];
        PassesBalance storage sellerBalance =
            passesBalance[streamer][msg.sender];

        if (sellerBalance.unlocked < amount) {
            revert InsufficientPasses();
        }
        if (supply <= amount) {
            revert CannotSellLastPass();
        }

        uint256 price = getPrice(supply - amount, amount);
        Fees memory fees = getFees(price, referrer);

        sellerBalance.unlocked -= amount;
        passesSupply[streamer] = supply - amount;
        emit Trade(
            msg.sender,
            streamer,
            referrer,
            false,
            amount,
            price,
            fees.ethFee + fees.dmtFee,
            fees.streamerFee,
            fees.referralFee,
            supply - amount
        );

        (bool sellerSend,) = msg.sender.call{
            value: price
                - (fees.ethFee + fees.dmtFee + fees.streamerFee + fees.referralFee)
        }("");

        (bool streamerSend,) = streamer.call{value: fees.streamerFee}("");
        (bool protocolSend,) =
            protocolFeeDestination.call{value: fees.ethFee}("");

        bool feeSend = true;
        if (fees.dmtFee > 0) {
            feeSend = feeConverter.convertFees{value: fees.dmtFee}();
        }

        bool referrerSend = true;
        if (referrer != address(0)) {
            (referrerSend,) = referrer.call{value: fees.referralFee}("");
        }

        if (
            !(
                sellerSend && streamerSend && protocolSend && feeSend
                    && referrerSend
            )
        ) {
            revert FundsTransferFailed();
        }
    }

    function lockPasses(bytes32 packedArgs, uint256 lockTimeSeconds)
        external
        whenLive
    {
        PackedArgs memory args = unpackArgs(packedArgs);
        uint96 amount = args.amount;
        address streamer = args.addy;

        PassesBalance memory balance = passesBalance[streamer][msg.sender];
        if (balance.unlocked < amount) {
            revert InsufficientPasses();
        }

        uint64 newUnlocksAt = uint64(block.timestamp + lockTimeSeconds);
        uint64 oldUnlocksAt = balance.unlocksAt;
        if (newUnlocksAt < oldUnlocksAt) {
            revert UnlocksTooSoon();
        }

        passesBalance[streamer][msg.sender] = PassesBalance({
            locked: balance.locked += amount,
            unlocked: balance.unlocked -= amount,
            unlocksAt: newUnlocksAt
        });

        emit Locked(msg.sender, streamer, amount, newUnlocksAt);
    }

    function unlockPasses(address streamer) external whenLive {
        PassesBalance memory balance = passesBalance[streamer][msg.sender];
        if (balance.unlocksAt > block.timestamp) {
            revert NotUnlockedYet();
        }

        if (balance.locked == 0) {
            revert InsufficientPasses();
        }

        passesBalance[streamer][msg.sender] = PassesBalance({
            locked: 0,
            unlocked: balance.unlocked + balance.locked,
            unlocksAt: 0
        });

        emit Unlocked(msg.sender, streamer, balance.locked);
    }

    function getPrice(uint256 supply, uint256 amount)
        public
        pure
        returns (uint256)
    {
        uint256 x1 = priceCurve(supply);
        uint256 x2 = priceCurve(supply + amount);

        return (x2 - x1) * 1 ether / 16_000;
    }

    function priceCurve(uint256 x) public pure returns (uint256) {
        if (x == 0) {
            return 0;
        }

        return (x - 1) * x * (2 * (x - 1) + 1) / 6;
    }

    function getFees(uint256 price, address referrer)
        public
        view
        returns (Fees memory)
    {
        uint256 ethFee;
        uint256 dmtFee;
        uint256 referralFee;
        if (referrer != address(0)) {
            referralFee = price * referralFeePercent / 1 ether;
            ethFee = price * ethFeePercent / 1 ether;
            dmtFee = price * dmtFeePercent / 1 ether;
        } else {
            referralFee = 0;
            uint256 referralFeePercentShare =
                dmtFeePercent > 0 ? referralFeePercent / 2 : referralFeePercent;
            ethFee = price * (ethFeePercent + referralFeePercentShare) / 1 ether;
            dmtFee = dmtFeePercent > 0
                ? price * (dmtFeePercent + referralFeePercentShare) / 1 ether
                : 0;
        }
        uint256 streamerFee = price * streamerFeePercent / 1 ether;
        return Fees({
            streamerFee: streamerFee,
            ethFee: ethFee,
            dmtFee: dmtFee,
            referralFee: referralFee
        });
    }

    function getBuyPrice(address streamer, uint256 amount)
        public
        view
        returns (uint256)
    {
        return getPrice(passesSupply[streamer], amount);
    }

    function getSellPrice(address streamer, uint256 amount)
        public
        view
        returns (uint256)
    {
        return getPrice(passesSupply[streamer] - amount, amount);
    }

    function getBuyPriceAfterFee(address streamer, uint256 amount)
        external
        view
        returns (uint256)
    {
        uint256 price = getBuyPrice(streamer, amount);
        Fees memory fees = getFees(price, address(0));
        return price + fees.ethFee + fees.dmtFee + fees.streamerFee
            + fees.referralFee;
    }

    function getSellPriceAfterFee(address streamer, uint256 amount)
        external
        view
        returns (uint256)
    {
        uint256 price = getSellPrice(streamer, amount);
        Fees memory fees = getFees(price, address(0));
        return price - fees.ethFee + fees.dmtFee + fees.streamerFee
            + fees.referralFee;
    }

    function unpackArgs(bytes32 args)
        private
        pure
        returns (PackedArgs memory)
    {
        // Extract the amount (first 12 bytes)
        uint96 amount = uint96(uint256(args) >> (160));

        // Extract the referrer or streamer address (last 20 bytes)
        address addy = address(uint160(uint256(args)));

        return PackedArgs({amount: amount, addy: addy});
    }

    function packArgs(PackedArgs calldata args) public pure returns (bytes32) {
        return bytes32(
            (uint256(uint96(args.amount)) << 160) | uint256(uint160(args.addy))
        );
    }
}

// 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();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           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: `not(_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.
    uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8;

    /// 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 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 {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Store the new value.
            sstore(not(_OWNER_SLOT_NOT), 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 {
        /// @solidity memory-safe-assembly
        assembly {
            let ownerSlot := not(_OWNER_SLOT_NOT)
            // 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(not(_OWNER_SLOT_NOT)))) {
                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(not(_OWNER_SLOT_NOT))
        }
    }

    /// @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();
        _;
    }
}

// SPDX-License-Identifier: UNLICENSE
pragma solidity ^0.8.21;

import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {Ownable} from "@solady/auth/Ownable.sol";
import {ICamelotRouter} from "@camelot/interfaces/ICamelotRouter.sol";

interface IFeeConverter {
    function setFeeToken(address _feeToken) external;
    function setRouter(address _router) external;
    function setUsdc(address _usdc) external;

    // Withdraw collected oracle fees to a recipient
    function withdrawFees() external;
    function convertFees() external payable returns (bool);
}

// 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);
}

pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

interface ICamelotRouter is IUniswapV2Router01 {
  function removeLiquidityETHSupportingFeeOnTransferTokens(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external returns (uint amountETH);

  function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountETH);

  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    address referrer,
    uint deadline
  ) external;

  function swapExactETHForTokensSupportingFeeOnTransferTokens(
    uint amountOutMin,
    address[] calldata path,
    address to,
    address referrer,
    uint deadline
  ) external payable;

  function swapExactTokensForETHSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    address referrer,
    uint deadline
  ) external;


}

pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
  function factory() external pure returns (address);

  function WETH() external pure returns (address);

  function addLiquidity(
    address tokenA,
    address tokenB,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) external returns (uint amountA, uint amountB, uint liquidity);

  function addLiquidityETH(
    address token,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external payable returns (uint amountToken, uint amountETH, uint liquidity);

  function removeLiquidity(
    address tokenA,
    address tokenB,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) external returns (uint amountA, uint amountB);

  function removeLiquidityETH(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external returns (uint amountToken, uint amountETH);

  function removeLiquidityWithPermit(
    address tokenA,
    address tokenB,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountA, uint amountB);

  function removeLiquidityETHWithPermit(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountToken, uint amountETH);

  function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);

}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "@solmate/=lib/solmate/src/",
    "@chiru/=lib/ERC721A/contracts/",
    "@solady/=lib/solady/src/",
    "@trig/=lib/solidity-trigonometry/src/",
    "@camelot/=lib/periphery/contracts/",
    "@camelot-core/=lib/core/contracts/",
    "@manifoldxyz/libraries-solidity/=lib/caviar/lib/royalty-registry-solidity/lib/libraries-solidity/",
    "@openzeppelin/contracts-upgradeable/=lib/caviar/lib/royalty-registry-solidity/lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/caviar/lib/royalty-registry-solidity/lib/openzeppelin-contracts/contracts/",
    "ERC721A/=lib/ERC721A/contracts/",
    "caviar/=lib/caviar/",
    "core/=lib/core/contracts/",
    "create2-helpers/=lib/caviar/lib/royalty-registry-solidity/lib/create2-helpers/",
    "create2-scripts/=lib/caviar/lib/royalty-registry-solidity/lib/create2-helpers/script/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "libraries-solidity/=lib/caviar/lib/royalty-registry-solidity/lib/libraries-solidity/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/caviar/lib/royalty-registry-solidity/lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "oracle/=lib/caviar/lib/oracle/contracts/",
    "periphery/=lib/periphery/contracts/",
    "prb-math/=lib/solidity-trigonometry/lib/prb-math/contracts/",
    "reservoir-oracle/=lib/caviar/lib/oracle/contracts/",
    "royalty-registry-solidity/=lib/caviar/lib/royalty-registry-solidity/",
    "solady/=lib/solady/",
    "solidity-trigonometry/=lib/solidity-trigonometry/src/",
    "solmate/=lib/solmate/src/"
  ],
  "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

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotSellLastPass","type":"error"},{"inputs":[],"name":"FundsTransferFailed","type":"error"},{"inputs":[],"name":"InsufficientPasses","type":"error"},{"inputs":[],"name":"InsufficientPayment","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NotLiveYet","type":"error"},{"inputs":[],"name":"NotUnlockedYet","type":"error"},{"inputs":[],"name":"StreamerMustBuyFirstPass","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnlocksTooSoon","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":true,"internalType":"address","name":"streamer","type":"address"},{"indexed":false,"internalType":"uint256","name":"passAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlocksAt","type":"uint256"}],"name":"Locked","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":true,"internalType":"address","name":"trader","type":"address"},{"indexed":true,"internalType":"address","name":"streamer","type":"address"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"passAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"streamerEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"referralEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Trade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":true,"internalType":"address","name":"streamer","type":"address"},{"indexed":false,"internalType":"uint256","name":"passAmount","type":"uint256"}],"name":"Unlocked","type":"event"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"bytes32","name":"packedArgs","type":"bytes32"}],"name":"buyPasses","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"dmtFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeConverter","outputs":[{"internalType":"contract IFeeConverter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"getFees","outputs":[{"components":[{"internalType":"uint256","name":"streamerFee","type":"uint256"},{"internalType":"uint256","name":"ethFee","type":"uint256"},{"internalType":"uint256","name":"dmtFee","type":"uint256"},{"internalType":"uint256","name":"referralFee","type":"uint256"}],"internalType":"struct SankoTVPasses.Fees","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"live","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"packedArgs","type":"bytes32"},{"internalType":"uint256","name":"lockTimeSeconds","type":"uint256"}],"name":"lockPasses","outputs":[],"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":[{"components":[{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"address","name":"addy","type":"address"}],"internalType":"struct SankoTVPasses.PackedArgs","name":"args","type":"tuple"}],"name":"packArgs","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"address","name":"fan","type":"address"}],"name":"passesBalance","outputs":[{"internalType":"uint96","name":"unlocked","type":"uint96"},{"internalType":"uint96","name":"locked","type":"uint96"},{"internalType":"uint64","name":"unlocksAt","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"}],"name":"passesSupply","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"priceCurve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"protocolFeeDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralFeePercent","outputs":[{"internalType":"uint256","name":"","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":"streamer","type":"address"},{"internalType":"bytes32","name":"packedArgs","type":"bytes32"}],"name":"sellPasses","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setDmtFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setEthFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFeeConverter","name":"_feeConverter","type":"address"}],"name":"setFeeConverter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeDestination","type":"address"}],"name":"setFeeDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setLive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setReferralFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setStreamerFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"streamerFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"}],"name":"unlockPasses","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061001a3361001f565b61005b565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b611b818061006a6000396000f3fe6080604052600436106102045760003560e01c80637a31c18511610118578063f04e283e116100a0578063f478eebf1161006f578063f478eebf146105f7578063f801311f14610617578063f9a01cb61461062d578063fbe532341461065a578063fee81cf41461067a57600080fd5b8063f04e283e14610568578063f22c852f1461057b578063f2fde38b146105ce578063f46d9324146105e157600080fd5b80639ae71781116100e75780639ae71781146104d3578063a14124c2146104f3578063b98de7c714610513578063cce7b8cd14610528578063d8ce4a421461054857600080fd5b80637a31c185146104505780638da5cb5b146104705780639247a0d914610489578063957aa58c146104a957600080fd5b80632e6d29a81161019b578063542fe0621161016a578063542fe0621461037057806354d1f13d146104005780635cf4ee9114610408578063614524e214610428578063715018a61461044857600080fd5b80632e6d29a8146102e55780633fe86b68146102f85780634635256e146103185780634ce7957c1461033857600080fd5b806319a1a4c7116101d757806319a1a4c71461027d5780632267a89c1461029d57806325692962146102bd5780632d4f9999146102c557600080fd5b8063052dfafe14610209578063091e26a51461021e5780630f026f6d1461024757806313c9440b14610267575b600080fd5b61021c61021736600461194a565b6106ad565b005b34801561022a57600080fd5b5061023460035481565b6040519081526020015b60405180910390f35b34801561025357600080fd5b5061023461026236600461194a565b610b63565b34801561027357600080fd5b5061023460055481565b34801561028957600080fd5b50610234610298366004611976565b610bc9565b3480156102a957600080fd5b506102346102b836600461194a565b610c28565b61021c610c65565b3480156102d157600080fd5b5061021c6102e0366004611976565b610cb5565b61021c6102f336600461194a565b610cc2565b34801561030457600080fd5b5061021c61031336600461198f565b611118565b34801561032457600080fd5b5061023461033336600461194a565b611338565b34801561034457600080fd5b50600054610358906001600160a01b031681565b6040516001600160a01b03909116815260200161023e565b34801561037c57600080fd5b506103d061038b3660046119b1565b60076020908152600092835260408084209091529082529020546001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff169082015260600161023e565b61021c611362565b34801561041457600080fd5b5061023461042336600461198f565b61139e565b34801561043457600080fd5b5061021c610443366004611976565b6113e6565b61021c6113f3565b34801561045c57600080fd5b5061021c61046b366004611976565b611407565b34801561047c57600080fd5b50638b78c6d81954610358565b34801561049557600080fd5b5061021c6104a4366004611976565b611414565b3480156104b557600080fd5b506006546104c39060ff1681565b604051901515815260200161023e565b3480156104df57600080fd5b506102346104ee36600461194a565b611421565b3480156104ff57600080fd5b50600154610358906001600160a01b031681565b34801561051f57600080fd5b5061021c61144f565b34801561053457600080fd5b5061021c6105433660046119ea565b611466565b34801561055457600080fd5b5061021c6105633660046119ea565b61161f565b61021c6105763660046119ea565b611649565b34801561058757600080fd5b5061059b610596366004611a07565b611689565b60405161023e91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61021c6105dc3660046119ea565b611816565b3480156105ed57600080fd5b5061023460045481565b34801561060357600080fd5b50610234610612366004611a2c565b61183d565b34801561062357600080fd5b5061023460025481565b34801561063957600080fd5b506102346106483660046119ea565b60086020526000908152604090205481565b34801561066657600080fd5b5061021c6106753660046119ea565b611879565b34801561068657600080fd5b506102346106953660046119ea565b63389a75e1600c908152600091909152602090205490565b60065460ff166106d057604051631afd3bab60e21b815260040160405180910390fd5b60006106db826118a3565b80516020808301516001600160a01b038716600090815260088352604080822054600785528183203384529094529020805494955092939092906001600160601b03808616911610156107415760405163159dea9b60e21b815260040160405180910390fd5b836001600160601b0316821161076a5760405163d57482cb60e01b815260040160405180910390fd5b60006107916107826001600160601b03871685611a5a565b866001600160601b031661139e565b9050600061079f8286611689565b8354909150869084906000906107bf9084906001600160601b0316611a6d565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550856001600160601b0316846107f89190611a5a565b600860008b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550846001600160a01b0316896001600160a01b0316336001600160a01b03167f9ca3528cfea12217d72e62b6215794c9ebb440b1c13f653d5d5f55f32bcd248b60008a87876040015188602001516108789190611a94565b886000015189606001518f6001600160601b03168e6108979190611a5a565b6040805197151588526001600160601b039096166020880152948601939093526060850191909152608084015260a083015260c082015260e00160405180910390a46000336001600160a01b031682606001518360000151846040015185602001516109039190611a94565b61090d9190611a94565b6109179190611a94565b6109219085611a5a565b604051600081818185875af1925050503d806000811461095d576040519150601f19603f3d011682016040523d82523d6000602084013e610962565b606091505b505082516040519192506000916001600160a01b038d1691908381818185875af1925050503d80600081146109b3576040519150601f19603f3d011682016040523d82523d6000602084013e6109b8565b606091505b505060008054602086015160405193945091926001600160a01b0390911691908381818185875af1925050503d8060008114610a10576040519150601f19603f3d011682016040523d82523d6000602084013e610a15565b606091505b5050604085015190915060019015610aa857600160009054906101000a90046001600160a01b03166001600160a01b0316632b5335c386604001516040518263ffffffff1660e01b815260040160206040518083038185885af1158015610a80573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610aa59190611aa7565b90505b60016001600160a01b038a1615610b115760608601516040516001600160a01b038c169190600081818185875af1925050503d8060008114610b06576040519150601f19603f3d011682016040523d82523d6000602084013e610b0b565b606091505b50909150505b848015610b1b5750835b8015610b245750825b8015610b2d5750815b8015610b365750805b610b5357604051634a66f90360e01b815260040160405180910390fd5b5050505050505050505050505050565b600080610b708484611338565b90506000610b7f826000611689565b9050806060015181600001518260400151836020015185610ba09190611a94565b610baa9190611a94565b610bb49190611a94565b610bbe9190611a94565b925050505b92915050565b600081600003610bdb57506000919050565b6006610be8600184611a5a565b610bf3906002611ac9565b610bfe906001611a94565b83610c0a600182611a5a565b610c149190611ac9565b610c1e9190611ac9565b610bc39190611ae0565b600080610c358484611421565b90506000610c44826000611689565b9050806060015181600001518260400151836020015185610ba09190611a5a565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610cbd6118dc565b600355565b60065460ff16610ce557604051631afd3bab60e21b815260040160405180910390fd5b6000610cf0826118a3565b80516020808301516001600160a01b03871660009081526008909252604090912054929350909180158015610d2e5750336001600160a01b03871614155b15610d4c57604051636c7b35c360e01b815260040160405180910390fd5b6000610d6182856001600160601b031661139e565b90506000610d6f8285611689565b6060810151815160408301516020840151939450600093610d909087611a94565b610d9a9190611a94565b610da49190611a94565b610dae9190611a94565b905080341015610dd15760405163cd1c886760e01b815260040160405180910390fd5b6001600160a01b038916600090815260076020908152604080832033845290915281208054889290610e0d9084906001600160601b0316611b02565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550856001600160601b031684610e469190611a94565b600860008b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550846001600160a01b0316896001600160a01b0316336001600160a01b03167f9ca3528cfea12217d72e62b6215794c9ebb440b1c13f653d5d5f55f32bcd248b60018a8888604001518960200151610ec69190611a94565b89600001518a606001518f6001600160601b03168e610ee59190611a94565b6040805197151588526001600160601b039096166020880152948601939093526060850191909152608084015260a083015260c082015260e00160405180910390a481516040516000916001600160a01b038c16918381818185875af1925050503d8060008114610f72576040519150601f19603f3d011682016040523d82523d6000602084013e610f77565b606091505b505060008054602086015160405193945091926001600160a01b0390911691908381818185875af1925050503d8060008114610fcf576040519150601f19603f3d011682016040523d82523d6000602084013e610fd4565b606091505b505060408501519091506001901561106757600160009054906101000a90046001600160a01b03166001600160a01b0316632b5335c386604001516040518263ffffffff1660e01b815260040160206040518083038185885af115801561103f573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906110649190611aa7565b90505b60016001600160a01b038916156110d05760608601516040516001600160a01b038b169190600081818185875af1925050503d80600081146110c5576040519150601f19603f3d011682016040523d82523d6000602084013e6110ca565b606091505b50909150505b8380156110da5750825b80156110e35750815b80156110ec5750805b61110957604051634a66f90360e01b815260040160405180910390fd5b50505050505050505050505050565b60065460ff1661113b57604051631afd3bab60e21b815260040160405180910390fd5b6000611146836118a3565b80516020808301516001600160a01b0381166000908152600783526040808220338352845290819020815160608101835290546001600160601b03808216808452600160601b8304821696840196909652600160c01b90910467ffffffffffffffff169282019290925294955092939092909190841611156111db5760405163159dea9b60e21b815260040160405180910390fd5b60006111e78642611a94565b604083015190915067ffffffffffffffff808216908316101561121d5760405163bad21ce360e01b815260040160405180910390fd5b6040518060600160405280868560000181815161123a9190611a6d565b6001600160601b0316908190528252506020858101805191909201918891611263908390611b02565b6001600160601b039081169182905290835267ffffffffffffffff86811660209485018190526001600160a01b038a1660008181526007875260408082203380845290895291819020895181548b8b01519b840151909716600160c01b026001600160c01b039b8916600160601b026001600160c01b0319909816918916919091179690961799909916949094179097558251938c168452948301529293927f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c542992500160405180910390a35050505050505050565b6001600160a01b03821660009081526008602052604081205461135b908361139e565b9392505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b6000806113aa84610bc9565b905060006113bb6102988587611a94565b9050613e806113ca8383611a5a565b6113dc90670de0b6b3a7640000611ac9565b610bbe9190611ae0565b6113ee6118dc565b600555565b6113fb6118dc565b61140560006118f7565b565b61140f6118dc565b600455565b61141c6118dc565b600255565b6001600160a01b03821660009081526008602052604081205461135b90611449908490611a5a565b8361139e565b6114576118dc565b6006805460ff19166001179055565b60065460ff1661148957604051631afd3bab60e21b815260040160405180910390fd5b6001600160a01b0381166000908152600760209081526040808320338452825291829020825160608101845290546001600160601b038082168352600160601b82041692820192909252600160c01b90910467ffffffffffffffff169181018290529042101561150c5760405163dbace0b160e01b815260040160405180910390fd5b80602001516001600160601b031660000361153a5760405163159dea9b60e21b815260040160405180910390fd5b6040518060600160405280826020015183600001516115599190611b02565b6001600160601b0390811682526000602080840182905260409384018290526001600160a01b03871680835260078252848320338085529083529285902086518154888501519888015167ffffffffffffffff16600160c01b026001600160c01b03998816600160601b026001600160c01b031990921692881692909217179790971696909617909555858101519351939092168352917fe6e0ef9cd056ca98561ca60e347ada61e1ede2f1142a078951b7a52e1e508e60910160405180910390a35050565b6116276118dc565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6116516118dc565b63389a75e1600c52806000526020600c20805442111561167957636f5e88186000526004601cfd5b60009055611686816118f7565b50565b6116b46040518060800160405280600081526020016000815260200160008152602001600081525090565b600080806001600160a01b0385161561173557670de0b6b3a7640000600554876116de9190611ac9565b6116e89190611ae0565b9050670de0b6b3a7640000600254876117019190611ac9565b61170b9190611ae0565b9250670de0b6b3a7640000600354876117249190611ac9565b61172e9190611ae0565b91506117ca565b600090506000806003541161174c5760055461175b565b600260055461175b9190611ae0565b9050670de0b6b3a7640000816002546117749190611a94565b61177e9089611ac9565b6117889190611ae0565b935060006003541161179b5760006117c6565b670de0b6b3a7640000816003546117b29190611a94565b6117bc9089611ac9565b6117c69190611ae0565b9250505b6000670de0b6b3a7640000600454886117e39190611ac9565b6117ed9190611ae0565b604080516080810182529182526020820195909552938401929092526060830152509392505050565b61181e6118dc565b8060601b61183457637448fbae6000526004601cfd5b611686816118f7565b600061184f60408301602084016119ea565b6001600160a01b031660a06118676020850185611b22565b6001600160601b0316901b1792915050565b6118816118dc565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040805180820190915260008082526020820152506040805180820190915260a082901c81526001600160a01b03909116602082015290565b638b78c6d819543314611405576382b429006000526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b6001600160a01b038116811461168657600080fd5b6000806040838503121561195d57600080fd5b823561196881611935565b946020939093013593505050565b60006020828403121561198857600080fd5b5035919050565b600080604083850312156119a257600080fd5b50508035926020909101359150565b600080604083850312156119c457600080fd5b82356119cf81611935565b915060208301356119df81611935565b809150509250929050565b6000602082840312156119fc57600080fd5b813561135b81611935565b60008060408385031215611a1a57600080fd5b8235915060208301356119df81611935565b600060408284031215611a3e57600080fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610bc357610bc3611a44565b6001600160601b03828116828216039080821115611a8d57611a8d611a44565b5092915050565b80820180821115610bc357610bc3611a44565b600060208284031215611ab957600080fd5b8151801515811461135b57600080fd5b8082028115828204841417610bc357610bc3611a44565b600082611afd57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03818116838216019080821115611a8d57611a8d611a44565b600060208284031215611b3457600080fd5b81356001600160601b038116811461135b57600080fdfea2646970667358221220277cdaa5464523e155f419463e8006abaaa996201a1ff0187f0fc07f0f52823f64736f6c63430008150033

Deployed Bytecode

0x6080604052600436106102045760003560e01c80637a31c18511610118578063f04e283e116100a0578063f478eebf1161006f578063f478eebf146105f7578063f801311f14610617578063f9a01cb61461062d578063fbe532341461065a578063fee81cf41461067a57600080fd5b8063f04e283e14610568578063f22c852f1461057b578063f2fde38b146105ce578063f46d9324146105e157600080fd5b80639ae71781116100e75780639ae71781146104d3578063a14124c2146104f3578063b98de7c714610513578063cce7b8cd14610528578063d8ce4a421461054857600080fd5b80637a31c185146104505780638da5cb5b146104705780639247a0d914610489578063957aa58c146104a957600080fd5b80632e6d29a81161019b578063542fe0621161016a578063542fe0621461037057806354d1f13d146104005780635cf4ee9114610408578063614524e214610428578063715018a61461044857600080fd5b80632e6d29a8146102e55780633fe86b68146102f85780634635256e146103185780634ce7957c1461033857600080fd5b806319a1a4c7116101d757806319a1a4c71461027d5780632267a89c1461029d57806325692962146102bd5780632d4f9999146102c557600080fd5b8063052dfafe14610209578063091e26a51461021e5780630f026f6d1461024757806313c9440b14610267575b600080fd5b61021c61021736600461194a565b6106ad565b005b34801561022a57600080fd5b5061023460035481565b6040519081526020015b60405180910390f35b34801561025357600080fd5b5061023461026236600461194a565b610b63565b34801561027357600080fd5b5061023460055481565b34801561028957600080fd5b50610234610298366004611976565b610bc9565b3480156102a957600080fd5b506102346102b836600461194a565b610c28565b61021c610c65565b3480156102d157600080fd5b5061021c6102e0366004611976565b610cb5565b61021c6102f336600461194a565b610cc2565b34801561030457600080fd5b5061021c61031336600461198f565b611118565b34801561032457600080fd5b5061023461033336600461194a565b611338565b34801561034457600080fd5b50600054610358906001600160a01b031681565b6040516001600160a01b03909116815260200161023e565b34801561037c57600080fd5b506103d061038b3660046119b1565b60076020908152600092835260408084209091529082529020546001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff169082015260600161023e565b61021c611362565b34801561041457600080fd5b5061023461042336600461198f565b61139e565b34801561043457600080fd5b5061021c610443366004611976565b6113e6565b61021c6113f3565b34801561045c57600080fd5b5061021c61046b366004611976565b611407565b34801561047c57600080fd5b50638b78c6d81954610358565b34801561049557600080fd5b5061021c6104a4366004611976565b611414565b3480156104b557600080fd5b506006546104c39060ff1681565b604051901515815260200161023e565b3480156104df57600080fd5b506102346104ee36600461194a565b611421565b3480156104ff57600080fd5b50600154610358906001600160a01b031681565b34801561051f57600080fd5b5061021c61144f565b34801561053457600080fd5b5061021c6105433660046119ea565b611466565b34801561055457600080fd5b5061021c6105633660046119ea565b61161f565b61021c6105763660046119ea565b611649565b34801561058757600080fd5b5061059b610596366004611a07565b611689565b60405161023e91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61021c6105dc3660046119ea565b611816565b3480156105ed57600080fd5b5061023460045481565b34801561060357600080fd5b50610234610612366004611a2c565b61183d565b34801561062357600080fd5b5061023460025481565b34801561063957600080fd5b506102346106483660046119ea565b60086020526000908152604090205481565b34801561066657600080fd5b5061021c6106753660046119ea565b611879565b34801561068657600080fd5b506102346106953660046119ea565b63389a75e1600c908152600091909152602090205490565b60065460ff166106d057604051631afd3bab60e21b815260040160405180910390fd5b60006106db826118a3565b80516020808301516001600160a01b038716600090815260088352604080822054600785528183203384529094529020805494955092939092906001600160601b03808616911610156107415760405163159dea9b60e21b815260040160405180910390fd5b836001600160601b0316821161076a5760405163d57482cb60e01b815260040160405180910390fd5b60006107916107826001600160601b03871685611a5a565b866001600160601b031661139e565b9050600061079f8286611689565b8354909150869084906000906107bf9084906001600160601b0316611a6d565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550856001600160601b0316846107f89190611a5a565b600860008b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550846001600160a01b0316896001600160a01b0316336001600160a01b03167f9ca3528cfea12217d72e62b6215794c9ebb440b1c13f653d5d5f55f32bcd248b60008a87876040015188602001516108789190611a94565b886000015189606001518f6001600160601b03168e6108979190611a5a565b6040805197151588526001600160601b039096166020880152948601939093526060850191909152608084015260a083015260c082015260e00160405180910390a46000336001600160a01b031682606001518360000151846040015185602001516109039190611a94565b61090d9190611a94565b6109179190611a94565b6109219085611a5a565b604051600081818185875af1925050503d806000811461095d576040519150601f19603f3d011682016040523d82523d6000602084013e610962565b606091505b505082516040519192506000916001600160a01b038d1691908381818185875af1925050503d80600081146109b3576040519150601f19603f3d011682016040523d82523d6000602084013e6109b8565b606091505b505060008054602086015160405193945091926001600160a01b0390911691908381818185875af1925050503d8060008114610a10576040519150601f19603f3d011682016040523d82523d6000602084013e610a15565b606091505b5050604085015190915060019015610aa857600160009054906101000a90046001600160a01b03166001600160a01b0316632b5335c386604001516040518263ffffffff1660e01b815260040160206040518083038185885af1158015610a80573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610aa59190611aa7565b90505b60016001600160a01b038a1615610b115760608601516040516001600160a01b038c169190600081818185875af1925050503d8060008114610b06576040519150601f19603f3d011682016040523d82523d6000602084013e610b0b565b606091505b50909150505b848015610b1b5750835b8015610b245750825b8015610b2d5750815b8015610b365750805b610b5357604051634a66f90360e01b815260040160405180910390fd5b5050505050505050505050505050565b600080610b708484611338565b90506000610b7f826000611689565b9050806060015181600001518260400151836020015185610ba09190611a94565b610baa9190611a94565b610bb49190611a94565b610bbe9190611a94565b925050505b92915050565b600081600003610bdb57506000919050565b6006610be8600184611a5a565b610bf3906002611ac9565b610bfe906001611a94565b83610c0a600182611a5a565b610c149190611ac9565b610c1e9190611ac9565b610bc39190611ae0565b600080610c358484611421565b90506000610c44826000611689565b9050806060015181600001518260400151836020015185610ba09190611a5a565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610cbd6118dc565b600355565b60065460ff16610ce557604051631afd3bab60e21b815260040160405180910390fd5b6000610cf0826118a3565b80516020808301516001600160a01b03871660009081526008909252604090912054929350909180158015610d2e5750336001600160a01b03871614155b15610d4c57604051636c7b35c360e01b815260040160405180910390fd5b6000610d6182856001600160601b031661139e565b90506000610d6f8285611689565b6060810151815160408301516020840151939450600093610d909087611a94565b610d9a9190611a94565b610da49190611a94565b610dae9190611a94565b905080341015610dd15760405163cd1c886760e01b815260040160405180910390fd5b6001600160a01b038916600090815260076020908152604080832033845290915281208054889290610e0d9084906001600160601b0316611b02565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550856001600160601b031684610e469190611a94565b600860008b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550846001600160a01b0316896001600160a01b0316336001600160a01b03167f9ca3528cfea12217d72e62b6215794c9ebb440b1c13f653d5d5f55f32bcd248b60018a8888604001518960200151610ec69190611a94565b89600001518a606001518f6001600160601b03168e610ee59190611a94565b6040805197151588526001600160601b039096166020880152948601939093526060850191909152608084015260a083015260c082015260e00160405180910390a481516040516000916001600160a01b038c16918381818185875af1925050503d8060008114610f72576040519150601f19603f3d011682016040523d82523d6000602084013e610f77565b606091505b505060008054602086015160405193945091926001600160a01b0390911691908381818185875af1925050503d8060008114610fcf576040519150601f19603f3d011682016040523d82523d6000602084013e610fd4565b606091505b505060408501519091506001901561106757600160009054906101000a90046001600160a01b03166001600160a01b0316632b5335c386604001516040518263ffffffff1660e01b815260040160206040518083038185885af115801561103f573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906110649190611aa7565b90505b60016001600160a01b038916156110d05760608601516040516001600160a01b038b169190600081818185875af1925050503d80600081146110c5576040519150601f19603f3d011682016040523d82523d6000602084013e6110ca565b606091505b50909150505b8380156110da5750825b80156110e35750815b80156110ec5750805b61110957604051634a66f90360e01b815260040160405180910390fd5b50505050505050505050505050565b60065460ff1661113b57604051631afd3bab60e21b815260040160405180910390fd5b6000611146836118a3565b80516020808301516001600160a01b0381166000908152600783526040808220338352845290819020815160608101835290546001600160601b03808216808452600160601b8304821696840196909652600160c01b90910467ffffffffffffffff169282019290925294955092939092909190841611156111db5760405163159dea9b60e21b815260040160405180910390fd5b60006111e78642611a94565b604083015190915067ffffffffffffffff808216908316101561121d5760405163bad21ce360e01b815260040160405180910390fd5b6040518060600160405280868560000181815161123a9190611a6d565b6001600160601b0316908190528252506020858101805191909201918891611263908390611b02565b6001600160601b039081169182905290835267ffffffffffffffff86811660209485018190526001600160a01b038a1660008181526007875260408082203380845290895291819020895181548b8b01519b840151909716600160c01b026001600160c01b039b8916600160601b026001600160c01b0319909816918916919091179690961799909916949094179097558251938c168452948301529293927f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c542992500160405180910390a35050505050505050565b6001600160a01b03821660009081526008602052604081205461135b908361139e565b9392505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b6000806113aa84610bc9565b905060006113bb6102988587611a94565b9050613e806113ca8383611a5a565b6113dc90670de0b6b3a7640000611ac9565b610bbe9190611ae0565b6113ee6118dc565b600555565b6113fb6118dc565b61140560006118f7565b565b61140f6118dc565b600455565b61141c6118dc565b600255565b6001600160a01b03821660009081526008602052604081205461135b90611449908490611a5a565b8361139e565b6114576118dc565b6006805460ff19166001179055565b60065460ff1661148957604051631afd3bab60e21b815260040160405180910390fd5b6001600160a01b0381166000908152600760209081526040808320338452825291829020825160608101845290546001600160601b038082168352600160601b82041692820192909252600160c01b90910467ffffffffffffffff169181018290529042101561150c5760405163dbace0b160e01b815260040160405180910390fd5b80602001516001600160601b031660000361153a5760405163159dea9b60e21b815260040160405180910390fd5b6040518060600160405280826020015183600001516115599190611b02565b6001600160601b0390811682526000602080840182905260409384018290526001600160a01b03871680835260078252848320338085529083529285902086518154888501519888015167ffffffffffffffff16600160c01b026001600160c01b03998816600160601b026001600160c01b031990921692881692909217179790971696909617909555858101519351939092168352917fe6e0ef9cd056ca98561ca60e347ada61e1ede2f1142a078951b7a52e1e508e60910160405180910390a35050565b6116276118dc565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6116516118dc565b63389a75e1600c52806000526020600c20805442111561167957636f5e88186000526004601cfd5b60009055611686816118f7565b50565b6116b46040518060800160405280600081526020016000815260200160008152602001600081525090565b600080806001600160a01b0385161561173557670de0b6b3a7640000600554876116de9190611ac9565b6116e89190611ae0565b9050670de0b6b3a7640000600254876117019190611ac9565b61170b9190611ae0565b9250670de0b6b3a7640000600354876117249190611ac9565b61172e9190611ae0565b91506117ca565b600090506000806003541161174c5760055461175b565b600260055461175b9190611ae0565b9050670de0b6b3a7640000816002546117749190611a94565b61177e9089611ac9565b6117889190611ae0565b935060006003541161179b5760006117c6565b670de0b6b3a7640000816003546117b29190611a94565b6117bc9089611ac9565b6117c69190611ae0565b9250505b6000670de0b6b3a7640000600454886117e39190611ac9565b6117ed9190611ae0565b604080516080810182529182526020820195909552938401929092526060830152509392505050565b61181e6118dc565b8060601b61183457637448fbae6000526004601cfd5b611686816118f7565b600061184f60408301602084016119ea565b6001600160a01b031660a06118676020850185611b22565b6001600160601b0316901b1792915050565b6118816118dc565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040805180820190915260008082526020820152506040805180820190915260a082901c81526001600160a01b03909116602082015290565b638b78c6d819543314611405576382b429006000526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b6001600160a01b038116811461168657600080fd5b6000806040838503121561195d57600080fd5b823561196881611935565b946020939093013593505050565b60006020828403121561198857600080fd5b5035919050565b600080604083850312156119a257600080fd5b50508035926020909101359150565b600080604083850312156119c457600080fd5b82356119cf81611935565b915060208301356119df81611935565b809150509250929050565b6000602082840312156119fc57600080fd5b813561135b81611935565b60008060408385031215611a1a57600080fd5b8235915060208301356119df81611935565b600060408284031215611a3e57600080fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610bc357610bc3611a44565b6001600160601b03828116828216039080821115611a8d57611a8d611a44565b5092915050565b80820180821115610bc357610bc3611a44565b600060208284031215611ab957600080fd5b8151801515811461135b57600080fd5b8082028115828204841417610bc357610bc3611a44565b600082611afd57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03818116838216019080821115611a8d57611a8d611a44565b600060208284031215611b3457600080fd5b81356001600160601b038116811461135b57600080fdfea2646970667358221220277cdaa5464523e155f419463e8006abaaa996201a1ff0187f0fc07f0f52823f64736f6c63430008150033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.