ETH Price: $1,931.88 (+1.07%)
Gas: 0.37 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Deposit218175942025-02-10 17:24:5936 days ago1739208299IN
0xc12dfb80...eE6355058
0.03 ETH0.000189061.46176103
Deposit218175932025-02-10 17:24:4736 days ago1739208287IN
0xc12dfb80...eE6355058
0.03 ETH0.000187011.44596046
Deposit216073822025-01-12 9:01:5965 days ago1736672519IN
0xc12dfb80...eE6355058
12 ETH0.000316142.44430458
Deposit204771402024-08-07 13:57:47223 days ago1723039067IN
0xc12dfb80...eE6355058
6 ETH0.000981856.70489654
Deposit203250762024-07-17 8:32:47244 days ago1721205167IN
0xc12dfb80...eE6355058
5.9 ETH0.0021741114.84664542
Deposit202764132024-07-10 13:31:11251 days ago1720618271IN
0xc12dfb80...eE6355058
85 ETH0.001234937.55135617
Deposit201753272024-06-26 10:40:47265 days ago1719398447IN
0xc12dfb80...eE6355058
0.1 ETH0.000558533.81415619
Deposit200715482024-06-11 22:23:59280 days ago1718144639IN
0xc12dfb80...eE6355058
0.13 ETH0.001892312.92221146
Deposit199231272024-05-22 4:44:11300 days ago1716353051IN
0xc12dfb80...eE6355058
0.0109 ETH0.000975036.65831885
Deposit195799582024-04-04 4:16:23348 days ago1712204183IN
0xc12dfb80...eE6355058
32 ETH0.0023274417.99509052
Deposit195799362024-04-04 4:11:47348 days ago1712203907IN
0xc12dfb80...eE6355058
0.9 ETH0.00268218.31492255
Deposit194422372024-03-15 18:49:59368 days ago1710528599IN
0xc12dfb80...eE6355058
25 ETH0.006695845.72448825
Deposit192372082024-02-16 1:31:11397 days ago1708047071IN
0xc12dfb80...eE6355058
7.65 ETH0.003790323.17689284
Deposit190817652024-01-25 6:12:23418 days ago1706163143IN
0xc12dfb80...eE6355058
3.08 ETH0.001421379.70632435
Deposit190811002024-01-25 3:58:23418 days ago1706155103IN
0xc12dfb80...eE6355058
1 ETH0.0016428511.21874398
Deposit190677932024-01-23 7:08:59420 days ago1705993739IN
0xc12dfb80...eE6355058
2.3 ETH0.001218159.41834578
Deposit190677832024-01-23 7:06:59420 days ago1705993619IN
0xc12dfb80...eE6355058
2.5 ETH0.001199239.27208232
Deposit190677712024-01-23 7:04:35420 days ago1705993475IN
0xc12dfb80...eE6355058
2.6 ETH0.0016163511.03781118
Deposit190608022024-01-22 7:30:47421 days ago1705908647IN
0xc12dfb80...eE6355058
5.8 ETH0.0048035432.80259655
Deposit190253402024-01-17 8:13:35426 days ago1705479215IN
0xc12dfb80...eE6355058
4 ETH0.0057480935.14834632
Deposit190182692024-01-16 8:30:47427 days ago1705393847IN
0xc12dfb80...eE6355058
15 ETH0.0040560824.80207758
Deposit190150132024-01-15 21:37:23428 days ago1705354643IN
0xc12dfb80...eE6355058
2.02 ETH0.0035964821.99172247
Deposit188606102023-12-25 5:14:59449 days ago1703481299IN
0xc12dfb80...eE6355058
100 ETH0.0019769413.5002006
Deposit187982592023-12-16 11:13:59458 days ago1702725239IN
0xc12dfb80...eE6355058
99 ETH0.004635.56573316
Deposit187973032023-12-16 8:01:35458 days ago1702713695IN
0xc12dfb80...eE6355058
1 ETH0.0065633644.82007242
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Deposit Ether220737502025-03-18 12:26:2314 hrs ago1742300783
0xc12dfb80...eE6355058
0.00481352 ETH
Recycle Distribu...220737502025-03-18 12:26:2314 hrs ago1742300783
0xc12dfb80...eE6355058
0.00481352 ETH
Deposit Ether220522292025-03-15 12:17:593 days ago1742041079
0xc12dfb80...eE6355058
0.01801289 ETH
Recycle Distribu...220522292025-03-15 12:17:593 days ago1742041079
0xc12dfb80...eE6355058
0.01801289 ETH
Deposit Ether220511282025-03-15 8:37:233 days ago1742027843
0xc12dfb80...eE6355058
1.87761989 ETH
Recycle Withdraw...220511282025-03-15 8:37:233 days ago1742027843
0xc12dfb80...eE6355058
1.87761989 ETH
Deposit Ether220511232025-03-15 8:36:233 days ago1742027783
0xc12dfb80...eE6355058
0.26162111 ETH
Recycle Distribu...220511232025-03-15 8:36:233 days ago1742027783
0xc12dfb80...eE6355058
0.26162111 ETH
Deposit Ether220164272025-03-10 12:19:118 days ago1741609151
0xc12dfb80...eE6355058
0.04763071 ETH
Recycle Distribu...220164272025-03-10 12:19:118 days ago1741609151
0xc12dfb80...eE6355058
0.04763071 ETH
Deposit Ether220022272025-03-08 12:41:3510 days ago1741437695
0xc12dfb80...eE6355058
0.15736654 ETH
Recycle Distribu...220022272025-03-08 12:41:3510 days ago1741437695
0xc12dfb80...eE6355058
0.15736654 ETH
Deposit Ether219807382025-03-05 12:39:2313 days ago1741178363
0xc12dfb80...eE6355058
0.81411765 ETH
Recycle Withdraw...219807382025-03-05 12:39:2313 days ago1741178363
0xc12dfb80...eE6355058
0.81411765 ETH
Deposit Ether219807342025-03-05 12:38:3513 days ago1741178315
0xc12dfb80...eE6355058
0.04101061 ETH
Recycle Distribu...219807342025-03-05 12:38:3513 days ago1741178315
0xc12dfb80...eE6355058
0.04101061 ETH
Deposit Ether219735972025-03-04 12:42:3514 days ago1741092155
0xc12dfb80...eE6355058
0.87026134 ETH
Recycle Withdraw...219735972025-03-04 12:42:3514 days ago1741092155
0xc12dfb80...eE6355058
0.87026134 ETH
Deposit Ether219735922025-03-04 12:41:3514 days ago1741092095
0xc12dfb80...eE6355058
0.09460661 ETH
Recycle Distribu...219735922025-03-04 12:41:3514 days ago1741092095
0xc12dfb80...eE6355058
0.09460661 ETH
Deposit Ether219666132025-03-03 13:19:5915 days ago1741007999
0xc12dfb80...eE6355058
0.01761854 ETH
Recycle Distribu...219666132025-03-03 13:19:5915 days ago1741007999
0xc12dfb80...eE6355058
0.01761854 ETH
Deposit Eth219199262025-02-25 1:01:2322 days ago1740445283
0xc12dfb80...eE6355058
4.51020402 ETH
Receive Ether Wi...219199262025-02-25 1:01:2322 days ago1740445283
0xc12dfb80...eE6355058
4.51020402 ETH
Deposit Ether219161462025-02-24 12:21:1122 days ago1740399671
0xc12dfb80...eE6355058
0.00456945 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StafiUserDeposit

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 15 : StafiUserDeposit.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/math/SafeMath.sol";
import "../StafiBase.sol";
import "../interfaces/IStafiEther.sol";
import "../interfaces/IStafiEtherWithdrawer.sol";
import "../interfaces/deposit/IStafiUserDeposit.sol";
import "../interfaces/pool/IStafiStakingPool.sol";
import "../interfaces/pool/IStafiStakingPoolQueue.sol";
import "../interfaces/token/IRETHToken.sol";
import "../interfaces/node/IStafiSuperNode.sol";
import "../interfaces/node/IStafiLightNode.sol";
import "../interfaces/withdraw/IStafiWithdraw.sol";

// Accepts user deposits and mints rETH; handles assignment of deposited ETH to pools
contract StafiUserDeposit is StafiBase, IStafiUserDeposit, IStafiEtherWithdrawer {

    // Libs
    using SafeMath for uint256;

    // Events
    event DepositReceived(address indexed from, uint256 amount, uint256 time);
    event DepositRecycled(address indexed from, uint256 amount, uint256 time);
    event DepositAssigned(address indexed stakingPool, uint256 amount, uint256 time);
    event ExcessWithdrawn(address indexed to, uint256 amount, uint256 time);

    // Construct
    constructor(address _stafiStorageAddress) StafiBase(_stafiStorageAddress) {
        version = 1;
        // Initialize settings on deployment
        if (!getBoolS("settings.user.deposit.init")) {
            // Apply settings
            setDepositEnabled(true);
            setAssignDepositsEnabled(true);
            setMinimumDeposit(0.01 ether);
            // setMaximumDepositPoolSize(100000 ether);
            setMaximumDepositAssignments(2);
            // Settings initialized
            setBoolS("settings.user.deposit.init", true);
        }
    }

    // Current deposit pool balance
    function getBalance() override public view returns (uint256) {
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        return stafiEther.balanceOf(address(this));
    }

    // Excess deposit pool balance (in excess of stakingPool queue capacity)
    function getExcessBalance() override public view returns (uint256) {
        // Get stakingPool queue capacity
        IStafiStakingPoolQueue stafiStakingPoolQueue = IStafiStakingPoolQueue(getContractAddress("stafiStakingPoolQueue"));
        uint256 stakingPoolCapacity = stafiStakingPoolQueue.getEffectiveCapacity();
        // Calculate and return
        uint256 balance = getBalance();
        if (stakingPoolCapacity >= balance) { return 0; }
        else { return balance.sub(stakingPoolCapacity); }
    }

    // Receive a ether withdrawal
    // Only accepts calls from the StafiEther contract
    function receiveEtherWithdrawal() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiEther", msg.sender) {}

    // Accept a deposit from a user
    function deposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) {
        // Check deposit settings
        require(getDepositEnabled(), "Deposits into Stafi are currently disabled");
        require(msg.value >= getMinimumDeposit(), "The deposited amount is less than the minimum deposit size");
        // Load contracts
        IRETHToken rETHToken = IRETHToken(getContractAddress("rETHToken"));
        // Mint rETH to user account
        rETHToken.userMint(msg.value, msg.sender);
        // Emit deposit received event
        emit DepositReceived(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }

    // Recycle a deposit from a dissolved stakingPool
    // Only accepts calls from registered stakingPools
    function recycleDissolvedDeposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyRegisteredStakingPool(msg.sender) {
        // Emit deposit recycled event
        emit DepositRecycled(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }

    // Recycle a deposit from fee collector
    // Only accepts calls from registered stafiDistributor
    function recycleDistributorDeposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiDistributor", msg.sender) {
        // Emit deposit recycled event
        emit DepositRecycled(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }
    
    // Recycle a deposit from withdraw pool
    // Only accepts calls from registered stafiWithdraw
    function recycleWithdrawDeposit() override external payable onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiWithdraw", msg.sender) {
        // Emit deposit recycled event
        emit DepositRecycled(msg.sender, msg.value, block.timestamp);
        // Process deposit
        processDeposit();
    }

    // Process a deposit
    function processDeposit() private {
        // Load contracts
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Transfer ETH to stafiEther
        stafiEther.depositEther{value: msg.value}();
        // Assign deposits if enabled
        assignDeposits();
    }

    // Assign deposits to available stakingPools
    function assignDeposits() override public onlyLatestContract("stafiUserDeposit", address(this)) {
        // Check deposit settings
        if (!getAssignDepositsEnabled()) {
            return;
        }

        // Load contracts
        IStafiStakingPoolQueue stafiStakingPoolQueue = IStafiStakingPoolQueue(getContractAddress("stafiStakingPoolQueue"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Assign deposits
        uint256 maximumDepositAssignments = getMaximumDepositAssignments();
        for (uint256 i = 0; i < maximumDepositAssignments; ++i) {
            // Get & check next available staking pool capacity
            uint256 stakingPoolCapacity = stafiStakingPoolQueue.getNextCapacity();
            if (stakingPoolCapacity == 0 || getBalance() < stakingPoolCapacity) { break; }
            // Dequeue next available staking pool
            address stakingPoolAddress = stafiStakingPoolQueue.dequeueStakingPool();
            IStafiStakingPool stakingPool = IStafiStakingPool(stakingPoolAddress);
            // Withdraw ETH from stafiEther
            stafiEther.withdrawEther(stakingPoolCapacity);
            // Assign deposit to staking pool
            stakingPool.userDeposit{value: stakingPoolCapacity}();
            // Emit deposit assigned event
            emit DepositAssigned(stakingPoolAddress, stakingPoolCapacity, block.timestamp);
        }
    }

    // Withdraw excess deposit pool balance for rETH collateral
    function withdrawExcessBalance(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("rETHToken", msg.sender) {
        // Load contracts
        IRETHToken rETHToken = IRETHToken(getContractAddress("rETHToken"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to rETH contract
        rETHToken.depositExcess{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }

    // Withdraw excess deposit pool balance for super node
    function withdrawExcessBalanceForSuperNode(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiSuperNode", msg.sender) {
        // Load contracts
        IStafiSuperNode superNode = IStafiSuperNode(getContractAddress("stafiSuperNode"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to superNode contract
        superNode.depositEth{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }
    
    // Withdraw excess deposit pool balance for light node
    function withdrawExcessBalanceForLightNode(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiLightNode", msg.sender) {
        // Load contracts
        IStafiLightNode lightNode = IStafiLightNode(getContractAddress("stafiLightNode"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to superNode contract
        lightNode.depositEth{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }
    
    // Withdraw excess deposit pool balance for light node
    function withdrawExcessBalanceForWithdraw(uint256 _amount) override external onlyLatestContract("stafiUserDeposit", address(this)) onlyLatestContract("stafiWithdraw", msg.sender) {
        // Load contracts
        IStafiWithdraw stafiWithdraw = IStafiWithdraw(getContractAddress("stafiWithdraw"));
        IStafiEther stafiEther = IStafiEther(getContractAddress("stafiEther"));
        // Check amount
        require(_amount <= getBalance(), "Insufficient balance for withdrawal");
        // Withdraw ETH from vault
        stafiEther.withdrawEther(_amount);
        // Transfer to superNode contract
        stafiWithdraw.depositEth{value: _amount}();
        // Emit excess withdrawn event
        emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
    }

    // Deposits currently enabled
    function getDepositEnabled() public view returns (bool) {
        return getBoolS("settings.deposit.enabled");
    }
    function setDepositEnabled(bool _value) public onlySuperUser {
        setBoolS("settings.deposit.enabled", _value);
    }

    // Deposit assignments currently enabled
    function getAssignDepositsEnabled() public view returns (bool) {
        return getBoolS("settings.deposit.assign.enabled");
    }
    function setAssignDepositsEnabled(bool _value) public onlySuperUser {
        setBoolS("settings.deposit.assign.enabled", _value);
    }

    // Minimum deposit size
    function getMinimumDeposit() public view returns (uint256) {
        return getUintS("settings.deposit.minimum");
    }
    function setMinimumDeposit(uint256 _value) public onlySuperUser {
        setUintS("settings.deposit.minimum", _value);
    }

    // The maximum number of deposit assignments to perform at once
    function getMaximumDepositAssignments() public view returns (uint256) {
        return getUintS("settings.deposit.assign.maximum");
    }
    function setMaximumDepositAssignments(uint256 _value) public onlySuperUser {
        setUintS("settings.deposit.assign.maximum", _value);
    }

}

File 2 of 15 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 3 of 15 : IStafiUserDeposit.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiUserDeposit {
    function getBalance() external view returns (uint256);
    function getExcessBalance() external view returns (uint256);
    function deposit() external payable;
    function recycleDissolvedDeposit() external payable;
    function recycleWithdrawDeposit() external payable;
    function recycleDistributorDeposit() external payable;
    function assignDeposits() external;
    function withdrawExcessBalance(uint256 _amount) external;
    function withdrawExcessBalanceForSuperNode(uint256 _amount) external;
    function withdrawExcessBalanceForLightNode(uint256 _amount) external;
    function withdrawExcessBalanceForWithdraw(uint256 _amount) external;
}

File 4 of 15 : IStafiEther.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiEther {
    function balanceOf(address _contractAddress) external view returns (uint256);
    function depositEther() external payable;
    function withdrawEther(uint256 _amount) external;
}

File 5 of 15 : IStafiEtherWithdrawer.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiEtherWithdrawer {
    function receiveEtherWithdrawal() external payable;
}

File 6 of 15 : IStafiLightNode.sol
pragma solidity 0.7.6;
pragma abicoder v2;
// SPDX-License-Identifier: GPL-3.0-only

interface IStafiLightNode {
    function depositEth() external payable;
    function deposit(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external payable;
    function stake(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external;
    function offBoard(bytes calldata _validatorPubkey) external;
    function provideNodeDepositToken(bytes calldata _validatorPubkey) external payable;
    function withdrawNodeDepositToken(bytes calldata _validatorPubkey) external;
    function getLightNodePubkeyCount(address _nodeAddress) external view returns (uint256);
    function getLightNodePubkeyAt(address _nodeAddress, uint256 _index) external view returns (bytes memory);
    function getLightNodePubkeyStatus(bytes calldata _validatorPubkey) external view returns (uint256);
    function voteWithdrawCredentials(bytes[] calldata _pubkey, bool[] calldata _match) external;
}

File 7 of 15 : IStafiSuperNode.sol
pragma solidity 0.7.6;
pragma abicoder v2;
// SPDX-License-Identifier: GPL-3.0-only

interface IStafiSuperNode {
    function depositEth() external payable;
    function deposit(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external;
    function stake(bytes[] calldata _validatorPubkeys, bytes[] calldata _validatorSignatures, bytes32[] calldata _depositDataRoots) external;
    function getSuperNodePubkeyCount(address _nodeAddress) external view returns (uint256);
    function getSuperNodePubkeyAt(address _nodeAddress, uint256 _index) external view returns (bytes memory);
    function getSuperNodePubkeyStatus(bytes calldata _validatorPubkey) external view returns (uint256);
    function voteWithdrawCredentials(bytes[] calldata _pubkey, bool[] calldata _match) external;
}

File 8 of 15 : IStafiStakingPool.sol
pragma solidity 0.7.6;
// SPDX-License-Identifier: GPL-3.0-only

import "../../types/DepositType.sol";
import "../../types/StakingPoolStatus.sol";

interface IStafiStakingPool {
    function initialise(address _nodeAddress, DepositType _depositType) external;
    function getStatus() external view returns (StakingPoolStatus);
    function getStatusBlock() external view returns (uint256);
    function getStatusTime() external view returns (uint256);
    function getWithdrawalCredentialsMatch() external view returns (bool);
    function getDepositType() external view returns (DepositType);
    function getNodeAddress() external view returns (address);
    function getNodeFee() external view returns (uint256);
    function getNodeDepositBalance() external view returns (uint256);
    function getNodeRefundBalance() external view returns (uint256);
    function getNodeDepositAssigned() external view returns (bool);
    function getNodeCommonlyRefunded() external view returns (bool);
    function getNodeTrustedRefunded() external view returns (bool);
    function getUserDepositBalance() external view returns (uint256);
    function getUserDepositAssigned() external view returns (bool);
    function getUserDepositAssignedTime() external view returns (uint256);
    function getPlatformDepositBalance() external view returns (uint256);
    function nodeDeposit(bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot) external payable;
    function userDeposit() external payable;
    function stake(bytes calldata _validatorSignature, bytes32 _depositDataRoot)  external;
    function refund() external;
    function dissolve() external;
    function close() external;
    function voteWithdrawCredentials() external;
}

File 9 of 15 : IStafiStakingPoolQueue.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

import "../../types/DepositType.sol";

interface IStafiStakingPoolQueue {
    function getTotalLength() external view returns (uint256);
    function getLength(DepositType _depositType) external view returns (uint256);
    function getTotalCapacity() external view returns (uint256);
    function getEffectiveCapacity() external view returns (uint256);
    function getNextCapacity() external view returns (uint256);
    function enqueueStakingPool(DepositType _depositType, address _stakingPool) external;
    function dequeueStakingPool() external returns (address);
    function removeStakingPool() external;
}

File 10 of 15 : IStafiStorage.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiStorage {

    // Getters
    function getAddress(bytes32 _key) external view returns (address);
    function getUint(bytes32 _key) external view returns (uint);
    function getString(bytes32 _key) external view returns (string memory);
    function getBytes(bytes32 _key) external view returns (bytes memory);
    function getBool(bytes32 _key) external view returns (bool);
    function getInt(bytes32 _key) external view returns (int);
    function getBytes32(bytes32 _key) external view returns (bytes32);

    // Setters
    function setAddress(bytes32 _key, address _value) external;
    function setUint(bytes32 _key, uint _value) external;
    function setString(bytes32 _key, string calldata _value) external;
    function setBytes(bytes32 _key, bytes calldata _value) external;
    function setBool(bytes32 _key, bool _value) external;
    function setInt(bytes32 _key, int _value) external;
    function setBytes32(bytes32 _key, bytes32 _value) external;

    // Deleters
    function deleteAddress(bytes32 _key) external;
    function deleteUint(bytes32 _key) external;
    function deleteString(bytes32 _key) external;
    function deleteBytes(bytes32 _key) external;
    function deleteBool(bytes32 _key) external;
    function deleteInt(bytes32 _key) external;
    function deleteBytes32(bytes32 _key) external;

}

File 11 of 15 : IRETHToken.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IRETHToken {
    function getEthValue(uint256 _rethAmount) external view returns (uint256);
    function getRethValue(uint256 _ethAmount) external view returns (uint256);
    function getExchangeRate() external view returns (uint256);
    function getTotalCollateral() external view returns (uint256);
    function getCollateralRate() external view returns (uint256);
    function depositRewards() external payable;
    function depositExcess() external payable;
    function userMint(uint256 _ethAmount, address _to) external;
    function userBurn(uint256 _rethAmount) external;
}

File 12 of 15 : IStafiWithdraw.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

interface IStafiWithdraw {
    // user

    function unstake(uint256 _rEthAmount) external;

    function withdraw(uint256[] calldata _withdrawIndexList) external;

    // ejector
    function notifyValidatorExit(
        uint256 _withdrawCycle,
        uint256 _ejectedStartWithdrawCycle,
        uint256[] calldata _validatorIndex
    ) external;

    // voter
    function distributeWithdrawals(
        uint256 _dealedHeight,
        uint256 _userAmount,
        uint256 _nodeAmount,
        uint256 _platformAmount,
        uint256 _maxClaimableWithdrawIndex
    ) external;

    function reserveEthForWithdraw(uint256 _withdrawCycle) external;

    function depositEth() external payable;

    function getUnclaimedWithdrawalsOfUser(address user) external view returns (uint256[] memory);

    function getEjectedValidatorsAtCycle(uint256 cycle) external view returns (uint256[] memory);
}

File 13 of 15 : StafiBase.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

import "./interfaces/storage/IStafiStorage.sol";

abstract contract StafiBase {

    // Version of the contract
    uint8 public version;

    // The main storage contract where primary persistant storage is maintained
    IStafiStorage stafiStorage = IStafiStorage(0);


    /**
    * @dev Throws if called by any sender that doesn't match a network contract
    */
    modifier onlyLatestNetworkContract() {
        require(getBool(keccak256(abi.encodePacked("contract.exists", msg.sender))), "Invalid or outdated network contract");
        _;
    }


    /**
    * @dev Throws if called by any sender that doesn't match one of the supplied contract or is the latest version of that contract
    */
    modifier onlyLatestContract(string memory _contractName, address _contractAddress) {
        require(_contractAddress == getAddress(keccak256(abi.encodePacked("contract.address", _contractName))), "Invalid or outdated contract");
        _;
    }


    /**
    * @dev Throws if called by any sender that isn't a trusted node
    */
    modifier onlyTrustedNode(address _nodeAddress) {
        require(getBool(keccak256(abi.encodePacked("node.trusted", _nodeAddress))), "Invalid trusted node");
        _;
    }
    
    /**
    * @dev Throws if called by any sender that isn't a super node
    */
    modifier onlySuperNode(address _nodeAddress) {
        require(getBool(keccak256(abi.encodePacked("node.super", _nodeAddress))), "Invalid super node");
        _;
    }


    /**
    * @dev Throws if called by any sender that isn't a registered staking pool
    */
    modifier onlyRegisteredStakingPool(address _stakingPoolAddress) {
        require(getBool(keccak256(abi.encodePacked("stakingpool.exists", _stakingPoolAddress))), "Invalid staking pool");
        _;
    }


    /**
    * @dev Throws if called by any account other than the owner.
    */
    modifier onlyOwner() {
        require(roleHas("owner", msg.sender), "Account is not the owner");
        _;
    }


    /**
    * @dev Modifier to scope access to admins
    */
    modifier onlyAdmin() {
        require(roleHas("admin", msg.sender), "Account is not an admin");
        _;
    }


    /**
    * @dev Modifier to scope access to admins
    */
    modifier onlySuperUser() {
        require(roleHas("owner", msg.sender) || roleHas("admin", msg.sender), "Account is not a super user");
        _;
    }


    /**
    * @dev Reverts if the address doesn't have this role
    */
    modifier onlyRole(string memory _role) {
        require(roleHas(_role, msg.sender), "Account does not match the specified role");
        _;
    }


    /// @dev Set the main Storage address
    constructor(address _stafiStorageAddress) {
        // Update the contract address
        stafiStorage = IStafiStorage(_stafiStorageAddress);
    }


    /// @dev Get the address of a network contract by name
    function getContractAddress(string memory _contractName) internal view returns (address) {
        // Get the current contract address
        address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName)));
        // Check it
        require(contractAddress != address(0x0), "Contract not found");
        // Return
        return contractAddress;
    }


    /// @dev Get the name of a network contract by address
    function getContractName(address _contractAddress) internal view returns (string memory) {
        // Get the contract name
        string memory contractName = getString(keccak256(abi.encodePacked("contract.name", _contractAddress)));
        // Check it
        require(keccak256(abi.encodePacked(contractName)) != keccak256(abi.encodePacked("")), "Contract not found");
        // Return
        return contractName;
    }


    /// @dev Storage get methods
    function getAddress(bytes32 _key) internal view returns (address) { return stafiStorage.getAddress(_key); }
    function getUint(bytes32 _key) internal view returns (uint256) { return stafiStorage.getUint(_key); }
    function getString(bytes32 _key) internal view returns (string memory) { return stafiStorage.getString(_key); }
    function getBytes(bytes32 _key) internal view returns (bytes memory) { return stafiStorage.getBytes(_key); }
    function getBool(bytes32 _key) internal view returns (bool) { return stafiStorage.getBool(_key); }
    function getInt(bytes32 _key) internal view returns (int256) { return stafiStorage.getInt(_key); }
    function getBytes32(bytes32 _key) internal view returns (bytes32) { return stafiStorage.getBytes32(_key); }
    function getAddressS(string memory _key) internal view returns (address) { return stafiStorage.getAddress(keccak256(abi.encodePacked(_key))); }
    function getUintS(string memory _key) internal view returns (uint256) { return stafiStorage.getUint(keccak256(abi.encodePacked(_key))); }
    function getStringS(string memory _key) internal view returns (string memory) { return stafiStorage.getString(keccak256(abi.encodePacked(_key))); }
    function getBytesS(string memory _key) internal view returns (bytes memory) { return stafiStorage.getBytes(keccak256(abi.encodePacked(_key))); }
    function getBoolS(string memory _key) internal view returns (bool) { return stafiStorage.getBool(keccak256(abi.encodePacked(_key))); }
    function getIntS(string memory _key) internal view returns (int256) { return stafiStorage.getInt(keccak256(abi.encodePacked(_key))); }
    function getBytes32S(string memory _key) internal view returns (bytes32) { return stafiStorage.getBytes32(keccak256(abi.encodePacked(_key))); }

    /// @dev Storage set methods
    function setAddress(bytes32 _key, address _value) internal { stafiStorage.setAddress(_key, _value); }
    function setUint(bytes32 _key, uint256 _value) internal { stafiStorage.setUint(_key, _value); }
    function setString(bytes32 _key, string memory _value) internal { stafiStorage.setString(_key, _value); }
    function setBytes(bytes32 _key, bytes memory _value) internal { stafiStorage.setBytes(_key, _value); }
    function setBool(bytes32 _key, bool _value) internal { stafiStorage.setBool(_key, _value); }
    function setInt(bytes32 _key, int256 _value) internal { stafiStorage.setInt(_key, _value); }
    function setBytes32(bytes32 _key, bytes32 _value) internal { stafiStorage.setBytes32(_key, _value); }
    function setAddressS(string memory _key, address _value) internal { stafiStorage.setAddress(keccak256(abi.encodePacked(_key)), _value); }
    function setUintS(string memory _key, uint256 _value) internal { stafiStorage.setUint(keccak256(abi.encodePacked(_key)), _value); }
    function setStringS(string memory _key, string memory _value) internal { stafiStorage.setString(keccak256(abi.encodePacked(_key)), _value); }
    function setBytesS(string memory _key, bytes memory _value) internal { stafiStorage.setBytes(keccak256(abi.encodePacked(_key)), _value); }
    function setBoolS(string memory _key, bool _value) internal { stafiStorage.setBool(keccak256(abi.encodePacked(_key)), _value); }
    function setIntS(string memory _key, int256 _value) internal { stafiStorage.setInt(keccak256(abi.encodePacked(_key)), _value); }
    function setBytes32S(string memory _key, bytes32 _value) internal { stafiStorage.setBytes32(keccak256(abi.encodePacked(_key)), _value); }

    /// @dev Storage delete methods
    function deleteAddress(bytes32 _key) internal { stafiStorage.deleteAddress(_key); }
    function deleteUint(bytes32 _key) internal { stafiStorage.deleteUint(_key); }
    function deleteString(bytes32 _key) internal { stafiStorage.deleteString(_key); }
    function deleteBytes(bytes32 _key) internal { stafiStorage.deleteBytes(_key); }
    function deleteBool(bytes32 _key) internal { stafiStorage.deleteBool(_key); }
    function deleteInt(bytes32 _key) internal { stafiStorage.deleteInt(_key); }
    function deleteBytes32(bytes32 _key) internal { stafiStorage.deleteBytes32(_key); }
    function deleteAddressS(string memory _key) internal { stafiStorage.deleteAddress(keccak256(abi.encodePacked(_key))); }
    function deleteUintS(string memory _key) internal { stafiStorage.deleteUint(keccak256(abi.encodePacked(_key))); }
    function deleteStringS(string memory _key) internal { stafiStorage.deleteString(keccak256(abi.encodePacked(_key))); }
    function deleteBytesS(string memory _key) internal { stafiStorage.deleteBytes(keccak256(abi.encodePacked(_key))); }
    function deleteBoolS(string memory _key) internal { stafiStorage.deleteBool(keccak256(abi.encodePacked(_key))); }
    function deleteIntS(string memory _key) internal { stafiStorage.deleteInt(keccak256(abi.encodePacked(_key))); }
    function deleteBytes32S(string memory _key) internal { stafiStorage.deleteBytes32(keccak256(abi.encodePacked(_key))); }


    /**
    * @dev Check if an address has this role
    */
    function roleHas(string memory _role, address _address) internal view returns (bool) {
        return getBool(keccak256(abi.encodePacked("access.role", _role, _address)));
    }

}

File 14 of 15 : DepositType.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

// Represents the type of deposits
enum DepositType {
    None,    // Marks an invalid deposit type
    FOUR,    // Require 4 ETH from the node operator to be matched with 28 ETH from user deposits
    EIGHT,   // Require 8 ETH from the node operator to be matched with 24 ETH from user deposits
    TWELVE,  // Require 12 ETH from the node operator to be matched with 20 ETH from user deposits
    SIXTEEN,  // Require 16 ETH from the node operator to be matched with 16 ETH from user deposits
    Empty    // Require 0 ETH from the node operator to be matched with 32 ETH from user deposits (trusted nodes only)
}

File 15 of 15 : StakingPoolStatus.sol
pragma solidity 0.7.6;

// SPDX-License-Identifier: GPL-3.0-only

// Represents a stakingpool's status within the network
enum StakingPoolStatus {
    Initialized,    // The stakingpool has been initialized and is awaiting a deposit of user ETH
    Prelaunch,      // The stakingpool has enough ETH to begin staking and is awaiting launch by the node
    Staking,        // The stakingpool is currently staking
    Withdrawn,   // The stakingpool has been withdrawn from by the node
    Dissolved       // The stakingpool has been dissolved and its user deposited ETH has been returned to the deposit pool
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_stafiStorageAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingPool","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"DepositAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"DepositReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"DepositRecycled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"ExcessWithdrawn","type":"event"},{"inputs":[],"name":"assignDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getAssignDepositsEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDepositEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExcessBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaximumDepositAssignments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinimumDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"receiveEtherWithdrawal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"recycleDissolvedDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"recycleDistributorDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"recycleWithdrawDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setAssignDepositsEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setDepositEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setMaximumDepositAssignments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setMinimumDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawExcessBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawExcessBalanceForLightNode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawExcessBalanceForSuperNode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawExcessBalanceForWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260008054610100600160a81b03191690553480156200002257600080fd5b5060405162002e7a38038062002e7a833981810160405260208110156200004857600080fd5b5051600080546001610100600160a81b03199091166101006001600160a01b038516021760ff191617905560408051808201909152601a81527f73657474696e67732e757365722e6465706f7369742e696e69740000000000006020820152620000b29062000135565b6200012e57620000c3600162000233565b620000cf60016200030e565b620000e1662386f26fc10000620003e6565b620000ed6002620004be565b60408051808201909152601a81527f73657474696e67732e757365722e6465706f7369742e696e697400000000000060208201526200012e90600162000596565b5062000869565b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca836040516020018082805190602001908083835b602083106200018f5780518252601f1990920191602091820191016200016e565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015620001ff57600080fd5b505afa15801562000214573d6000803e3d6000fd5b505050506040513d60208110156200022b57600080fd5b505192915050565b60408051808201909152600581526437bbb732b960d91b60208201526200025b903362000688565b806200028a575060408051808201909152600581526430b236b4b760d91b60208201526200028a903362000688565b620002cb576040805162461bcd60e51b815260206004820152601b602482015260008051602062002e5a833981519152604482015290519081900360640190fd5b60408051808201909152601881527f73657474696e67732e6465706f7369742e656e61626c6564000000000000000060208201526200030b908262000596565b50565b60408051808201909152600581526437bbb732b960d91b602082015262000336903362000688565b8062000365575060408051808201909152600581526430b236b4b760d91b602082015262000365903362000688565b620003a6576040805162461bcd60e51b815260206004820152601b602482015260008051602062002e5a833981519152604482015290519081900360640190fd5b60408051808201909152601f81527f73657474696e67732e6465706f7369742e61737369676e2e656e61626c65640060208201526200030b908262000596565b60408051808201909152600581526437bbb732b960d91b60208201526200040e903362000688565b806200043d575060408051808201909152600581526430b236b4b760d91b60208201526200043d903362000688565b6200047e576040805162461bcd60e51b815260206004820152601b602482015260008051602062002e5a833981519152604482015290519081900360640190fd5b60408051808201909152601881527f73657474696e67732e6465706f7369742e6d696e696d756d000000000000000060208201526200030b90826200073b565b60408051808201909152600581526437bbb732b960d91b6020820152620004e6903362000688565b8062000515575060408051808201909152600581526430b236b4b760d91b602082015262000515903362000688565b62000556576040805162461bcd60e51b815260206004820152601b602482015260008051602062002e5a833981519152604482015290519081900360640190fd5b60408051808201909152601f81527f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d0060208201526200030b90826200073b565b600060019054906101000a90046001600160a01b03166001600160a01b031663abfdcced836040516020018082805190602001908083835b60208310620005ef5780518252601f199092019160209182019101620005ce565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b1580156200066b57600080fd5b505af115801562000680573d6000803e3d6000fd5b505050505050565b600062000734838360405160200180806a6163636573732e726f6c6560a81b815250600b0183805190602001908083835b60208310620006da5780518252601f199092019160209182019101620006b9565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206200080e60201b60201c565b9392505050565b600060019054906101000a90046001600160a01b03166001600160a01b031663e2a4853a836040516020018082805190602001908083835b60208310620007945780518252601f19909201916020918201910162000773565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b1580156200066b57600080fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015620001ff57600080fd5b6125e180620008796000396000f3fe60806040526004361061012a5760003560e01c80635cb17a90116100ab5780637c697e741161006f5780637c697e74146102ee5780638554913b146102f6578063888b042f14610320578063cc88c3c814610335578063d0e30db01461035f578063e78ec42e146103675761012a565b80635cb17a90146102735780635fd58f0d1461029f57806363a5db9e146102a75780636ada7847146102d157806372f5158d146102e65761012a565b80633b474a65116100f25780633b474a65146101b45780633fa9c18d146101c957806347fa434a146101f357806354fd4d501461021c5780635b17d04b146102475761012a565b8063035cf1421461012f5780630a019eaf146101565780630c37d2dc1461016057806312065fe01461018a57806327c8f1931461019f575b600080fd5b34801561013b57600080fd5b50610144610391565b60408051918252519081900360200190f35b61015e6103d2565b005b34801561016c57600080fd5b5061015e6004803603602081101561018357600080fd5b50356105a3565b34801561019657600080fd5b506101446108ce565b3480156101ab57600080fd5b5061015e61097d565b3480156101c057600080fd5b50610144610cdb565b3480156101d557600080fd5b5061015e600480360360208110156101ec57600080fd5b5035610d1b565b3480156101ff57600080fd5b50610208610df0565b604080519115158252519081900360200190f35b34801561022857600080fd5b50610231610e30565b6040805160ff9092168252519081900360200190f35b34801561025357600080fd5b5061015e6004803603602081101561026a57600080fd5b50351515610e39565b34801561027f57600080fd5b5061015e6004803603602081101561029657600080fd5b50351515610f06565b61015e610fd8565b3480156102b357600080fd5b5061015e600480360360208110156102ca57600080fd5b50356111a6565b3480156102dd57600080fd5b5061020861146b565b61015e6114a6565b61015e61164a565b34801561030257600080fd5b5061015e6004803603602081101561031957600080fd5b5035611787565b34801561032c57600080fd5b50610144611946565b34801561034157600080fd5b5061015e6004803603602081101561035857600080fd5b5035611a1d565b61015e611bdc565b34801561037357600080fd5b5061015e6004803603602081101561038a57600080fd5b5035611e06565b60006103cc6040518060400160405280601881526020017773657474696e67732e6465706f7369742e6d696e696d756d60401b815250611ed3565b90505b90565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061048882604051602001808060008051602061251f83398151915281525060100182805190602001908083835b602083106104485780518252601f199092019160209182019101610429565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120611fcc565b6001600160a01b0316816001600160a01b0316146104db576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b8152503361054a82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461059d576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b50505050565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061061882604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461066b576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600d81526020016c7374616669576974686472617760981b815250336106dd82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614610730576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600d81526020016c7374616669576974686472617760981b815250612026565b9050600061078f6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506107996108ce565b8711156107d75760405162461bcd60e51b815260040180806020018281038252602381526020018061255f6023913960400191505060405180910390fd5b806001600160a01b0316633bed33ce886040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561081d57600080fd5b505af1158015610831573d6000803e3d6000fd5b50505050816001600160a01b031663439370b1886040518263ffffffff1660e01b81526004016000604051808303818588803b15801561087057600080fd5b505af1158015610884573d6000803e3d6000fd5b5050604080518b815242602082015281513395507f992f462cfb62e164bd03bf07baf2cffce83fbd9370cae10635842b20200121209450908190039091019150a250505050505050565b6000806108fc6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b9050806001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561094b57600080fd5b505afa15801561095f573d6000803e3d6000fd5b505050506040513d602081101561097557600080fd5b505191505090565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306109f282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614610a45576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b610a4d610df0565b610a5657610cd7565b6000610a8e6040518060400160405280601581526020017473746166695374616b696e67506f6f6c517565756560581b815250612026565b90506000610abd6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506000610ac9610cdb565b905060005b81811015610cd2576000846001600160a01b031663516123056040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1157600080fd5b505afa158015610b25573d6000803e3d6000fd5b505050506040513d6020811015610b3b57600080fd5b50519050801580610b52575080610b506108ce565b105b15610b5d5750610cd2565b6000856001600160a01b0316639a9580616040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610b9a57600080fd5b505af1158015610bae573d6000803e3d6000fd5b505050506040513d6020811015610bc457600080fd5b505160408051631df699e760e11b815260048101859052905191925082916001600160a01b03881691633bed33ce91602480830192600092919082900301818387803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b50505050806001600160a01b03166348146113846040518263ffffffff1660e01b81526004016000604051808303818588803b158015610c6657600080fd5b505af1158015610c7a573d6000803e3d6000fd5b50506040805187815242602082015281516001600160a01b03881695507fa1811054b7d96716259cff0d366c2f6405951e0efe00c8db3e237cbf77fe7be99450908190039091019150a2505050806001019050610ace565b505050505b5050565b60006103cc6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d00815250611ed3565b610d426040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610d6f5750610d6f6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610dae576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d0081525082612175565b50565b60006103cc6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e656e61626c656400815250612259565b60005460ff1681565b610e606040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610e8d5750610e8d6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610ecc576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded604051806040016040528060188152602001771cd95d1d1a5b99dccb99195c1bdcda5d0b995b98589b195960421b815250826122b0565b610f2d6040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610f5a5750610f5a6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610f99576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e656e61626c656400815250826122b0565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061104d82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b0316146110a0576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600d81526020016c7374616669576974686472617760981b8152503361111282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611165576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60408051348152426020820152815133927f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d406279196608512925928290030190a261059d612382565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061121b82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461126e576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250336112dc82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461132f576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b600061135b604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250612026565b9050600061138a6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506113946108ce565b8711156113d25760405162461bcd60e51b815260040180806020018281038252602381526020018061255f6023913960400191505060405180910390fd5b806001600160a01b0316633bed33ce886040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561141857600080fd5b505af115801561142c573d6000803e3d6000fd5b50505050816001600160a01b0316636c985a88886040518263ffffffff1660e01b81526004016000604051808303818588803b15801561087057600080fd5b60006103cc604051806040016040528060188152602001771cd95d1d1a5b99dccb99195c1bdcda5d0b995b98589b195960421b815250612259565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061151b82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461156e576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60408051717374616b696e67706f6f6c2e65786973747360701b60208083019190915233606081901b603284015283516026818503018152604690930190935281519101206115bc9061240d565b611604576040805162461bcd60e51b8152602060048201526014602482015273125b9d985b1a59081cdd185ada5b99c81c1bdbdb60621b604482015290519081900360640190fd5b60408051348152426020820152815133927f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d406279196608512925928290030190a2611645612382565b505050565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306116bf82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611712576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280601081526020016f39ba30b334a234b9ba3934b13aba37b960811b8152503361111282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306117fc82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461184f576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600e81526020016d737461666953757065724e6f646560901b815250336118c282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611915576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600e81526020016d737461666953757065724e6f646560901b815250612026565b60008061197f6040518060400160405280601581526020017473746166695374616b696e67506f6f6c517565756560581b815250612026565b90506000816001600160a01b031663e60b40bf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119bc57600080fd5b505afa1580156119d0573d6000803e3d6000fd5b505050506040513d60208110156119e657600080fd5b5051905060006119f46108ce565b9050808210611a0957600093505050506103cf565b611a138183612467565b93505050506103cf565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b81525030611a9282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611ae5576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600e81526020016d73746166694c696768744e6f646560901b81525033611b5882604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611bab576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600e81526020016d73746166694c696768744e6f646560901b815250612026565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b81525030611c5182604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611ca4576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b611cac61146b565b611ce75760405162461bcd60e51b815260040180806020018281038252602a815260200180612582602a913960400191505060405180910390fd5b611cef610391565b341015611d2d5760405162461bcd60e51b815260040180806020018281038252603a8152602001806124c5603a913960400191505060405180910390fd5b6000611d59604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250612026565b604080516317fe753f60e31b815234600482015233602482015290519192506001600160a01b0383169163bff3a9f89160448082019260009290919082900301818387803b158015611daa57600080fd5b505af1158015611dbe573d6000803e3d6000fd5b50506040805134815242602082015281513394507f7aa1a8eb998c779420645fc14513bf058edb347d95c2fc2e6845bdc22f88863193509081900390910190a2611645612382565b611e2d6040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80611e5a5750611e5a6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b611e99576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601881526020017773657474696e67732e6465706f7369742e6d696e696d756d60401b81525082612175565b60008060019054906101000a90046001600160a01b03166001600160a01b031663bd02d0f5836040516020018082805190602001908083835b60208310611f2b5780518252601f199092019160209182019101611f0c565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b505afa158015611fae573d6000803e3d6000fd5b505050506040513d6020811015611fc457600080fd5b505192915050565b60008060019054906101000a90046001600160a01b03166001600160a01b03166321f8a721836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b60008061207483604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b90506001600160a01b0381166120c6576040805162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081b9bdd08199bdd5b9960721b604482015290519081900360640190fd5b92915050565b600061216e838360405160200180806a6163636573732e726f6c6560a81b815250600b0183805190602001908083835b6020831061211b5780518252601f1990920191602091820191016120fc565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b031660601b8152601401925050506040516020818303038152906040528051906020012061240d565b9392505050565b600060019054906101000a90046001600160a01b03166001600160a01b031663e2a4853a836040516020018082805190602001908083835b602083106121cc5780518252601f1990920191602091820191016121ad565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561224557600080fd5b505af1158015610cd2573d6000803e3d6000fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca8360405160200180828051906020019080838360208310611f2b5780518252601f199092019160209182019101611f0c565b600060019054906101000a90046001600160a01b03166001600160a01b031663abfdcced836040516020018082805190602001908083835b602083106123075780518252601f1990920191602091820191016122e8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561224557600080fd5b60006123af6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b9050806001600160a01b03166398ea5fca346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156123ec57600080fd5b505af1158015612400573d6000803e3d6000fd5b5050505050610ded61097d565b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b6000828211156124be576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe546865206465706f736974656420616d6f756e74206973206c657373207468616e20746865206d696e696d756d206465706f7369742073697a65496e76616c6964206f72206f7574646174656420636f6e747261637400000000636f6e74726163742e61646472657373000000000000000000000000000000004163636f756e74206973206e6f74206120737570657220757365720000000000496e73756666696369656e742062616c616e636520666f72207769746864726177616c4465706f7369747320696e746f205374616669206172652063757272656e746c792064697361626c6564a2646970667358221220181c7d9b7044f5321b27fd1cd61b34cf94cf8f3f465a3f92855f47aba506712b64736f6c634300070600334163636f756e74206973206e6f742061207375706572207573657200000000000000000000000000000000006c2f7b6110a37b3b0fbdd811876be368df02e8b0

Deployed Bytecode

0x60806040526004361061012a5760003560e01c80635cb17a90116100ab5780637c697e741161006f5780637c697e74146102ee5780638554913b146102f6578063888b042f14610320578063cc88c3c814610335578063d0e30db01461035f578063e78ec42e146103675761012a565b80635cb17a90146102735780635fd58f0d1461029f57806363a5db9e146102a75780636ada7847146102d157806372f5158d146102e65761012a565b80633b474a65116100f25780633b474a65146101b45780633fa9c18d146101c957806347fa434a146101f357806354fd4d501461021c5780635b17d04b146102475761012a565b8063035cf1421461012f5780630a019eaf146101565780630c37d2dc1461016057806312065fe01461018a57806327c8f1931461019f575b600080fd5b34801561013b57600080fd5b50610144610391565b60408051918252519081900360200190f35b61015e6103d2565b005b34801561016c57600080fd5b5061015e6004803603602081101561018357600080fd5b50356105a3565b34801561019657600080fd5b506101446108ce565b3480156101ab57600080fd5b5061015e61097d565b3480156101c057600080fd5b50610144610cdb565b3480156101d557600080fd5b5061015e600480360360208110156101ec57600080fd5b5035610d1b565b3480156101ff57600080fd5b50610208610df0565b604080519115158252519081900360200190f35b34801561022857600080fd5b50610231610e30565b6040805160ff9092168252519081900360200190f35b34801561025357600080fd5b5061015e6004803603602081101561026a57600080fd5b50351515610e39565b34801561027f57600080fd5b5061015e6004803603602081101561029657600080fd5b50351515610f06565b61015e610fd8565b3480156102b357600080fd5b5061015e600480360360208110156102ca57600080fd5b50356111a6565b3480156102dd57600080fd5b5061020861146b565b61015e6114a6565b61015e61164a565b34801561030257600080fd5b5061015e6004803603602081101561031957600080fd5b5035611787565b34801561032c57600080fd5b50610144611946565b34801561034157600080fd5b5061015e6004803603602081101561035857600080fd5b5035611a1d565b61015e611bdc565b34801561037357600080fd5b5061015e6004803603602081101561038a57600080fd5b5035611e06565b60006103cc6040518060400160405280601881526020017773657474696e67732e6465706f7369742e6d696e696d756d60401b815250611ed3565b90505b90565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061048882604051602001808060008051602061251f83398151915281525060100182805190602001908083835b602083106104485780518252601f199092019160209182019101610429565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120611fcc565b6001600160a01b0316816001600160a01b0316146104db576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b8152503361054a82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461059d576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b50505050565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061061882604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461066b576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600d81526020016c7374616669576974686472617760981b815250336106dd82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614610730576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600d81526020016c7374616669576974686472617760981b815250612026565b9050600061078f6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506107996108ce565b8711156107d75760405162461bcd60e51b815260040180806020018281038252602381526020018061255f6023913960400191505060405180910390fd5b806001600160a01b0316633bed33ce886040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561081d57600080fd5b505af1158015610831573d6000803e3d6000fd5b50505050816001600160a01b031663439370b1886040518263ffffffff1660e01b81526004016000604051808303818588803b15801561087057600080fd5b505af1158015610884573d6000803e3d6000fd5b5050604080518b815242602082015281513395507f992f462cfb62e164bd03bf07baf2cffce83fbd9370cae10635842b20200121209450908190039091019150a250505050505050565b6000806108fc6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b9050806001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561094b57600080fd5b505afa15801561095f573d6000803e3d6000fd5b505050506040513d602081101561097557600080fd5b505191505090565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306109f282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614610a45576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b610a4d610df0565b610a5657610cd7565b6000610a8e6040518060400160405280601581526020017473746166695374616b696e67506f6f6c517565756560581b815250612026565b90506000610abd6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506000610ac9610cdb565b905060005b81811015610cd2576000846001600160a01b031663516123056040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1157600080fd5b505afa158015610b25573d6000803e3d6000fd5b505050506040513d6020811015610b3b57600080fd5b50519050801580610b52575080610b506108ce565b105b15610b5d5750610cd2565b6000856001600160a01b0316639a9580616040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610b9a57600080fd5b505af1158015610bae573d6000803e3d6000fd5b505050506040513d6020811015610bc457600080fd5b505160408051631df699e760e11b815260048101859052905191925082916001600160a01b03881691633bed33ce91602480830192600092919082900301818387803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b50505050806001600160a01b03166348146113846040518263ffffffff1660e01b81526004016000604051808303818588803b158015610c6657600080fd5b505af1158015610c7a573d6000803e3d6000fd5b50506040805187815242602082015281516001600160a01b03881695507fa1811054b7d96716259cff0d366c2f6405951e0efe00c8db3e237cbf77fe7be99450908190039091019150a2505050806001019050610ace565b505050505b5050565b60006103cc6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d00815250611ed3565b610d426040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610d6f5750610d6f6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610dae576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e6d6178696d756d0081525082612175565b50565b60006103cc6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e656e61626c656400815250612259565b60005460ff1681565b610e606040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610e8d5750610e8d6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610ecc576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded604051806040016040528060188152602001771cd95d1d1a5b99dccb99195c1bdcda5d0b995b98589b195960421b815250826122b0565b610f2d6040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80610f5a5750610f5a6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b610f99576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601f81526020017f73657474696e67732e6465706f7369742e61737369676e2e656e61626c656400815250826122b0565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061104d82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b0316146110a0576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600d81526020016c7374616669576974686472617760981b8152503361111282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611165576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60408051348152426020820152815133927f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d406279196608512925928290030190a261059d612382565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061121b82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461126e576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250336112dc82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461132f576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b600061135b604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250612026565b9050600061138a6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b90506113946108ce565b8711156113d25760405162461bcd60e51b815260040180806020018281038252602381526020018061255f6023913960400191505060405180910390fd5b806001600160a01b0316633bed33ce886040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561141857600080fd5b505af115801561142c573d6000803e3d6000fd5b50505050816001600160a01b0316636c985a88886040518263ffffffff1660e01b81526004016000604051808303818588803b15801561087057600080fd5b60006103cc604051806040016040528060188152602001771cd95d1d1a5b99dccb99195c1bdcda5d0b995b98589b195960421b815250612259565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b8152503061151b82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461156e576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60408051717374616b696e67706f6f6c2e65786973747360701b60208083019190915233606081901b603284015283516026818503018152604690930190935281519101206115bc9061240d565b611604576040805162461bcd60e51b8152602060048201526014602482015273125b9d985b1a59081cdd185ada5b99c81c1bdbdb60621b604482015290519081900360640190fd5b60408051348152426020820152815133927f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d406279196608512925928290030190a2611645612382565b505050565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306116bf82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611712576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280601081526020016f39ba30b334a234b9ba3934b13aba37b960811b8152503361111282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b815250306117fc82604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b03161461184f576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600e81526020016d737461666953757065724e6f646560901b815250336118c282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611915576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600e81526020016d737461666953757065724e6f646560901b815250612026565b60008061197f6040518060400160405280601581526020017473746166695374616b696e67506f6f6c517565756560581b815250612026565b90506000816001600160a01b031663e60b40bf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119bc57600080fd5b505afa1580156119d0573d6000803e3d6000fd5b505050506040513d60208110156119e657600080fd5b5051905060006119f46108ce565b9050808210611a0957600093505050506103cf565b611a138183612467565b93505050506103cf565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b81525030611a9282604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611ae5576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b6040518060400160405280600e81526020016d73746166694c696768744e6f646560901b81525033611b5882604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611bab576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b60006107606040518060400160405280600e81526020016d73746166694c696768744e6f646560901b815250612026565b6040518060400160405280601081526020016f1cdd18599a555cd95c91195c1bdcda5d60821b81525030611c5182604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b6001600160a01b0316816001600160a01b031614611ca4576040805162461bcd60e51b815260206004820152601c60248201526000805160206124ff833981519152604482015290519081900360640190fd5b611cac61146b565b611ce75760405162461bcd60e51b815260040180806020018281038252602a815260200180612582602a913960400191505060405180910390fd5b611cef610391565b341015611d2d5760405162461bcd60e51b815260040180806020018281038252603a8152602001806124c5603a913960400191505060405180910390fd5b6000611d59604051806040016040528060098152602001683922aa242a37b5b2b760b91b815250612026565b604080516317fe753f60e31b815234600482015233602482015290519192506001600160a01b0383169163bff3a9f89160448082019260009290919082900301818387803b158015611daa57600080fd5b505af1158015611dbe573d6000803e3d6000fd5b50506040805134815242602082015281513394507f7aa1a8eb998c779420645fc14513bf058edb347d95c2fc2e6845bdc22f88863193509081900390910190a2611645612382565b611e2d6040518060400160405280600581526020016437bbb732b960d91b815250336120cc565b80611e5a5750611e5a6040518060400160405280600581526020016430b236b4b760d91b815250336120cc565b611e99576040805162461bcd60e51b815260206004820152601b602482015260008051602061253f833981519152604482015290519081900360640190fd5b610ded6040518060400160405280601881526020017773657474696e67732e6465706f7369742e6d696e696d756d60401b81525082612175565b60008060019054906101000a90046001600160a01b03166001600160a01b031663bd02d0f5836040516020018082805190602001908083835b60208310611f2b5780518252601f199092019160209182019101611f0c565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b505afa158015611fae573d6000803e3d6000fd5b505050506040513d6020811015611fc457600080fd5b505192915050565b60008060019054906101000a90046001600160a01b03166001600160a01b03166321f8a721836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b60008061207483604051602001808060008051602061251f8339815191528152506010018280519060200190808383602083106104485780518252601f199092019160209182019101610429565b90506001600160a01b0381166120c6576040805162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081b9bdd08199bdd5b9960721b604482015290519081900360640190fd5b92915050565b600061216e838360405160200180806a6163636573732e726f6c6560a81b815250600b0183805190602001908083835b6020831061211b5780518252601f1990920191602091820191016120fc565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b031660601b8152601401925050506040516020818303038152906040528051906020012061240d565b9392505050565b600060019054906101000a90046001600160a01b03166001600160a01b031663e2a4853a836040516020018082805190602001908083835b602083106121cc5780518252601f1990920191602091820191016121ad565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561224557600080fd5b505af1158015610cd2573d6000803e3d6000fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca8360405160200180828051906020019080838360208310611f2b5780518252601f199092019160209182019101611f0c565b600060019054906101000a90046001600160a01b03166001600160a01b031663abfdcced836040516020018082805190602001908083835b602083106123075780518252601f1990920191602091820191016122e8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561224557600080fd5b60006123af6040518060400160405280600a81526020016939ba30b334a2ba3432b960b11b815250612026565b9050806001600160a01b03166398ea5fca346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156123ec57600080fd5b505af1158015612400573d6000803e3d6000fd5b5050505050610ded61097d565b60008060019054906101000a90046001600160a01b03166001600160a01b0316637ae1cfca836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f9a57600080fd5b6000828211156124be576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe546865206465706f736974656420616d6f756e74206973206c657373207468616e20746865206d696e696d756d206465706f7369742073697a65496e76616c6964206f72206f7574646174656420636f6e747261637400000000636f6e74726163742e61646472657373000000000000000000000000000000004163636f756e74206973206e6f74206120737570657220757365720000000000496e73756666696369656e742062616c616e636520666f72207769746864726177616c4465706f7369747320696e746f205374616669206172652063757272656e746c792064697361626c6564a2646970667358221220181c7d9b7044f5321b27fd1cd61b34cf94cf8f3f465a3f92855f47aba506712b64736f6c63430007060033

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

0000000000000000000000006c2f7b6110a37b3b0fbdd811876be368df02e8b0

-----Decoded View---------------
Arg [0] : _stafiStorageAddress (address): 0x6c2f7b6110a37b3B0fbdd811876be368df02E8B0

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000006c2f7b6110a37b3b0fbdd811876be368df02e8b0


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.