ETH Price: $2,688.95 (-2.31%)

Contract

0xFB4022E94460ae7bd4d65EcD8214fbf574740494
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Stake192172392024-02-13 6:14:35195 days ago1707804875IN
0xFB4022E9...574740494
0 ETH0.0015795421.22410719
Deposit192169682024-02-13 5:20:23195 days ago1707801623IN
0xFB4022E9...574740494
32 ETH0.0014320217.34901985
Stake190754482024-01-24 8:57:23215 days ago1706086643IN
0xFB4022E9...574740494
0 ETH0.0016311310.8570848
Deposit190754472024-01-24 8:57:11215 days ago1706086631IN
0xFB4022E9...574740494
96 ETH0.000805529.75897793
Stake190743992024-01-24 5:24:35215 days ago1706073875IN
0xFB4022E9...574740494
0 ETH0.004960469.99123422
Deposit190743982024-01-24 5:24:23215 days ago1706073863IN
0xFB4022E9...574740494
448 ETH0.00070768.57260957
Stake190605432024-01-22 6:38:23217 days ago1705905503IN
0xFB4022E9...574740494
0 ETH0.0009285612.47909023
Deposit190605422024-01-22 6:38:11217 days ago1705905491IN
0xFB4022E9...574740494
32 ETH0.005163511.05013487
Stake190546432024-01-21 10:29:11218 days ago1705832951IN
0xFB4022E9...574740494
0 ETH0.0008960212.04364015
Deposit190540942024-01-21 8:38:11218 days ago1705826291IN
0xFB4022E9...574740494
32 ETH0.004009598.58070726
Stake190389932024-01-19 6:03:23220 days ago1705644203IN
0xFB4022E9...574740494
0 ETH0.0212212121.81142959
Deposit190389922024-01-19 6:03:11220 days ago1705644191IN
0xFB4022E9...574740494
928 ETH0.0015589918.8872893
Stake190389612024-01-19 5:56:47220 days ago1705643807IN
0xFB4022E9...574740494
0 ETH0.0080243722.82953841
Deposit190389602024-01-19 5:56:35220 days ago1705643795IN
0xFB4022E9...574740494
288 ETH0.0015751819.08345246
Stake190389422024-01-19 5:52:59220 days ago1705643579IN
0xFB4022E9...574740494
0 ETH0.0015037320.20550994
Deposit190389412024-01-19 5:52:47220 days ago1705643567IN
0xFB4022E9...574740494
32 ETH0.0090346819.33463256
Nominate Owner190385152024-01-19 4:27:11220 days ago1705638431IN
0xFB4022E9...574740494
0 ETH0.0011705724.77148333
Stake190277122024-01-17 16:11:59222 days ago1705507919IN
0xFB4022E9...574740494
0 ETH0.0088329160.52886525
Deposit190277112024-01-17 16:11:47222 days ago1705507907IN
0xFB4022E9...574740494
96 ETH0.0278901159.68609705
Stake190250812024-01-17 7:21:35222 days ago1705476095IN
0xFB4022E9...574740494
0 ETH0.0038389133.52792617
Deposit190250802024-01-17 7:21:23222 days ago1705476083IN
0xFB4022E9...574740494
64 ETH0.0027000232.71090728
Stake190250732024-01-17 7:19:59222 days ago1705475999IN
0xFB4022E9...574740494
0 ETH0.0026014335.98558619
Deposit190250722024-01-17 7:19:47222 days ago1705475987IN
0xFB4022E9...574740494
32 ETH0.0157361433.6760439
Stake189745892024-01-10 5:53:59229 days ago1704866039IN
0xFB4022E9...574740494
0 ETH0.0017315123.9519491
Deposit189745882024-01-10 5:53:47229 days ago1704866027IN
0xFB4022E9...574740494
32 ETH0.0018975122.98850148
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
192172392024-02-13 6:14:35195 days ago1707804875
0xFB4022E9...574740494
32 ETH
190754482024-01-24 8:57:23215 days ago1706086643
0xFB4022E9...574740494
32 ETH
190754482024-01-24 8:57:23215 days ago1706086643
0xFB4022E9...574740494
32 ETH
190754482024-01-24 8:57:23215 days ago1706086643
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190743992024-01-24 5:24:35215 days ago1706073875
0xFB4022E9...574740494
32 ETH
190605432024-01-22 6:38:23217 days ago1705905503
0xFB4022E9...574740494
32 ETH
190605422024-01-22 6:38:11217 days ago1705905491
0xFB4022E9...574740494
 Contract Creation0 ETH
190546432024-01-21 10:29:11218 days ago1705832951
0xFB4022E9...574740494
32 ETH
190540942024-01-21 8:38:11218 days ago1705826291
0xFB4022E9...574740494
 Contract Creation0 ETH
190389932024-01-19 6:03:23220 days ago1705644203
0xFB4022E9...574740494
32 ETH
190389932024-01-19 6:03:23220 days ago1705644203
0xFB4022E9...574740494
32 ETH
190389932024-01-19 6:03:23220 days ago1705644203
0xFB4022E9...574740494
32 ETH
View All Internal Transactions
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
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 Security Audit

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"}]

60a060405260016000553480156200001657600080fd5b50604051620021fe380380620021fe833981016040819052620000399162000318565b86866001600160a01b038216620000635760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381166200008b5760405163d92e233d60e01b815260040160405180910390fd5b6040516001600160a01b038316906000907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a36040516001600160a01b038216906000907ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c908290a3600180546001600160a01b03199081166001600160a01b0394851617909155600380549091169183169190911790558516620001465760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0385166080526200015e846200018c565b6200016983620001e8565b620001748262000246565b6200017f81620002a0565b5050505050505062000392565b6004546040516001600160a01b038084169216907f567657fa3f286518b318f4a29870674f433f622fdfc819691acb13105b22822590600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b600854156200020a57604051633d4366cb60e01b815260040160405180910390fd5b60058190556040518181527fa9be77e1a84a70ba86813c7f754603b280ffbeae336e020f99450b6f7da19958906020015b60405180910390a150565b6127108111156200026a5760405163162908e360e11b815260040160405180910390fd5b60068190556040518181527fceb20f7f0b19335681096ee1eaa9bb2a6ef5a9a69ba48b6b488e7b7eff2ef04d906020016200023b565b62093a80811115620002c55760405163162908e360e11b815260040160405180910390fd5b60078190556040518181527f829115d20ef76cd57820d0bbc4775febaa93deae0e86c936cde129d1349f676e906020016200023b565b80516001600160a01b03811681146200031357600080fd5b919050565b600080600080600080600060e0888a0312156200033457600080fd5b6200033f88620002fb565b96506200034f60208901620002fb565b95506200035f60408901620002fb565b94506200036f60608901620002fb565b93506080880151925060a0880151915060c0880151905092959891949750929550565b608051611e49620003b56000396000818161049f01526109970152611e496000f3fe6080604052600436106101a05760003560e01c806370897b23116100ec578063b3ab15fb1161008a578063eea758f111610064578063eea758f1146104c1578063f0f44260146104e1578063f340fa0114610501578063f8245bca1461051457600080fd5b8063b3ab15fb1461044d578063e1ba24261461046d578063e94ad65b1461048d57600080fd5b80638456cb59116100c65780638456cb59146103ec5780638686ebcc1461040157806387788782146104175780638da5cb5b1461042d57600080fd5b806370897b231461039757806379ba5097146103b75780637bfa9819146103cc57600080fd5b806353a47bb7116101595780635b94db27116101335780635b94db27146102f95780635c975abb1461031957806361d027b31461034a578063655d8dec1461036a57600080fd5b806353a47bb7146102a4578063570ca735146102c4578063590e1ae3146102e457600080fd5b8063038defd7146101b5578063047f48b8146102085780632dd00477146102435780633e602b4c146102595780633f4ba83a1461026f5780634e81f4971461028457600080fd5b366101b0576101ae3361052a565b005b600080fd5b3480156101c157600080fd5b506101eb6101d03660046112f6565b6009602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021457600080fd5b506102356102233660046112f6565b600a6020526000908152604090205481565b6040519081526020016101ff565b34801561024f57600080fd5b5061023560085481565b34801561026557600080fd5b5061023560075481565b34801561027b57600080fd5b506101ae6107b8565b34801561029057600080fd5b506101ae61029f3660046113f8565b610805565b3480156102b057600080fd5b506002546101eb906001600160a01b031681565b3480156102d057600080fd5b506003546101eb906001600160a01b031681565b3480156102f057600080fd5b506101ae610ae0565b34801561030557600080fd5b506101ae6103143660046112f6565b610b7d565b34801561032557600080fd5b5060035461033a90600160a01b900460ff1681565b60405190151581526020016101ff565b34801561035657600080fd5b506004546101eb906001600160a01b031681565b34801561037657600080fd5b506102356103853660046112f6565b600b6020526000908152604090205481565b3480156103a357600080fd5b506101ae6103b2366004611530565b610bfd565b3480156103c357600080fd5b506101ae610c55565b3480156103d857600080fd5b506101ae6103e7366004611530565b610ce5565b3480156103f857600080fd5b506101ae610d3a565b34801561040d57600080fd5b5061023561271081565b34801561042357600080fd5b5061023560065481565b34801561043957600080fd5b506001546101eb906001600160a01b031681565b34801561045957600080fd5b506101ae6104683660046112f6565b610d85565b34801561047957600080fd5b506101ae610488366004611530565b610e32565b34801561049957600080fd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104cd57600080fd5b506101ae6104dc366004611549565b610e87565b3480156104ed57600080fd5b506101ae6104fc3660046112f6565b610ed8565b6101ae61050f3660046112f6565b610f61565b34801561052057600080fd5b5061023560055481565b600354600160a01b900460ff161561055557604051631309a56360e01b815260040160405180910390fd5b6000546001146105995760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60026000556001600160a01b0381166105c55760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a6020526040902054156105fc57604051633d4366cb60e01b815260040160405180910390fd5b60006005546801bc16d674ec8000006106159190611589565b905034158061062c575061062981346115b7565b15155b1561064a5760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038281166000908152600960205260409020541661070057600082604051610678906112cd565b6001600160a01b039091168152602001604051809103906000f0801580156106a4573d6000803e3d6000fd5b506001600160a01b0384811660008181526009602052604080822080546001600160a01b031916948616948517905551939450919290917f2138b9314634f9fdd5e49bee3eaf17ca557b6637524d0db759711c3bfcd3d85091a3505b600061070c82346115cb565b6001600160a01b0384166000908152600a6020526040812080549293508392909190610739908490611589565b9250508190555080600860008282546107529190611589565b90915550506001600160a01b0383166000818152600b6020526040908190204290555133907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906107a69085815260200190565b60405180910390a35050600160005550565b6001546001600160a01b031633148015906107de57506003546001600160a01b03163314155b156107fb576040516282b42960e81b815260040160405180910390fd5b610803610f6a565b565b6001546001600160a01b0316331480159061082b57506003546001600160a01b03163314155b15610848576040516282b42960e81b815260040160405180910390fd5b8051600081900361086c5760405163251f56a160e21b815260040160405180910390fd5b6001600160a01b0383166000908152600a6020526040812080548392906108949084906115df565b9250508190555080600860008282546108ad91906115df565b9091555050600554156108dd576004546005546108dd916001600160a01b0316906108d890846115f6565b610fce565b60008167ffffffffffffffff8111156108f8576108f8611318565b60405190808252806020026020018201604052801561092b57816020015b60608152602001906001900390816109165790505b50905060005b82811015610a9857600084828151811061094d5761094d611615565b6020908102919091018101515160408051600160f81b93810193909352600060218401526bffffffffffffffffffffffff1960608a901b16602c8401529092506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916322895118916801bc16d674ec800000918591016040516020818303038152906040528987815181106109ed576109ed611615565b6020026020010151602001518a8881518110610a0b57610a0b611615565b6020026020010151604001516040518663ffffffff1660e01b8152600401610a369493929190611678565b6000604051808303818588803b158015610a4f57600080fd5b505af1158015610a63573d6000803e3d6000fd5b505050505080838381518110610a7b57610a7b611615565b60200260200101819052505080610a91906116c3565b9050610931565b50836001600160a01b03167fddb1ded6779e003e6e258c4bedfe8ab9f83cfa5390e730b6c0c5e5e85d96082a82604051610ad291906116dc565b60405180910390a250505050565b600054600114610b1f5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610590565b60026000908155338152600a6020908152604080832054600754600b909352922054610b4b9190611589565b421015610b6b576040516380a3a69f60e01b815260040160405180910390fd5b610b753382611024565b506001600055565b6001546001600160a01b03163314610ba7576040516282b42960e81b815260040160405180910390fd5b6040516001600160a01b038216907f0b6876d59e2e3c1a7e4bb6dd95d7ef3a8a17927d9f55c43cc4358973f6b97e1290600090a2600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610c27576040516282b42960e81b815260040160405180910390fd5b6006548103610c495760405163c23f6ccb60e01b815260040160405180910390fd5b610c52816110f8565b50565b6002546001600160a01b03163314610c7f576040516282b42960e81b815260040160405180910390fd5b6002546001546040516001600160a01b0392831692909116907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236490600090a360028054600180546001600160a01b03199081166001600160a01b03841617909155169055565b6001546001600160a01b03163314610d0f576040516282b42960e81b815260040160405180910390fd5b6007548103610d315760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611157565b6001546001600160a01b03163314801590610d6057506003546001600160a01b03163314155b15610d7d576040516282b42960e81b815260040160405180910390fd5b6108036111b0565b6001546001600160a01b03163314610daf576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610dd65760405163d92e233d60e01b815260040160405180910390fd5b6003546040516001600160a01b038084169216907ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c90600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610e5c576040516282b42960e81b815260040160405180910390fd5b6005548103610e7e5760405163c23f6ccb60e01b815260040160405180910390fd5b610c528161121b565b6001546001600160a01b03163314801590610ead57506003546001600160a01b03163314155b15610eca576040516282b42960e81b815260040160405180910390fd5b610ed48282611024565b5050565b6001546001600160a01b03163314610f02576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610f295760405163d92e233d60e01b815260040160405180910390fd5b6004546001600160a01b0390811690821603610f585760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611271565b610c528161052a565b600354600160a01b900460ff16610f9457604051636cd6020160e01b815260040160405180910390fd5b6003805460ff60a01b1916905560405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90600090a2565b600080600080600085875af190508061101f5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610590565b505050565b8060000361104557604051633a6a68b160e01b815260040160405180910390fd5b6001600160a01b0382166000908152600a60205260408120805483929061106d9084906115df565b92505081905550806008600082825461108691906115df565b90915550506005546110b19083906110a7906801bc16d674ec800000611589565b6108d890846115f6565b816001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d826040516110ec91815260200190565b60405180910390a25050565b61271081111561111b5760405163162908e360e11b815260040160405180910390fd5b60068190556040518181527fceb20f7f0b19335681096ee1eaa9bb2a6ef5a9a69ba48b6b488e7b7eff2ef04d906020015b60405180910390a150565b62093a8081111561117b5760405163162908e360e11b815260040160405180910390fd5b60078190556040518181527f829115d20ef76cd57820d0bbc4775febaa93deae0e86c936cde129d1349f676e9060200161114c565b600354600160a01b900460ff16156111db57604051631309a56360e01b815260040160405180910390fd5b6003805460ff60a01b1916600160a01b17905560405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890600090a2565b6008541561123c57604051633d4366cb60e01b815260040160405180910390fd5b60058190556040518181527fa9be77e1a84a70ba86813c7f754603b280ffbeae336e020f99450b6f7da199589060200161114c565b6004546040516001600160a01b038084169216907f567657fa3f286518b318f4a29870674f433f622fdfc819691acb13105b22822590600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b6106d58061173f83390190565b80356001600160a01b03811681146112f157600080fd5b919050565b60006020828403121561130857600080fd5b611311826112da565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561135157611351611318565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561138057611380611318565b604052919050565b600082601f83011261139957600080fd5b813567ffffffffffffffff8111156113b3576113b3611318565b6113c6601f8201601f1916602001611357565b8181528460208386010111156113db57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561140b57600080fd5b611414836112da565b915060208084013567ffffffffffffffff8082111561143257600080fd5b818601915086601f83011261144657600080fd5b81358181111561145857611458611318565b8060051b611467858201611357565b918252838101850191858101908a84111561148157600080fd5b86860192505b8383101561151f5782358581111561149f5760008081fd5b86016060818d03601f19018113156114b75760008081fd5b6114bf61132e565b89830135888111156114d15760008081fd5b6114df8f8c83870101611388565b8252506040830135888111156114f55760008081fd5b6115038f8c83870101611388565b828c015250910135604082015282529186019190860190611487565b809750505050505050509250929050565b60006020828403121561154257600080fd5b5035919050565b6000806040838503121561155c57600080fd5b611565836112da565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561159c5761159c611573565b500190565b634e487b7160e01b600052601260045260246000fd5b6000826115c6576115c66115a1565b500690565b6000826115da576115da6115a1565b500490565b6000828210156115f1576115f1611573565b500390565b600081600019048311821515161561161057611610611573565b500290565b634e487b7160e01b600052603260045260246000fd5b6000815180845260005b8181101561165157602081850181015186830182015201611635565b81811115611663576000602083870101525b50601f01601f19169290920160200192915050565b60808152600061168b608083018761162b565b828103602084015261169d818761162b565b905082810360408401526116b1818661162b565b91505082606083015295945050505050565b6000600182016116d5576116d5611573565b5060010190565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561173157603f1988860301845261171f85835161162b565b94509285019290850190600101611703565b509297965050505050505056fe60c060405234801561001057600080fd5b506040516106d53803806106d583398101604081905261002f91610044565b336080526001600160a01b031660a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a05161061b6100ba6000396000818160df0152818161015a0152610203015260008181608e0152818161022c015281816103be01526104a9015261061b6000f3fe6080604052600436106100595760003560e01c8063372500ab146100655780634cf088d91461007c5780634f8632ba146100cd5780635475a7be146101015780638686ebcc14610116578063f85f91b41461013a57600080fd5b3661006057005b600080fd5b34801561007157600080fd5b5061007a61014f565b005b34801561008857600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d957600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b34801561010d57600080fd5b5061007a61022a565b34801561012257600080fd5b5061012c61271081565b6040519081526020016100c4565b34801561014657600080fd5b5061012c61031a565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610197576040516282b42960e81b815260040160405180910390fd5b61019f61031a565b6000036101bf576040516312d37ee560e31b815260040160405180910390fd5b6101c761033c565b6040514781527fbacfa9662d479c707dae707c358323f0c7711ef382007957dc9935e629da36b29060200160405180910390a1600080556102287f000000000000000000000000000000000000000000000000000000000000000047610448565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac9190610557565b6001600160a01b0316336001600160a01b0316146102dc576040516282b42960e81b815260040160405180910390fd5b6102f2600054476102ed919061059d565b6104a2565b600003610312576040516312d37ee560e31b815260040160405180910390fd5b61022861033c565b600061032d600054476102ed919061059d565b610337904761059d565b905090565b6000805461034a904761059d565b90506000610357826104a2565b905080600003610365575050565b6040518181527fb9197c6b8e21274bd1e2d9c956a88af5cfee510f630fab3f046300f88b4223619060200160405180910390a16103a2818361059d565b6000808282546103b291906105b4565b925050819055506104447f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190610557565b82610448565b5050565b600080600080600085875af190508061049d5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b60006105337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663877887826040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906105cc565b8390612710610539565b92915050565b600082600019048411830215820261055057600080fd5b5091020490565b60006020828403121561056957600080fd5b81516001600160a01b038116811461058057600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156105af576105af610587565b500390565b600082198211156105c7576105c7610587565b500190565b6000602082840312156105de57600080fd5b505191905056fea2646970667358221220cf8c68186eb03b0415c4e1a451bafa8213a95358dfe1202ce8aa3ce23100036364736f6c634300080d0033a2646970667358221220183a0c36c9591a073c3ab6214384e8867e8f14be98c4c2bee35920d8082b228164736f6c634300080d00330000000000000000000000003b373f51cea611f92d1deb2adb354bf2c11e3c980000000000000000000000003b373f51cea611f92d1deb2adb354bf2c11e3c9800000000000000000000000000000000219ab540356cbb839cbe05303d7705fa0000000000000000000000001c064ea662365c09c8e87242791dacbb9000260500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000003f480

Deployed Bytecode

0x6080604052600436106101a05760003560e01c806370897b23116100ec578063b3ab15fb1161008a578063eea758f111610064578063eea758f1146104c1578063f0f44260146104e1578063f340fa0114610501578063f8245bca1461051457600080fd5b8063b3ab15fb1461044d578063e1ba24261461046d578063e94ad65b1461048d57600080fd5b80638456cb59116100c65780638456cb59146103ec5780638686ebcc1461040157806387788782146104175780638da5cb5b1461042d57600080fd5b806370897b231461039757806379ba5097146103b75780637bfa9819146103cc57600080fd5b806353a47bb7116101595780635b94db27116101335780635b94db27146102f95780635c975abb1461031957806361d027b31461034a578063655d8dec1461036a57600080fd5b806353a47bb7146102a4578063570ca735146102c4578063590e1ae3146102e457600080fd5b8063038defd7146101b5578063047f48b8146102085780632dd00477146102435780633e602b4c146102595780633f4ba83a1461026f5780634e81f4971461028457600080fd5b366101b0576101ae3361052a565b005b600080fd5b3480156101c157600080fd5b506101eb6101d03660046112f6565b6009602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021457600080fd5b506102356102233660046112f6565b600a6020526000908152604090205481565b6040519081526020016101ff565b34801561024f57600080fd5b5061023560085481565b34801561026557600080fd5b5061023560075481565b34801561027b57600080fd5b506101ae6107b8565b34801561029057600080fd5b506101ae61029f3660046113f8565b610805565b3480156102b057600080fd5b506002546101eb906001600160a01b031681565b3480156102d057600080fd5b506003546101eb906001600160a01b031681565b3480156102f057600080fd5b506101ae610ae0565b34801561030557600080fd5b506101ae6103143660046112f6565b610b7d565b34801561032557600080fd5b5060035461033a90600160a01b900460ff1681565b60405190151581526020016101ff565b34801561035657600080fd5b506004546101eb906001600160a01b031681565b34801561037657600080fd5b506102356103853660046112f6565b600b6020526000908152604090205481565b3480156103a357600080fd5b506101ae6103b2366004611530565b610bfd565b3480156103c357600080fd5b506101ae610c55565b3480156103d857600080fd5b506101ae6103e7366004611530565b610ce5565b3480156103f857600080fd5b506101ae610d3a565b34801561040d57600080fd5b5061023561271081565b34801561042357600080fd5b5061023560065481565b34801561043957600080fd5b506001546101eb906001600160a01b031681565b34801561045957600080fd5b506101ae6104683660046112f6565b610d85565b34801561047957600080fd5b506101ae610488366004611530565b610e32565b34801561049957600080fd5b506101eb7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa81565b3480156104cd57600080fd5b506101ae6104dc366004611549565b610e87565b3480156104ed57600080fd5b506101ae6104fc3660046112f6565b610ed8565b6101ae61050f3660046112f6565b610f61565b34801561052057600080fd5b5061023560055481565b600354600160a01b900460ff161561055557604051631309a56360e01b815260040160405180910390fd5b6000546001146105995760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60026000556001600160a01b0381166105c55760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a6020526040902054156105fc57604051633d4366cb60e01b815260040160405180910390fd5b60006005546801bc16d674ec8000006106159190611589565b905034158061062c575061062981346115b7565b15155b1561064a5760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038281166000908152600960205260409020541661070057600082604051610678906112cd565b6001600160a01b039091168152602001604051809103906000f0801580156106a4573d6000803e3d6000fd5b506001600160a01b0384811660008181526009602052604080822080546001600160a01b031916948616948517905551939450919290917f2138b9314634f9fdd5e49bee3eaf17ca557b6637524d0db759711c3bfcd3d85091a3505b600061070c82346115cb565b6001600160a01b0384166000908152600a6020526040812080549293508392909190610739908490611589565b9250508190555080600860008282546107529190611589565b90915550506001600160a01b0383166000818152600b6020526040908190204290555133907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906107a69085815260200190565b60405180910390a35050600160005550565b6001546001600160a01b031633148015906107de57506003546001600160a01b03163314155b156107fb576040516282b42960e81b815260040160405180910390fd5b610803610f6a565b565b6001546001600160a01b0316331480159061082b57506003546001600160a01b03163314155b15610848576040516282b42960e81b815260040160405180910390fd5b8051600081900361086c5760405163251f56a160e21b815260040160405180910390fd5b6001600160a01b0383166000908152600a6020526040812080548392906108949084906115df565b9250508190555080600860008282546108ad91906115df565b9091555050600554156108dd576004546005546108dd916001600160a01b0316906108d890846115f6565b610fce565b60008167ffffffffffffffff8111156108f8576108f8611318565b60405190808252806020026020018201604052801561092b57816020015b60608152602001906001900390816109165790505b50905060005b82811015610a9857600084828151811061094d5761094d611615565b6020908102919091018101515160408051600160f81b93810193909352600060218401526bffffffffffffffffffffffff1960608a901b16602c8401529092506001600160a01b037f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa16916322895118916801bc16d674ec800000918591016040516020818303038152906040528987815181106109ed576109ed611615565b6020026020010151602001518a8881518110610a0b57610a0b611615565b6020026020010151604001516040518663ffffffff1660e01b8152600401610a369493929190611678565b6000604051808303818588803b158015610a4f57600080fd5b505af1158015610a63573d6000803e3d6000fd5b505050505080838381518110610a7b57610a7b611615565b60200260200101819052505080610a91906116c3565b9050610931565b50836001600160a01b03167fddb1ded6779e003e6e258c4bedfe8ab9f83cfa5390e730b6c0c5e5e85d96082a82604051610ad291906116dc565b60405180910390a250505050565b600054600114610b1f5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610590565b60026000908155338152600a6020908152604080832054600754600b909352922054610b4b9190611589565b421015610b6b576040516380a3a69f60e01b815260040160405180910390fd5b610b753382611024565b506001600055565b6001546001600160a01b03163314610ba7576040516282b42960e81b815260040160405180910390fd5b6040516001600160a01b038216907f0b6876d59e2e3c1a7e4bb6dd95d7ef3a8a17927d9f55c43cc4358973f6b97e1290600090a2600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610c27576040516282b42960e81b815260040160405180910390fd5b6006548103610c495760405163c23f6ccb60e01b815260040160405180910390fd5b610c52816110f8565b50565b6002546001600160a01b03163314610c7f576040516282b42960e81b815260040160405180910390fd5b6002546001546040516001600160a01b0392831692909116907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236490600090a360028054600180546001600160a01b03199081166001600160a01b03841617909155169055565b6001546001600160a01b03163314610d0f576040516282b42960e81b815260040160405180910390fd5b6007548103610d315760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611157565b6001546001600160a01b03163314801590610d6057506003546001600160a01b03163314155b15610d7d576040516282b42960e81b815260040160405180910390fd5b6108036111b0565b6001546001600160a01b03163314610daf576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610dd65760405163d92e233d60e01b815260040160405180910390fd5b6003546040516001600160a01b038084169216907ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c90600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610e5c576040516282b42960e81b815260040160405180910390fd5b6005548103610e7e5760405163c23f6ccb60e01b815260040160405180910390fd5b610c528161121b565b6001546001600160a01b03163314801590610ead57506003546001600160a01b03163314155b15610eca576040516282b42960e81b815260040160405180910390fd5b610ed48282611024565b5050565b6001546001600160a01b03163314610f02576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610f295760405163d92e233d60e01b815260040160405180910390fd5b6004546001600160a01b0390811690821603610f585760405163c23f6ccb60e01b815260040160405180910390fd5b610c5281611271565b610c528161052a565b600354600160a01b900460ff16610f9457604051636cd6020160e01b815260040160405180910390fd5b6003805460ff60a01b1916905560405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90600090a2565b600080600080600085875af190508061101f5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610590565b505050565b8060000361104557604051633a6a68b160e01b815260040160405180910390fd5b6001600160a01b0382166000908152600a60205260408120805483929061106d9084906115df565b92505081905550806008600082825461108691906115df565b90915550506005546110b19083906110a7906801bc16d674ec800000611589565b6108d890846115f6565b816001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d826040516110ec91815260200190565b60405180910390a25050565b61271081111561111b5760405163162908e360e11b815260040160405180910390fd5b60068190556040518181527fceb20f7f0b19335681096ee1eaa9bb2a6ef5a9a69ba48b6b488e7b7eff2ef04d906020015b60405180910390a150565b62093a8081111561117b5760405163162908e360e11b815260040160405180910390fd5b60078190556040518181527f829115d20ef76cd57820d0bbc4775febaa93deae0e86c936cde129d1349f676e9060200161114c565b600354600160a01b900460ff16156111db57604051631309a56360e01b815260040160405180910390fd5b6003805460ff60a01b1916600160a01b17905560405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890600090a2565b6008541561123c57604051633d4366cb60e01b815260040160405180910390fd5b60058190556040518181527fa9be77e1a84a70ba86813c7f754603b280ffbeae336e020f99450b6f7da199589060200161114c565b6004546040516001600160a01b038084169216907f567657fa3f286518b318f4a29870674f433f622fdfc819691acb13105b22822590600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b6106d58061173f83390190565b80356001600160a01b03811681146112f157600080fd5b919050565b60006020828403121561130857600080fd5b611311826112da565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561135157611351611318565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561138057611380611318565b604052919050565b600082601f83011261139957600080fd5b813567ffffffffffffffff8111156113b3576113b3611318565b6113c6601f8201601f1916602001611357565b8181528460208386010111156113db57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561140b57600080fd5b611414836112da565b915060208084013567ffffffffffffffff8082111561143257600080fd5b818601915086601f83011261144657600080fd5b81358181111561145857611458611318565b8060051b611467858201611357565b918252838101850191858101908a84111561148157600080fd5b86860192505b8383101561151f5782358581111561149f5760008081fd5b86016060818d03601f19018113156114b75760008081fd5b6114bf61132e565b89830135888111156114d15760008081fd5b6114df8f8c83870101611388565b8252506040830135888111156114f55760008081fd5b6115038f8c83870101611388565b828c015250910135604082015282529186019190860190611487565b809750505050505050509250929050565b60006020828403121561154257600080fd5b5035919050565b6000806040838503121561155c57600080fd5b611565836112da565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561159c5761159c611573565b500190565b634e487b7160e01b600052601260045260246000fd5b6000826115c6576115c66115a1565b500690565b6000826115da576115da6115a1565b500490565b6000828210156115f1576115f1611573565b500390565b600081600019048311821515161561161057611610611573565b500290565b634e487b7160e01b600052603260045260246000fd5b6000815180845260005b8181101561165157602081850181015186830182015201611635565b81811115611663576000602083870101525b50601f01601f19169290920160200192915050565b60808152600061168b608083018761162b565b828103602084015261169d818761162b565b905082810360408401526116b1818661162b565b91505082606083015295945050505050565b6000600182016116d5576116d5611573565b5060010190565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561173157603f1988860301845261171f85835161162b565b94509285019290850190600101611703565b509297965050505050505056fe60c060405234801561001057600080fd5b506040516106d53803806106d583398101604081905261002f91610044565b336080526001600160a01b031660a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a05161061b6100ba6000396000818160df0152818161015a0152610203015260008181608e0152818161022c015281816103be01526104a9015261061b6000f3fe6080604052600436106100595760003560e01c8063372500ab146100655780634cf088d91461007c5780634f8632ba146100cd5780635475a7be146101015780638686ebcc14610116578063f85f91b41461013a57600080fd5b3661006057005b600080fd5b34801561007157600080fd5b5061007a61014f565b005b34801561008857600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d957600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b34801561010d57600080fd5b5061007a61022a565b34801561012257600080fd5b5061012c61271081565b6040519081526020016100c4565b34801561014657600080fd5b5061012c61031a565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610197576040516282b42960e81b815260040160405180910390fd5b61019f61031a565b6000036101bf576040516312d37ee560e31b815260040160405180910390fd5b6101c761033c565b6040514781527fbacfa9662d479c707dae707c358323f0c7711ef382007957dc9935e629da36b29060200160405180910390a1600080556102287f000000000000000000000000000000000000000000000000000000000000000047610448565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac9190610557565b6001600160a01b0316336001600160a01b0316146102dc576040516282b42960e81b815260040160405180910390fd5b6102f2600054476102ed919061059d565b6104a2565b600003610312576040516312d37ee560e31b815260040160405180910390fd5b61022861033c565b600061032d600054476102ed919061059d565b610337904761059d565b905090565b6000805461034a904761059d565b90506000610357826104a2565b905080600003610365575050565b6040518181527fb9197c6b8e21274bd1e2d9c956a88af5cfee510f630fab3f046300f88b4223619060200160405180910390a16103a2818361059d565b6000808282546103b291906105b4565b925050819055506104447f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190610557565b82610448565b5050565b600080600080600085875af190508061049d5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b60006105337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663877887826040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906105cc565b8390612710610539565b92915050565b600082600019048411830215820261055057600080fd5b5091020490565b60006020828403121561056957600080fd5b81516001600160a01b038116811461058057600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156105af576105af610587565b500390565b600082198211156105c7576105c7610587565b500190565b6000602082840312156105de57600080fd5b505191905056fea2646970667358221220cf8c68186eb03b0415c4e1a451bafa8213a95358dfe1202ce8aa3ce23100036364736f6c634300080d0033a2646970667358221220183a0c36c9591a073c3ab6214384e8867e8f14be98c4c2bee35920d8082b228164736f6c634300080d0033

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

0000000000000000000000003b373f51cea611f92d1deb2adb354bf2c11e3c980000000000000000000000003b373f51cea611f92d1deb2adb354bf2c11e3c9800000000000000000000000000000000219ab540356cbb839cbe05303d7705fa0000000000000000000000001c064ea662365c09c8e87242791dacbb9000260500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000003f480

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

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000003b373f51cea611f92d1deb2adb354bf2c11e3c98
Arg [1] : 0000000000000000000000003b373f51cea611f92d1deb2adb354bf2c11e3c98
Arg [2] : 00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa
Arg [3] : 0000000000000000000000001c064ea662365c09c8e87242791dacbb90002605
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
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.