Holesky Testnet

Contract

0xFde372A760e409616780FE213Da24af546815eB0

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Refund4290772023-12-01 1:35:12367 days ago1701394512IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4290722023-12-01 1:34:12367 days ago1701394452IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund User4249492023-11-30 11:17:48368 days ago1701343068IN
0xFde372A7...546815eB0
0 ETH0.000057071.5
Deposit4240132023-11-30 7:59:12368 days ago1701331152IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4240052023-11-30 7:57:36368 days ago1701331056IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4239952023-11-30 7:55:24368 days ago1701330924IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4239872023-11-30 7:53:48368 days ago1701330828IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4239842023-11-30 7:52:48368 days ago1701330768IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4234932023-11-30 6:09:12368 days ago1701324552IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4233882023-11-30 5:47:12368 days ago1701323232IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4233842023-11-30 5:46:24368 days ago1701323184IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4233582023-11-30 5:40:48368 days ago1701322848IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4233552023-11-30 5:40:12368 days ago1701322812IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4233402023-11-30 5:37:12368 days ago1701322632IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4233382023-11-30 5:36:48368 days ago1701322608IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4232372023-11-30 5:15:48368 days ago1701321348IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4232352023-11-30 5:15:24368 days ago1701321324IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4232262023-11-30 5:13:24368 days ago1701321204IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund4232242023-11-30 5:13:00368 days ago1701321180IN
0xFde372A7...546815eB0
0 ETH0.00006231.5
Deposit4231662023-11-30 5:01:00368 days ago1701320460IN
0xFde372A7...546815eB0
32 ETH0.000700921.5
Set Refund Delay4230142023-11-30 4:29:24368 days ago1701318564IN
0xFde372A7...546815eB0
0 ETH0.00003751.5
Refund User4230122023-11-30 4:29:00368 days ago1701318540IN
0xFde372A7...546815eB0
0 ETH0.000054071.5
Deposit4230072023-11-30 4:28:00368 days ago1701318480IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
Refund User4230052023-11-30 4:27:36368 days ago1701318456IN
0xFde372A7...546815eB0
0 ETH0.000054071.5
Deposit4229632023-11-30 4:18:48368 days ago1701317928IN
0xFde372A7...546815eB0
32 ETH0.000123811.5
View all transactions

Latest 16 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
4290772023-12-01 1:35:12367 days ago1701394512
0xFde372A7...546815eB0
32 ETH
4249492023-11-30 11:17:48368 days ago1701343068
0xFde372A7...546815eB0
32 ETH
4240052023-11-30 7:57:36368 days ago1701331056
0xFde372A7...546815eB0
32 ETH
4239872023-11-30 7:53:48368 days ago1701330828
0xFde372A7...546815eB0
32 ETH
4234932023-11-30 6:09:12368 days ago1701324552
0xFde372A7...546815eB0
32 ETH
4233842023-11-30 5:46:24368 days ago1701323184
0xFde372A7...546815eB0
32 ETH
4233552023-11-30 5:40:12368 days ago1701322812
0xFde372A7...546815eB0
32 ETH
4233382023-11-30 5:36:48368 days ago1701322608
0xFde372A7...546815eB0
32 ETH
4232352023-11-30 5:15:24368 days ago1701321324
0xFde372A7...546815eB0
32 ETH
4232242023-11-30 5:13:00368 days ago1701321180
0xFde372A7...546815eB0
32 ETH
4231662023-11-30 5:01:00368 days ago1701320460
0xFde372A7...546815eB0
 Contract Creation0 ETH
4230122023-11-30 4:29:00368 days ago1701318540
0xFde372A7...546815eB0
32 ETH
4230052023-11-30 4:27:36368 days ago1701318456
0xFde372A7...546815eB0
32 ETH
4229592023-11-30 4:18:00368 days ago1701317880
0xFde372A7...546815eB0
32 ETH
4229202023-11-30 4:09:48368 days ago1701317388
0xFde372A7...546815eB0
32 ETH
4160972023-11-29 4:14:24369 days ago1701231264
0xFde372A7...546815eB0
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Staking

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : Staking.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.13;

import {ReentrancyGuard} from "solmate/utils/ReentrancyGuard.sol";
import {IDepositContract} from "src/interfaces/IDepositContract.sol";
import {IStaking} from "src/interfaces/IStaking.sol";
import {Owned} from "src/lib/Owned.sol";
import {Pausable} from "src/lib/Pausable.sol";
import {SafeTransferLib} from "src/lib/SafeTransferLib.sol";
import {FeeRecipient} from "src/FeeRecipient.sol";
import {StakingConstants} from "src/StakingConstants.sol";

contract Staking is IStaking, ReentrancyGuard, Owned, Pausable, StakingConstants {
    /// @notice Ethereum staking deposit contract address.
    address public immutable depositContract;
    /// @notice stakewith.us treasury which receives share of profit from execution layer rewards.
    address public treasury;
    /// @notice One-time fee for creating a new validator.
    uint256 public oneTimeFee;
    /// @notice Performance fee percentage from execution layer rewards / `FEE_BASIS`, i.e. 10_000 represents 100%.
    uint256 public performanceFee;
    /// @notice Delay before a user can initiate a refund of pending unstaked ETH.
    uint256 public refundDelay;
    /// @notice Total number pending unstaked deposits across all users.
    uint256 public totalPendingValidators;

    /// @notice Mapping of users to FeeRecipient contracts which users collect their execution layer rewards from.
    mapping(address => address) public registry;
    /// @notice Mapping of users to number of pending unstaked deposits for that user.
    mapping(address => uint256) public pendingValidators;
    /// @notice Mapping of users to timestamp of their last deposit.
    mapping(address => uint256) public lastDepositTimestamp;

    uint256 internal constant _DEPOSIT_AMOUNT = 32 ether;
    uint256 internal constant _MAXIMUM_REFUND_DELAY = 7 days;

    error InvalidAmount();
    error InvalidLength();
    error PendingValidators();
    error NoDeposit();
    error BeforeRefundDelay();
    error SameValue();

    constructor(
        address owner_,
        address operator_,
        address depositContract_,
        address treasury_,
        uint256 oneTimeFee_,
        uint256 performanceFee_,
        uint256 refundDelay_
    ) Owned(owner_, operator_) {
        if (depositContract_ == address(0)) revert ZeroAddress();
        depositContract = depositContract_;
        _setTreasury(treasury_);
        _setOneTimeFee(oneTimeFee_);
        _setPerformanceFee(performanceFee_);
        _setRefundDelay(refundDelay_);
    }

    /// @dev Costs less gas than `deposit()` if user if depositing for their own address.
    receive() external payable {
        _deposit(msg.sender);
    }

    /*//////////////////////////////////////
	            PUBLIC FUNCTIONS
	//////////////////////////////////////*/

    /**
     * @notice Deposits ETH into this contract for stakewith.us to create a new validator node on user's behalf.
     * @param user_ User's withdrawal address which receives consensus rewards and can claim execution layer rewards.
     * @dev `msg.value` must be a multiple of `_DEPOSIT_AMOUNT (32 ether) + oneTimeFee`
     */
    function deposit(address user_) external payable {
        _deposit(user_);
    }

    function _deposit(address user_) internal whenNotPaused nonReentrant {
        if (user_ == address(0)) revert ZeroAddress();
        if (pendingValidators[user_] > 0) revert PendingValidators();

        uint256 perValidator = _DEPOSIT_AMOUNT + oneTimeFee;
        if (msg.value == 0 || msg.value % perValidator != 0) revert InvalidAmount();

        // Deploy FeeRecipient for address if its their first deposit.
        if (registry[user_] == address(0)) {
            address feeRecipient = address(new FeeRecipient(user_));
            registry[user_] = feeRecipient;
            emit UserRegistered(user_, feeRecipient);
        }

        uint256 validators = msg.value / perValidator;

        pendingValidators[user_] += validators;
        totalPendingValidators += validators;
        lastDepositTimestamp[user_] = block.timestamp;

        emit Deposit(msg.sender, user_, validators);
    }

    /**
     * @notice Refunds unstaked ETH to user. User must wait for at least `refundDelay` after depositing before
     * initiating a refund.
     */
    function refund() external nonReentrant {
        uint256 validators = pendingValidators[msg.sender];
        if (block.timestamp < lastDepositTimestamp[msg.sender] + refundDelay) revert BeforeRefundDelay();

        _refund(msg.sender, validators);
    }

    /*////////////////////////////////////////
	            OPERATOR FUNCTIONS
	////////////////////////////////////////*/

    function stake(address user_, DepositData[] memory data_) external onlyOperator {
        uint256 length = data_.length;
        if (length == 0) revert InvalidLength();

        // This underflows, throwing an error if length > pendingValidators[user_]
        pendingValidators[user_] -= length;
        totalPendingValidators -= length;

        if (oneTimeFee > 0) SafeTransferLib.safeTransferETH(treasury, length * oneTimeFee);

        bytes[] memory pubkeys = new bytes[](length);

        for (uint256 i = 0; i < length; ++i) {
            bytes memory pubkey = data_[i].pubkey;

            IDepositContract(depositContract).deposit{value: _DEPOSIT_AMOUNT}({
                pubkey: pubkey,
                withdrawal_credentials: abi.encodePacked(true, uint88(0), user_), // true | 11 bytes padding | address
                signature: data_[i].signature,
                deposit_data_root: data_[i].deposit_data_root
            });

            pubkeys[i] = pubkey;
        }

        emit Staked(user_, pubkeys);
    }

    function refundUser(address user_, uint256 validators_) external onlyOperator {
        _refund(user_, validators_);
    }

    function pause() external onlyOperator {
        _pause();
    }

    function unpause() external onlyOperator {
        _unpause();
    }

    /*/////////////////////////////////////
	            OWNER FUNCTIONS
	/////////////////////////////////////*/

    function setOneTimeFee(uint256 oneTimeFee_) external onlyOwner {
        if (oneTimeFee_ == oneTimeFee) revert SameValue();
        _setOneTimeFee(oneTimeFee_);
    }

    function setPerformanceFee(uint256 performanceFee_) external onlyOwner {
        if (performanceFee_ == performanceFee) revert SameValue();
        _setPerformanceFee(performanceFee_);
    }

    function setTreasury(address treasury_) external onlyOwner {
        if (treasury_ == address(0)) revert ZeroAddress();
        if (treasury_ == treasury) revert SameValue();
        _setTreasury(treasury_);
    }

    function setRefundDelay(uint256 refundDelay_) external onlyOwner {
        if (refundDelay_ == refundDelay) revert SameValue();
        _setRefundDelay(refundDelay_);
    }

    /*////////////////////////////////////////
	            INTERNAL FUNCTIONS
	////////////////////////////////////////*/

    function _refund(address user_, uint256 validators_) internal {
        if (validators_ == 0) revert NoDeposit();

        // This underflows, throwing an error if validators_ > pendingValidators[user_]
        pendingValidators[user_] -= validators_;
        totalPendingValidators -= validators_;

        SafeTransferLib.safeTransferETH(user_, validators_ * (_DEPOSIT_AMOUNT + oneTimeFee));
        emit Refund(user_, validators_);
    }

    /// @dev One-time fee cannot be adjusted while there are still pending validators. Pause contract and stake/refund
    /// all pending validators before changing one-time fee.
    function _setOneTimeFee(uint256 oneTimeFee_) internal {
        if (totalPendingValidators != 0) revert PendingValidators();
        oneTimeFee = oneTimeFee_;
        emit OneTimeFeeSet(oneTimeFee_);
    }

    function _setPerformanceFee(uint256 performanceFee_) internal {
        if (performanceFee_ > FEE_BASIS) revert InvalidAmount();
        performanceFee = performanceFee_;
        emit PerformanceFeeSet(performanceFee_);
    }

    function _setTreasury(address treasury_) internal {
        emit NewTreasury(treasury, treasury_);
        treasury = treasury_;
    }

    function _setRefundDelay(uint256 refundDelay_) internal {
        if (refundDelay_ > _MAXIMUM_REFUND_DELAY) revert InvalidAmount();
        refundDelay = refundDelay_;
        emit RefundDelaySet(refundDelay_);
    }
}

File 2 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

File 3 of 10 : IDepositContract.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.13;

interface IDepositContract {
    function deposit(
        bytes calldata pubkey,
        bytes calldata withdrawal_credentials,
        bytes calldata signature,
        bytes32 deposit_data_root
    ) external payable;
}

File 4 of 10 : IStaking.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IStaking {
    struct DepositData {
        bytes pubkey;
        bytes signature;
        bytes32 deposit_data_root;
    }

    event UserRegistered(address indexed user, address indexed feeRecipient);
    event Deposit(address indexed from, address indexed user, uint256 validators);
    event Staked(address indexed user, bytes[] pubkeys);
    event Refund(address indexed user, uint256 validators);
    event OneTimeFeeSet(uint256);
    event PerformanceFeeSet(uint256);
    event NewTreasury(address indexed oldTreasury, address indexed newTreasury);
    event RefundDelaySet(uint256);

    function depositContract() external view returns (address);

    function treasury() external view returns (address);

    function oneTimeFee() external view returns (uint256);

    function performanceFee() external view returns (uint256);

    function registry(address) external view returns (address);

    function pendingValidators(address) external view returns (uint256);

    function deposit(address user) external payable;
}

File 5 of 10 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.13;

/**
 * @notice Auth contract with two levels of access - `owner` can access both `onlyOwner` and `onlyOperator` functions,
 *  while `operator` can only access `onlyOperator` functions.
 */
abstract contract Owned {
    address public owner;
    address public nominatedOwner;
    address public operator;

    event NewOwner(address indexed oldOwner, address indexed newOwner);
    event NominatedOwner(address indexed nominatedOwner);
    event NewOperator(address indexed oldOperator, address indexed newOperator);

    error Unauthorized();
    error ZeroAddress();

    modifier onlyOwner() virtual {
        if (msg.sender != owner) revert Unauthorized();
        _;
    }

    modifier onlyNominatedOwner() virtual {
        if (msg.sender != nominatedOwner) revert Unauthorized();
        _;
    }

    modifier onlyOperator() virtual {
        if (msg.sender != owner && msg.sender != operator) revert Unauthorized();
        _;
    }

    constructor(address owner_, address operator_) {
        if (owner_ == address(0)) revert ZeroAddress();
        if (operator_ == address(0)) revert ZeroAddress();
        emit NewOwner(address(0), owner_);
        emit NewOperator(address(0), operator_);
        owner = owner_;
        operator = operator_;
    }

    function setOperator(address operator_) public virtual onlyOwner {
        if (operator_ == address(0)) revert ZeroAddress();
        emit NewOperator(operator, operator_);
        operator = operator_;
    }

    function nominateOwner(address nominatedOwner_) public virtual onlyOwner {
        emit NominatedOwner(nominatedOwner_);
        nominatedOwner = nominatedOwner_;
    }

    function acceptOwnership() public virtual onlyNominatedOwner {
        emit NewOwner(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }
}

File 6 of 10 : Pausable.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.13;

abstract contract Pausable {
    bool public paused;

    event Paused(address indexed sender);
    event Unpaused(address indexed sender);

    error IsPaused();
    error NotPaused();

    function _pause() internal whenNotPaused {
        paused = true;
        emit Paused(msg.sender);
    }

    function _unpause() internal whenPaused {
        paused = false;
        emit Unpaused(msg.sender);
    }

    modifier whenNotPaused() {
        if (paused) revert IsPaused();
        _;
    }

    modifier whenPaused() {
        if (!paused) revert NotPaused();
        _;
    }
}

File 7 of 10 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.13;

/// @notice Gas-efficient safe ETH transfer library that gracefully handles missing return values.
/// @author Copied from Solmate with ERC20 code removed.
/// @author https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }
}

File 8 of 10 : FeeRecipient.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.13;

import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";
import {IStaking} from "src/interfaces/IStaking.sol";
import {SafeTransferLib} from "src/lib/SafeTransferLib.sol";
import {StakingConstants} from "src/StakingConstants.sol";

/**
 * @notice Contract set as the `fee_recipient` for all validators belonging to a user. Receives execution layer rewards
 * from block production gas tips and MEV bribes which users can claim via `claimRewards()` function.
 */
contract FeeRecipient is StakingConstants {
    using FixedPointMathLib for uint256;

    IStaking public immutable staking;
    address public immutable user;

    /// @dev Unclaimed rewards that fully belong to user.
    uint256 internal _userRewards;

    event ClaimRewards(uint256 amount);
    event TreasuryClaim(uint256 amount);

    error Unauthorized();
    error NothingToClaim();

    constructor(address user_) {
        staking = IStaking(payable(msg.sender));
        user = user_;
    }

    /// @dev To receive MEV bribes directly transferred to `fee_recipient`.
    receive() external payable {}

    function unclaimedRewards() public view returns (uint256) {
        return address(this).balance - _calcToTreasury(address(this).balance - _userRewards);
    }

    function claimRewards() external onlyUser {
        if (unclaimedRewards() == 0) revert NothingToClaim();

        _treasuryClaim();

        emit ClaimRewards(address(this).balance);
        _userRewards = 0;

        SafeTransferLib.safeTransferETH(user, address(this).balance);
    }

    function treasuryClaim() external onlyTreasury {
        if (_calcToTreasury(address(this).balance - _userRewards) == 0) revert NothingToClaim();
        _treasuryClaim();
    }

    function _treasuryClaim() internal {
        uint256 share = address(this).balance - _userRewards;
        uint256 toTreasury = _calcToTreasury(share);
        if (toTreasury == 0) return; // Do nothing as treasury has nothing to claim.

        emit TreasuryClaim(toTreasury);
        _userRewards += share - toTreasury;

        SafeTransferLib.safeTransferETH(staking.treasury(), toTreasury);
    }

    function _calcToTreasury(uint256 amount_) internal view returns (uint256) {
        return amount_.mulDivDown(staking.performanceFee(), FEE_BASIS);
    }

    modifier onlyUser() {
        if (msg.sender != user) revert Unauthorized();
        _;
    }

    modifier onlyTreasury() {
        if (msg.sender != staking.treasury()) revert Unauthorized();
        _;
    }
}

File 9 of 10 : StakingConstants.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.13;

/// @notice Contract for shared values between Staking.sol and FeeRecipient.sol.
abstract contract StakingConstants {
    /// @notice Denominator for calculating performance fees, i.e. a `performanceFee` of 10_000 represents 100%.
    uint256 public constant FEE_BASIS = 10_000;
}

File 10 of 10 : FixedPointMathLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant MAX_UINT256 = 2**256 - 1;

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // Divide x * y by the denominator.
            z := div(mul(x, y), denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // If x * y modulo the denominator is strictly greater than 0,
            // 1 is added to round up the division of x * y by the denominator.
            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            let y := x // We start y at x, which will help us make our initial estimate.

            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // We check y >= 2^(k + 8) but shift right by k bits
            // each branch to ensure that if x >= 256, then y >= 256.
            if iszero(lt(y, 0x10000000000000000000000000000000000)) {
                y := shr(128, y)
                z := shl(64, z)
            }
            if iszero(lt(y, 0x1000000000000000000)) {
                y := shr(64, y)
                z := shl(32, z)
            }
            if iszero(lt(y, 0x10000000000)) {
                y := shr(32, y)
                z := shl(16, z)
            }
            if iszero(lt(y, 0x1000000)) {
                y := shr(16, y)
                z := shl(8, z)
            }

            // Goal was to get z*z*y within a small factor of x. More iterations could
            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).
            // We ensured y >= 256 so that the relative difference between y and y+1 is small.
            // That's not possible if x < 256 but we can just verify those cases exhaustively.

            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.

            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.

            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.

            // There is no overflow risk here since y < 2^136 after the first branch above.
            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // If x+1 is a perfect square, the Babylonian method cycles between
            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.
            z := sub(z, lt(div(x, z), z))
        }
    }

    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Mod x by y. Note this will return
            // 0 instead of reverting if y is zero.
            z := mod(x, y)
        }
    }

    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Divide x by y. Note this will return
            // 0 instead of reverting if y is zero.
            r := div(x, y)
        }
    }

    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Add 1 to x * y if x % y > 0. Note this will
            // return 0 instead of reverting if y is zero.
            z := add(gt(mod(x, y), 0), div(x, y))
        }
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"operator_","type":"address"},{"internalType":"address","name":"depositContract_","type":"address"},{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"uint256","name":"oneTimeFee_","type":"uint256"},{"internalType":"uint256","name":"performanceFee_","type":"uint256"},{"internalType":"uint256","name":"refundDelay_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BeforeRefundDelay","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"NoDeposit","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[],"name":"PendingValidators","type":"error"},{"inputs":[],"name":"SameValue","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"validators","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOperator","type":"address"},{"indexed":true,"internalType":"address","name":"newOperator","type":"address"}],"name":"NewOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"NewTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominatedOwner","type":"address"}],"name":"NominatedOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"OneTimeFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PerformanceFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"validators","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"RefundDelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bytes[]","name":"pubkeys","type":"bytes[]"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"feeRecipient","type":"address"}],"name":"UserRegistered","type":"event"},{"inputs":[],"name":"FEE_BASIS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastDepositTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nominatedOwner_","type":"address"}],"name":"nominateOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oneTimeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingValidators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refundDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"},{"internalType":"uint256","name":"validators_","type":"uint256"}],"name":"refundUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"oneTimeFee_","type":"uint256"}],"name":"setOneTimeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator_","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"performanceFee_","type":"uint256"}],"name":"setPerformanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"refundDelay_","type":"uint256"}],"name":"setRefundDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"treasury_","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"},{"components":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"deposit_data_root","type":"bytes32"}],"internalType":"struct IStaking.DepositData[]","name":"data_","type":"tuple[]"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalPendingValidators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a060405260016000553480156200001657600080fd5b50604051620021fe380380620021fe833981016040819052620000399162000318565b86866001600160a01b038216620000635760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381166200008b5760405163d92e233d60e01b815260040160405180910390fd5b6040516001600160a01b038316906000907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a36040516001600160a01b038216906000907ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c908290a3600180546001600160a01b03199081166001600160a01b0394851617909155600380549091169183169190911790558516620001465760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0385166080526200015e846200018c565b6200016983620001e8565b620001748262000246565b6200017f81620002a0565b5050505050505062000392565b6004546040516001600160a01b038084169216907f567657fa3f286518b318f4a29870674f433f622fdfc819691acb13105b22822590600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b600854156200020a57604051633d4366cb60e01b815260040160405180910390fd5b60058190556040518181527fa9be77e1a84a70ba86813c7f754603b280ffbeae336e020f99450b6f7da19958906020015b60405180910390a150565b6127108111156200026a5760405163162908e360e11b815260040160405180910390fd5b60068190556040518181527fceb20f7f0b19335681096ee1eaa9bb2a6ef5a9a69ba48b6b488e7b7eff2ef04d906020016200023b565b62093a80811115620002c55760405163162908e360e11b815260040160405180910390fd5b60078190556040518181527f829115d20ef76cd57820d0bbc4775febaa93deae0e86c936cde129d1349f676e906020016200023b565b80516001600160a01b03811681146200031357600080fd5b919050565b600080600080600080600060e0888a0312156200033457600080fd5b6200033f88620002fb565b96506200034f60208901620002fb565b95506200035f60408901620002fb565b94506200036f60608901620002fb565b93506080880151925060a0880151915060c0880151905092959891949750929550565b608051611e49620003b56000396000818161049f01526109970152611e496000f3fe6080604052600436106101a05760003560e01c806370897b23116100ec578063b3ab15fb1161008a578063eea758f111610064578063eea758f1146104c1578063f0f44260146104e1578063f340fa0114610501578063f8245bca1461051457600080fd5b8063b3ab15fb1461044d578063e1ba24261461046d578063e94ad65b1461048d57600080fd5b80638456cb59116100c65780638456cb59146103ec5780638686ebcc1461040157806387788782146104175780638da5cb5b1461042d57600080fd5b806370897b231461039757806379ba5097146103b75780637bfa9819146103cc57600080fd5b806353a47bb7116101595780635b94db27116101335780635b94db27146102f95780635c975abb1461031957806361d027b31461034a578063655d8dec1461036a57600080fd5b806353a47bb7146102a4578063570ca735146102c4578063590e1ae3146102e457600080fd5b8063038defd7146101b5578063047f48b8146102085780632dd00477146102435780633e602b4c146102595780633f4ba83a1461026f5780634e81f4971461028457600080fd5b366101b0576101ae3361052a565b005b600080fd5b3480156101c157600080fd5b506101eb6101d03660046112f6565b6009602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021457600080fd5b506102356102233660046112f6565b600a6020526000908152604090205481565b6040519081526020016101ff565b34801561024f57600080fd5b5061023560085481565b34801561026557600080fd5b5061023560075481565b34801561027b57600080fd5b506101ae6107b8565b34801561029057600080fd5b506101ae61029f3660046113f8565b610805565b3480156102b057600080fd5b506002546101eb906001600160a01b031681565b3480156102d057600080fd5b506003546101eb906001600160a01b031681565b3480156102f057600080fd5b506101ae610ae0565b34801561030557600080fd5b506101ae6103143660046112f6565b610b7d565b34801561032557600080fd5b5060035461033a90600160a01b900460ff1681565b60405190151581526020016101ff565b34801561035657600080fd5b506004546101eb906001600160a01b031681565b34801561037657600080fd5b506102356103853660046112f6565b600b6020526000908152604090205481565b3480156103a357600080fd5b506101ae6103b2366004611530565b610bfd565b3480156103c357600080fd5b506101ae610c55565b3480156103d857600080fd5b506101ae6103e7366004611530565b610ce5565b3480156103f857600080fd5b506101ae610d3a565b34801561040d57600080fd5b5061023561271081565b34801561042357600080fd5b5061023560065481565b34801561043957600080fd5b506001546101eb906001600160a01b031681565b34801561045957600080fd5b506101ae6104683660046112f6565b610d85565b34801561047957600080fd5b506101ae610488366004611530565b610e32565b34801561049957600080fd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104cd57600080fd5b506101ae6104dc366004611549565b610e87565b3480156104ed57600080fd5b506101ae6104fc3660046112f6565b610ed8565b6101ae61050f3660046112f6565b610f61565b34801561052057600080fd5b5061023560055481565b600354600160a01b900460ff161561055557604051631309a56360e01b815260040160405180910390fd5b6000546001146105995760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60026000556001600160a01b0381166105c55760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a6020526040902054156105fc57604051633d4366cb60e01b815260040160405180910390fd5b60006005546801bc16d674ec8000006106159190611589565b905034158061062c575061062981346115b7565b15155b1561064a5760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038281166000908152600960205260409020541661070057600082604051610678906112cd565b6001600160a01b039091168152602001604051809103906000f0801580156106a4573d6000803e3d6000fd5b506001600160a01b0384811660008181526009602052604080822080546001600160a01b031916948616948517905551939450919290917f2138b9314634f9fdd5e49bee3eaf17ca557b6637524d0db759711c3bfcd3d85091a3505b600061070c82346115cb565b6001600160a01b0384166000908152600a6020526040812080549293508392909190610739908490611589565b9250508190555080600860008282546107529190611589565b90915550506001600160a01b0383166000818152600b6020526040908190204290555133907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906107a69085815260200190565b60405180910390a35050600160005550565b6001546001600160a01b031633148015906107de57506003546001600160a01b03163314155b156107fb576040516282b42960e81b815260040160405180910390fd5b610803610f6a565b565b6001546001600160a01b0316331480159061082b57506003546001600160a01b03163314155b15610848576040516282b42960e81b815260040160405180910390fd5b8051600081900361086c5760405163251f56a160e21b815260040160405180910390fd5b6001600160a01b0383166000908152600a6020526040812080548392906108949084906115df565b9250508190555080600860008282546108ad91906115df565b9091555050600554156108dd576004546005546108dd916001600160a01b0316906108d890846115f6565b610fce565b60008167ffffffffffffffff8111156108f8576108f8611318565b60405190808252806020026020018201604052801561092b57816020015b60608152602001906001900390816109165790505b50905060005b82811015610a9857600084828151811061094d5761094d611615565b6020908102919091018101515160408051600160f81b93810193909352600060218401526bffffffffffffffffffffffff1960608a901b16602c8401529092506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916322895118916801bc16d674ec800000918591016040516020818303038152906040528987815181106109ed576109ed611615565b6020026020010151602001518a8881518110610a0b57610a0b611615565b6020026020010151604001516040518663ffffffff1660e01b8152600401610a369493929190611678565b6000604051808303818588803b158015610a4f57600080fd5b505af1158015610a63573d6000803e3d6000fd5b505050505080838381518110610a7b57610a7b611615565b60200260200101819052505080610a91906116c3565b9050610931565b50836001600160a01b03167fddb1ded6779e003e6e258c4bedfe8ab9f83cfa5390e730b6c0c5e5e85d96082a82604051610ad291906116dc565b60405180910390a250505050565b600054600114610b1f5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610590565b60026000908155338152600a6020908152604080832054600754600b909352922054610b4b9190611589565b421015610b6b576040516380a3a69f60e01b815260040160405180910390fd5b610b753382611024565b506001600055565b6001546001600160a01b03163314610ba7576040516282b42960e81b815260040160405180910390fd5b6040516001600160a01b038216907f0b6876d59e2e3c1a7e4bb6dd95d7ef3a8a17927d9f55c43cc4358973f6b97e1290600090a2600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610c27576040516282b42960e81b815260040160405180910390fd5b6006548103610c495760405163c23f6ccb60e01b815260040160405180910390fd5b610c52816110f8565b50565b6002546001600160a01b03163314610c7f576040516282b42960e81b815260040160405180910390fd5b6002546001546040516001600160a01b0392831692909116907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236490600090a360028054600180546001600160a01b03199081166001600160a01b03841617909155169055565b6001546001600160a01b03163314610d0f576040516282b42960e81b815260040160405180910390fd5b6007548103610d315760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611157565b6001546001600160a01b03163314801590610d6057506003546001600160a01b03163314155b15610d7d576040516282b42960e81b815260040160405180910390fd5b6108036111b0565b6001546001600160a01b03163314610daf576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610dd65760405163d92e233d60e01b815260040160405180910390fd5b6003546040516001600160a01b038084169216907ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c90600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610e5c576040516282b42960e81b815260040160405180910390fd5b6005548103610e7e5760405163c23f6ccb60e01b815260040160405180910390fd5b610c528161121b565b6001546001600160a01b03163314801590610ead57506003546001600160a01b03163314155b15610eca576040516282b42960e81b815260040160405180910390fd5b610ed48282611024565b5050565b6001546001600160a01b03163314610f02576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610f295760405163d92e233d60e01b815260040160405180910390fd5b6004546001600160a01b0390811690821603610f585760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611271565b610c528161052a565b600354600160a01b900460ff16610f9457604051636cd6020160e01b815260040160405180910390fd5b6003805460ff60a01b1916905560405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90600090a2565b600080600080600085875af190508061101f5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610590565b505050565b8060000361104557604051633a6a68b160e01b815260040160405180910390fd5b6001600160a01b0382166000908152600a60205260408120805483929061106d9084906115df565b92505081905550806008600082825461108691906115df565b90915550506005546110b19083906110a7906801bc16d674ec800000611589565b6108d890846115f6565b816001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d826040516110ec91815260200190565b60405180910390a25050565b61271081111561111b5760405163162908e360e11b815260040160405180910390fd5b60068190556040518181527fceb20f7f0b19335681096ee1eaa9bb2a6ef5a9a69ba48b6b488e7b7eff2ef04d906020015b60405180910390a150565b62093a8081111561117b5760405163162908e360e11b815260040160405180910390fd5b60078190556040518181527f829115d20ef76cd57820d0bbc4775febaa93deae0e86c936cde129d1349f676e9060200161114c565b600354600160a01b900460ff16156111db57604051631309a56360e01b815260040160405180910390fd5b6003805460ff60a01b1916600160a01b17905560405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890600090a2565b6008541561123c57604051633d4366cb60e01b815260040160405180910390fd5b60058190556040518181527fa9be77e1a84a70ba86813c7f754603b280ffbeae336e020f99450b6f7da199589060200161114c565b6004546040516001600160a01b038084169216907f567657fa3f286518b318f4a29870674f433f622fdfc819691acb13105b22822590600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b6106d58061173f83390190565b80356001600160a01b03811681146112f157600080fd5b919050565b60006020828403121561130857600080fd5b611311826112da565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561135157611351611318565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561138057611380611318565b604052919050565b600082601f83011261139957600080fd5b813567ffffffffffffffff8111156113b3576113b3611318565b6113c6601f8201601f1916602001611357565b8181528460208386010111156113db57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561140b57600080fd5b611414836112da565b915060208084013567ffffffffffffffff8082111561143257600080fd5b818601915086601f83011261144657600080fd5b81358181111561145857611458611318565b8060051b611467858201611357565b918252838101850191858101908a84111561148157600080fd5b86860192505b8383101561151f5782358581111561149f5760008081fd5b86016060818d03601f19018113156114b75760008081fd5b6114bf61132e565b89830135888111156114d15760008081fd5b6114df8f8c83870101611388565b8252506040830135888111156114f55760008081fd5b6115038f8c83870101611388565b828c015250910135604082015282529186019190860190611487565b809750505050505050509250929050565b60006020828403121561154257600080fd5b5035919050565b6000806040838503121561155c57600080fd5b611565836112da565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561159c5761159c611573565b500190565b634e487b7160e01b600052601260045260246000fd5b6000826115c6576115c66115a1565b500690565b6000826115da576115da6115a1565b500490565b6000828210156115f1576115f1611573565b500390565b600081600019048311821515161561161057611610611573565b500290565b634e487b7160e01b600052603260045260246000fd5b6000815180845260005b8181101561165157602081850181015186830182015201611635565b81811115611663576000602083870101525b50601f01601f19169290920160200192915050565b60808152600061168b608083018761162b565b828103602084015261169d818761162b565b905082810360408401526116b1818661162b565b91505082606083015295945050505050565b6000600182016116d5576116d5611573565b5060010190565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561173157603f1988860301845261171f85835161162b565b94509285019290850190600101611703565b509297965050505050505056fe60c060405234801561001057600080fd5b506040516106d53803806106d583398101604081905261002f91610044565b336080526001600160a01b031660a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a05161061b6100ba6000396000818160df0152818161015a0152610203015260008181608e0152818161022c015281816103be01526104a9015261061b6000f3fe6080604052600436106100595760003560e01c8063372500ab146100655780634cf088d91461007c5780634f8632ba146100cd5780635475a7be146101015780638686ebcc14610116578063f85f91b41461013a57600080fd5b3661006057005b600080fd5b34801561007157600080fd5b5061007a61014f565b005b34801561008857600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d957600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b34801561010d57600080fd5b5061007a61022a565b34801561012257600080fd5b5061012c61271081565b6040519081526020016100c4565b34801561014657600080fd5b5061012c61031a565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610197576040516282b42960e81b815260040160405180910390fd5b61019f61031a565b6000036101bf576040516312d37ee560e31b815260040160405180910390fd5b6101c761033c565b6040514781527fbacfa9662d479c707dae707c358323f0c7711ef382007957dc9935e629da36b29060200160405180910390a1600080556102287f000000000000000000000000000000000000000000000000000000000000000047610448565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac9190610557565b6001600160a01b0316336001600160a01b0316146102dc576040516282b42960e81b815260040160405180910390fd5b6102f2600054476102ed919061059d565b6104a2565b600003610312576040516312d37ee560e31b815260040160405180910390fd5b61022861033c565b600061032d600054476102ed919061059d565b610337904761059d565b905090565b6000805461034a904761059d565b90506000610357826104a2565b905080600003610365575050565b6040518181527fb9197c6b8e21274bd1e2d9c956a88af5cfee510f630fab3f046300f88b4223619060200160405180910390a16103a2818361059d565b6000808282546103b291906105b4565b925050819055506104447f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190610557565b82610448565b5050565b600080600080600085875af190508061049d5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b60006105337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663877887826040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906105cc565b8390612710610539565b92915050565b600082600019048411830215820261055057600080fd5b5091020490565b60006020828403121561056957600080fd5b81516001600160a01b038116811461058057600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156105af576105af610587565b500390565b600082198211156105c7576105c7610587565b500190565b6000602082840312156105de57600080fd5b505191905056fea2646970667358221220cf8c68186eb03b0415c4e1a451bafa8213a95358dfe1202ce8aa3ce23100036364736f6c634300080d0033a2646970667358221220183a0c36c9591a073c3ab6214384e8867e8f14be98c4c2bee35920d8082b228164736f6c634300080d0033000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0000000000000000000000000ff50ed3d0ec03ac01d4c79aad74928bff48a7b2b000000000000000000000000abc46876f2831554a154af0585f98a66832a68b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000003f480

Deployed Bytecode

0x6080604052600436106101a05760003560e01c806370897b23116100ec578063b3ab15fb1161008a578063eea758f111610064578063eea758f1146104c1578063f0f44260146104e1578063f340fa0114610501578063f8245bca1461051457600080fd5b8063b3ab15fb1461044d578063e1ba24261461046d578063e94ad65b1461048d57600080fd5b80638456cb59116100c65780638456cb59146103ec5780638686ebcc1461040157806387788782146104175780638da5cb5b1461042d57600080fd5b806370897b231461039757806379ba5097146103b75780637bfa9819146103cc57600080fd5b806353a47bb7116101595780635b94db27116101335780635b94db27146102f95780635c975abb1461031957806361d027b31461034a578063655d8dec1461036a57600080fd5b806353a47bb7146102a4578063570ca735146102c4578063590e1ae3146102e457600080fd5b8063038defd7146101b5578063047f48b8146102085780632dd00477146102435780633e602b4c146102595780633f4ba83a1461026f5780634e81f4971461028457600080fd5b366101b0576101ae3361052a565b005b600080fd5b3480156101c157600080fd5b506101eb6101d03660046112f6565b6009602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021457600080fd5b506102356102233660046112f6565b600a6020526000908152604090205481565b6040519081526020016101ff565b34801561024f57600080fd5b5061023560085481565b34801561026557600080fd5b5061023560075481565b34801561027b57600080fd5b506101ae6107b8565b34801561029057600080fd5b506101ae61029f3660046113f8565b610805565b3480156102b057600080fd5b506002546101eb906001600160a01b031681565b3480156102d057600080fd5b506003546101eb906001600160a01b031681565b3480156102f057600080fd5b506101ae610ae0565b34801561030557600080fd5b506101ae6103143660046112f6565b610b7d565b34801561032557600080fd5b5060035461033a90600160a01b900460ff1681565b60405190151581526020016101ff565b34801561035657600080fd5b506004546101eb906001600160a01b031681565b34801561037657600080fd5b506102356103853660046112f6565b600b6020526000908152604090205481565b3480156103a357600080fd5b506101ae6103b2366004611530565b610bfd565b3480156103c357600080fd5b506101ae610c55565b3480156103d857600080fd5b506101ae6103e7366004611530565b610ce5565b3480156103f857600080fd5b506101ae610d3a565b34801561040d57600080fd5b5061023561271081565b34801561042357600080fd5b5061023560065481565b34801561043957600080fd5b506001546101eb906001600160a01b031681565b34801561045957600080fd5b506101ae6104683660046112f6565b610d85565b34801561047957600080fd5b506101ae610488366004611530565b610e32565b34801561049957600080fd5b506101eb7f000000000000000000000000ff50ed3d0ec03ac01d4c79aad74928bff48a7b2b81565b3480156104cd57600080fd5b506101ae6104dc366004611549565b610e87565b3480156104ed57600080fd5b506101ae6104fc3660046112f6565b610ed8565b6101ae61050f3660046112f6565b610f61565b34801561052057600080fd5b5061023560055481565b600354600160a01b900460ff161561055557604051631309a56360e01b815260040160405180910390fd5b6000546001146105995760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60026000556001600160a01b0381166105c55760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a6020526040902054156105fc57604051633d4366cb60e01b815260040160405180910390fd5b60006005546801bc16d674ec8000006106159190611589565b905034158061062c575061062981346115b7565b15155b1561064a5760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038281166000908152600960205260409020541661070057600082604051610678906112cd565b6001600160a01b039091168152602001604051809103906000f0801580156106a4573d6000803e3d6000fd5b506001600160a01b0384811660008181526009602052604080822080546001600160a01b031916948616948517905551939450919290917f2138b9314634f9fdd5e49bee3eaf17ca557b6637524d0db759711c3bfcd3d85091a3505b600061070c82346115cb565b6001600160a01b0384166000908152600a6020526040812080549293508392909190610739908490611589565b9250508190555080600860008282546107529190611589565b90915550506001600160a01b0383166000818152600b6020526040908190204290555133907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906107a69085815260200190565b60405180910390a35050600160005550565b6001546001600160a01b031633148015906107de57506003546001600160a01b03163314155b156107fb576040516282b42960e81b815260040160405180910390fd5b610803610f6a565b565b6001546001600160a01b0316331480159061082b57506003546001600160a01b03163314155b15610848576040516282b42960e81b815260040160405180910390fd5b8051600081900361086c5760405163251f56a160e21b815260040160405180910390fd5b6001600160a01b0383166000908152600a6020526040812080548392906108949084906115df565b9250508190555080600860008282546108ad91906115df565b9091555050600554156108dd576004546005546108dd916001600160a01b0316906108d890846115f6565b610fce565b60008167ffffffffffffffff8111156108f8576108f8611318565b60405190808252806020026020018201604052801561092b57816020015b60608152602001906001900390816109165790505b50905060005b82811015610a9857600084828151811061094d5761094d611615565b6020908102919091018101515160408051600160f81b93810193909352600060218401526bffffffffffffffffffffffff1960608a901b16602c8401529092506001600160a01b037f000000000000000000000000ff50ed3d0ec03ac01d4c79aad74928bff48a7b2b16916322895118916801bc16d674ec800000918591016040516020818303038152906040528987815181106109ed576109ed611615565b6020026020010151602001518a8881518110610a0b57610a0b611615565b6020026020010151604001516040518663ffffffff1660e01b8152600401610a369493929190611678565b6000604051808303818588803b158015610a4f57600080fd5b505af1158015610a63573d6000803e3d6000fd5b505050505080838381518110610a7b57610a7b611615565b60200260200101819052505080610a91906116c3565b9050610931565b50836001600160a01b03167fddb1ded6779e003e6e258c4bedfe8ab9f83cfa5390e730b6c0c5e5e85d96082a82604051610ad291906116dc565b60405180910390a250505050565b600054600114610b1f5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610590565b60026000908155338152600a6020908152604080832054600754600b909352922054610b4b9190611589565b421015610b6b576040516380a3a69f60e01b815260040160405180910390fd5b610b753382611024565b506001600055565b6001546001600160a01b03163314610ba7576040516282b42960e81b815260040160405180910390fd5b6040516001600160a01b038216907f0b6876d59e2e3c1a7e4bb6dd95d7ef3a8a17927d9f55c43cc4358973f6b97e1290600090a2600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610c27576040516282b42960e81b815260040160405180910390fd5b6006548103610c495760405163c23f6ccb60e01b815260040160405180910390fd5b610c52816110f8565b50565b6002546001600160a01b03163314610c7f576040516282b42960e81b815260040160405180910390fd5b6002546001546040516001600160a01b0392831692909116907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236490600090a360028054600180546001600160a01b03199081166001600160a01b03841617909155169055565b6001546001600160a01b03163314610d0f576040516282b42960e81b815260040160405180910390fd5b6007548103610d315760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611157565b6001546001600160a01b03163314801590610d6057506003546001600160a01b03163314155b15610d7d576040516282b42960e81b815260040160405180910390fd5b6108036111b0565b6001546001600160a01b03163314610daf576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610dd65760405163d92e233d60e01b815260040160405180910390fd5b6003546040516001600160a01b038084169216907ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c90600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610e5c576040516282b42960e81b815260040160405180910390fd5b6005548103610e7e5760405163c23f6ccb60e01b815260040160405180910390fd5b610c528161121b565b6001546001600160a01b03163314801590610ead57506003546001600160a01b03163314155b15610eca576040516282b42960e81b815260040160405180910390fd5b610ed48282611024565b5050565b6001546001600160a01b03163314610f02576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610f295760405163d92e233d60e01b815260040160405180910390fd5b6004546001600160a01b0390811690821603610f585760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611271565b610c528161052a565b600354600160a01b900460ff16610f9457604051636cd6020160e01b815260040160405180910390fd5b6003805460ff60a01b1916905560405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90600090a2565b600080600080600085875af190508061101f5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610590565b505050565b8060000361104557604051633a6a68b160e01b815260040160405180910390fd5b6001600160a01b0382166000908152600a60205260408120805483929061106d9084906115df565b92505081905550806008600082825461108691906115df565b90915550506005546110b19083906110a7906801bc16d674ec800000611589565b6108d890846115f6565b816001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d826040516110ec91815260200190565b60405180910390a25050565b61271081111561111b5760405163162908e360e11b815260040160405180910390fd5b60068190556040518181527fceb20f7f0b19335681096ee1eaa9bb2a6ef5a9a69ba48b6b488e7b7eff2ef04d906020015b60405180910390a150565b62093a8081111561117b5760405163162908e360e11b815260040160405180910390fd5b60078190556040518181527f829115d20ef76cd57820d0bbc4775febaa93deae0e86c936cde129d1349f676e9060200161114c565b600354600160a01b900460ff16156111db57604051631309a56360e01b815260040160405180910390fd5b6003805460ff60a01b1916600160a01b17905560405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890600090a2565b6008541561123c57604051633d4366cb60e01b815260040160405180910390fd5b60058190556040518181527fa9be77e1a84a70ba86813c7f754603b280ffbeae336e020f99450b6f7da199589060200161114c565b6004546040516001600160a01b038084169216907f567657fa3f286518b318f4a29870674f433f622fdfc819691acb13105b22822590600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b6106d58061173f83390190565b80356001600160a01b03811681146112f157600080fd5b919050565b60006020828403121561130857600080fd5b611311826112da565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561135157611351611318565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561138057611380611318565b604052919050565b600082601f83011261139957600080fd5b813567ffffffffffffffff8111156113b3576113b3611318565b6113c6601f8201601f1916602001611357565b8181528460208386010111156113db57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561140b57600080fd5b611414836112da565b915060208084013567ffffffffffffffff8082111561143257600080fd5b818601915086601f83011261144657600080fd5b81358181111561145857611458611318565b8060051b611467858201611357565b918252838101850191858101908a84111561148157600080fd5b86860192505b8383101561151f5782358581111561149f5760008081fd5b86016060818d03601f19018113156114b75760008081fd5b6114bf61132e565b89830135888111156114d15760008081fd5b6114df8f8c83870101611388565b8252506040830135888111156114f55760008081fd5b6115038f8c83870101611388565b828c015250910135604082015282529186019190860190611487565b809750505050505050509250929050565b60006020828403121561154257600080fd5b5035919050565b6000806040838503121561155c57600080fd5b611565836112da565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561159c5761159c611573565b500190565b634e487b7160e01b600052601260045260246000fd5b6000826115c6576115c66115a1565b500690565b6000826115da576115da6115a1565b500490565b6000828210156115f1576115f1611573565b500390565b600081600019048311821515161561161057611610611573565b500290565b634e487b7160e01b600052603260045260246000fd5b6000815180845260005b8181101561165157602081850181015186830182015201611635565b81811115611663576000602083870101525b50601f01601f19169290920160200192915050565b60808152600061168b608083018761162b565b828103602084015261169d818761162b565b905082810360408401526116b1818661162b565b91505082606083015295945050505050565b6000600182016116d5576116d5611573565b5060010190565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561173157603f1988860301845261171f85835161162b565b94509285019290850190600101611703565b509297965050505050505056fe60c060405234801561001057600080fd5b506040516106d53803806106d583398101604081905261002f91610044565b336080526001600160a01b031660a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a05161061b6100ba6000396000818160df0152818161015a0152610203015260008181608e0152818161022c015281816103be01526104a9015261061b6000f3fe6080604052600436106100595760003560e01c8063372500ab146100655780634cf088d91461007c5780634f8632ba146100cd5780635475a7be146101015780638686ebcc14610116578063f85f91b41461013a57600080fd5b3661006057005b600080fd5b34801561007157600080fd5b5061007a61014f565b005b34801561008857600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d957600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b34801561010d57600080fd5b5061007a61022a565b34801561012257600080fd5b5061012c61271081565b6040519081526020016100c4565b34801561014657600080fd5b5061012c61031a565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610197576040516282b42960e81b815260040160405180910390fd5b61019f61031a565b6000036101bf576040516312d37ee560e31b815260040160405180910390fd5b6101c761033c565b6040514781527fbacfa9662d479c707dae707c358323f0c7711ef382007957dc9935e629da36b29060200160405180910390a1600080556102287f000000000000000000000000000000000000000000000000000000000000000047610448565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac9190610557565b6001600160a01b0316336001600160a01b0316146102dc576040516282b42960e81b815260040160405180910390fd5b6102f2600054476102ed919061059d565b6104a2565b600003610312576040516312d37ee560e31b815260040160405180910390fd5b61022861033c565b600061032d600054476102ed919061059d565b610337904761059d565b905090565b6000805461034a904761059d565b90506000610357826104a2565b905080600003610365575050565b6040518181527fb9197c6b8e21274bd1e2d9c956a88af5cfee510f630fab3f046300f88b4223619060200160405180910390a16103a2818361059d565b6000808282546103b291906105b4565b925050819055506104447f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190610557565b82610448565b5050565b600080600080600085875af190508061049d5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b60006105337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663877887826040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906105cc565b8390612710610539565b92915050565b600082600019048411830215820261055057600080fd5b5091020490565b60006020828403121561056957600080fd5b81516001600160a01b038116811461058057600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156105af576105af610587565b500390565b600082198211156105c7576105c7610587565b500190565b6000602082840312156105de57600080fd5b505191905056fea2646970667358221220cf8c68186eb03b0415c4e1a451bafa8213a95358dfe1202ce8aa3ce23100036364736f6c634300080d0033a2646970667358221220183a0c36c9591a073c3ab6214384e8867e8f14be98c4c2bee35920d8082b228164736f6c634300080d0033

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

000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0000000000000000000000000ff50ed3d0ec03ac01d4c79aad74928bff48a7b2b000000000000000000000000abc46876f2831554a154af0585f98a66832a68b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000003f480

-----Decoded View---------------
Arg [0] : owner_ (address): 0xabc46876f2831554a154Af0585F98A66832A68B0
Arg [1] : operator_ (address): 0xabc46876f2831554a154Af0585F98A66832A68B0
Arg [2] : depositContract_ (address): 0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b
Arg [3] : treasury_ (address): 0xabc46876f2831554a154Af0585F98A66832A68B0
Arg [4] : oneTimeFee_ (uint256): 0
Arg [5] : performanceFee_ (uint256): 100
Arg [6] : refundDelay_ (uint256): 259200

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0
Arg [1] : 000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0
Arg [2] : 000000000000000000000000ff50ed3d0ec03ac01d4c79aad74928bff48a7b2b
Arg [3] : 000000000000000000000000abc46876f2831554a154af0585f98a66832a68b0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [6] : 000000000000000000000000000000000000000000000000000000000003f480


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.