Contract 0x764a861e984B317745d4e9ceA9d4A71dBe0f5512 1

Contract Overview

Balance:
0 AVAX
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x85f2c8c21e77264540731b440158d4b52497302468ce60a391053f2a9457dfd4Set AUTO43870122022-01-03 14:25:12266 days 17 hrs ago0x3f09e942b0089b8af73ccb9603da8064b6c4b637 IN 0x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX0.00110412525
0x18ddacb9cd8df3dbb06015da3a52818c9517e221227599b6b61d8823608471b60x60a0604043869272022-01-03 14:22:12266 days 17 hrs ago0x3f09e942b0089b8af73ccb9603da8064b6c4b637 IN  Create: StakeManager0 AVAX0.036451125
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x300f1639efa5177a2d6336dac4a15cdde3feb0038e2ed9e3546e1b67758fb8a1103414562022-06-03 3:46:53116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x300f1639efa5177a2d6336dac4a15cdde3feb0038e2ed9e3546e1b67758fb8a1103414562022-06-03 3:46:53116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x26d9db03cdf281482d525ad39cd79a3b389db6c2bcfd99874e905f6ccd17cc14103414512022-06-03 3:46:39116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x26d9db03cdf281482d525ad39cd79a3b389db6c2bcfd99874e905f6ccd17cc14103414512022-06-03 3:46:39116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0xa0767af73e2f75b033e8153b58358b6cd7370df85cbb9c090ad35273842baebb103414422022-06-03 3:46:14116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0xa0767af73e2f75b033e8153b58358b6cd7370df85cbb9c090ad35273842baebb103414422022-06-03 3:46:14116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x37d138bb334d10940f78ad843ba63bc1d6d8200861b606d4c70548c3dcb0aa75103414342022-06-03 3:45:52116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x37d138bb334d10940f78ad843ba63bc1d6d8200861b606d4c70548c3dcb0aa75103414342022-06-03 3:45:52116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0xe56e0a5841f3b8d0a6cc4262ec5cd95dc11c88f98e4198644b423a93af1fa399103413532022-06-03 3:42:21116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0xe56e0a5841f3b8d0a6cc4262ec5cd95dc11c88f98e4198644b423a93af1fa399103413532022-06-03 3:42:21116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0xaa56d887162e31c01d87cc4c54801de8224d33eec2c07e8d00314ab6956759fb103413372022-06-03 3:41:49116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0xaa56d887162e31c01d87cc4c54801de8224d33eec2c07e8d00314ab6956759fb103413372022-06-03 3:41:49116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x62841194bd1035eec4ead8c81f1688a6e5bfb77f14bc73df20ad63707a5aa23b103412702022-06-03 3:39:23116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x62841194bd1035eec4ead8c81f1688a6e5bfb77f14bc73df20ad63707a5aa23b103412702022-06-03 3:39:23116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x2cbaf81d556918e0e249feb7b61797cd8f82a837635515a88065e6fcc8a4070a103412392022-06-03 3:38:11116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x2cbaf81d556918e0e249feb7b61797cd8f82a837635515a88065e6fcc8a4070a103412392022-06-03 3:38:11116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x8be55d1b35f82521e61e728fb0fe84fac0cd604ea18c1c6b63dc47595323c852103412342022-06-03 3:37:56116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x8be55d1b35f82521e61e728fb0fe84fac0cd604ea18c1c6b63dc47595323c852103412342022-06-03 3:37:56116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x109fe37c5b542e7f2283afa3d6daad189e5113f64b5c4ca2200c8a0d7727494b103412222022-06-03 3:37:28116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x109fe37c5b542e7f2283afa3d6daad189e5113f64b5c4ca2200c8a0d7727494b103412222022-06-03 3:37:28116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x8633087ca9e03dcfec476f3a59fb8e8b710464d72cc629f5f9377b2f1973c613103411982022-06-03 3:36:31116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x8633087ca9e03dcfec476f3a59fb8e8b710464d72cc629f5f9377b2f1973c613103411982022-06-03 3:36:31116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x7ae4d52a3a82cb54ff23335d8cf187147323c709f57958e34229b91d486c0d4a103411892022-06-03 3:36:13116 days 3 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
0x7ae4d52a3a82cb54ff23335d8cf187147323c709f57958e34229b91d486c0d4a103411892022-06-03 3:36:13116 days 3 hrs ago 0xa0f25b796dd59e504077f87caea1c0472cd6b7b40x764a861e984b317745d4e9cea9d4a71dbe0f55120 AVAX
0x703cd8f8be7ae30f8a29b2942577e4a15cce2eb1ea785fa72cd6f0fb3a0092ae103409922022-06-03 3:28:52116 days 4 hrs ago 0x764a861e984b317745d4e9cea9d4a71dbe0f5512 0x8521f6c3a287b263b066513f4b47a979d0e83fc60 AVAX
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StakeManager

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 9 : StakeManager.sol
pragma solidity 0.8.6;


import "IERC777.sol";
import "ReentrancyGuard.sol";
import "IERC777Recipient.sol";
import "IERC1820Registry.sol";
import "IStakeManager.sol";
import "IOracle.sol";
import "Shared.sol";


contract StakeManager is IStakeManager, Shared, ReentrancyGuard, IERC777Recipient {

    uint public constant STAN_STAKE = 10000 * _E_18;
    uint public constant BLOCKS_IN_EPOCH = 100;
    bytes private constant _stakingIndicator = "staking";

    IOracle private immutable _oracle;
    // AUTO ERC777
    IERC777 private _AUTO;
    bool private _AUTOSet = false;
    IERC1820Registry constant private _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
    bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256('ERC777TokensRecipient');
    uint private _totalStaked = 0;
    // Needed so that receiving AUTO is rejected unless it's indicated
    // that's it's used for staking and therefore not an accident (protect users)
    Executor private _executor;
    mapping(address => uint) private _stakerToStakedAmount;
    address[] private _stakes;


    // Pasted for convenience here, defined in IStakeManager
    // struct Executor{
    //     address addr;
    //     uint96 forEpoch;
    // }


    event Staked(address staker, uint amount);
    event Unstaked(address staker, uint amount);


    constructor(IOracle oracle) {
        _oracle = oracle;
        _ERC1820_REGISTRY.setInterfaceImplementer(address(this), TOKENS_RECIPIENT_INTERFACE_HASH, address(this));
    }


    function setAUTO(IERC777 AUTO) external {
        require(!_AUTOSet, "SM: AUTO already set");
        _AUTOSet = true;
        _AUTO = AUTO;
    }


    //////////////////////////////////////////////////////////////
    //                                                          //
    //                          Getters                         //
    //                                                          //
    //////////////////////////////////////////////////////////////

    function getOracle() external view override returns (IOracle) {
        return _oracle;
    }

    function getAUTOAddr() external view override returns (address) {
        return address(_AUTO);
    }

    function getTotalStaked() external view override returns (uint) {
        return _totalStaked;
    }

    function getStake(address staker) external view override returns (uint) {
        return _stakerToStakedAmount[staker];
    }

    function getStakes() external view override returns (address[] memory) {
        return _stakes;
    }

    function getStakesLength() external view override returns (uint) {
        return _stakes.length;
    }

    function getStakesSlice(uint startIdx, uint endIdx) external view override returns (address[] memory) {
        address[] memory slice = new address[](endIdx - startIdx);
        uint sliceIdx = 0;
        for (uint stakeIdx = startIdx; stakeIdx < endIdx; stakeIdx++) {
            slice[sliceIdx] = _stakes[stakeIdx];
            sliceIdx++;
        }

        return slice;
    }

    function getCurEpoch() public view override returns (uint96) {
        return uint96((block.number / BLOCKS_IN_EPOCH) * BLOCKS_IN_EPOCH);
    }

    function getExecutor() external view override returns (Executor memory) {
        return _executor;
    }

    function isCurExec(address addr) external view override returns (bool) {
        // So that the storage is only loaded once
        Executor memory ex = _executor;
        if (ex.forEpoch == getCurEpoch()) {
            if (ex.addr == addr) {
                return true;
            } else {
                return false;
            }
        }
        // If there're no stakes, allow anyone to be the executor so that a random
        // person can bootstrap the network and nobody needs to be sent any coins
        if (_stakes.length == 0) { return true; }

        return false;
    }

    function getUpdatedExecRes() public view override returns (uint96 epoch, uint randNum, uint idxOfExecutor, address exec) {
        epoch = getCurEpoch();
        // So that the storage is only loaded once
        uint stakesLen = _stakes.length;
        // If the executor is out of date and the system already has stake,
        // choose a new executor. This will do nothing if the system is starting
        // and allow someone to stake without needing there to already be existing stakes
        if (_executor.forEpoch != epoch && stakesLen > 0) {
            // -1 because blockhash(seed) in Oracle will return 0x00 if the
            // seed == this block's height
            randNum = _oracle.getRandNum(epoch - 1);
            idxOfExecutor = randNum % stakesLen;
            exec = _stakes[idxOfExecutor];
        }
    }


    //////////////////////////////////////////////////////////////
    //                                                          //
    //                          Staking                         //
    //                                                          //
    //////////////////////////////////////////////////////////////

    function updateExecutor() external override nonReentrant noFish returns (uint, uint, uint, address) {
        return _updateExecutor();
    }

    function isUpdatedExec(address addr) external override nonReentrant noFish returns (bool) {
        // So that the storage is only loaded once
        Executor memory ex = _executor;
        if (ex.forEpoch == getCurEpoch()) {
            if (ex.addr == addr) {
                return true;
            } else {
                return false;
            }
        } else {
            (, , , address exec) = _updateExecutor();
            if (exec == addr) { return true; }
        }
        if (_stakes.length == 0) { return true; }

        return false;
    }

    // The 1st stake/unstake of an epoch shouldn't change the executor, otherwise
    // a staker could precalculate the effect of how much they stake in order to
    // game the staker selection algo
    function stake(uint numStakes) external nzUint(numStakes) nonReentrant updateExec noFish override {
        uint amount = numStakes * STAN_STAKE;
        _stakerToStakedAmount[msg.sender] += amount;
        // So that the storage is only loaded once
        IERC777 AUTO = _AUTO;

        // Deposit the coins
        uint balBefore = AUTO.balanceOf(address(this));
        AUTO.operatorSend(msg.sender, address(this), amount, "", _stakingIndicator);
        // This check is a bit unnecessary, but better to be paranoid than r3kt
        require(AUTO.balanceOf(address(this)) - balBefore == amount, "SM: transfer bal check failed");

        for (uint i; i < numStakes; i++) {
            _stakes.push(msg.sender);
        }

        _totalStaked += amount;
        emit Staked(msg.sender, amount);
    }

    function unstake(uint[] calldata idxs) external nzUintArr(idxs) nonReentrant updateExec noFish override {
        uint amount = idxs.length * STAN_STAKE;
        require(amount <= _stakerToStakedAmount[msg.sender], "SM: not enough stake, peasant");

        for (uint i = 0; i < idxs.length; i++) {
            require(_stakes[idxs[i]] == msg.sender, "SM: idx is not you");
            require(idxs[i] < _stakes.length, "SM: idx out of bounds");
            // Update stakes by moving the last element to the
            // element we're wanting to delete (so it doesn't leave gaps, which is
            // necessary for the _updateExecutor algo)
            _stakes[idxs[i]] = _stakes[_stakes.length-1];
            _stakes.pop();
        }
        
        _stakerToStakedAmount[msg.sender] -= amount;
        _AUTO.send(msg.sender, amount, _stakingIndicator);
        _totalStaked -= amount;
        emit Unstaked(msg.sender, amount);
    }

    function _updateExecutor() private returns (uint96 epoch, uint randNum, uint idxOfExecutor, address exec) {
        (epoch, randNum, idxOfExecutor, exec) = getUpdatedExecRes();
        if (exec != _ADDR_0) {
            _executor = Executor(exec, epoch);
        }
    }

    modifier updateExec() {
        // Need to update executor at the start of stake/unstake as opposed to the
        // end of the fcns because otherwise, for the 1st stake/unstake tx in an
        // epoch, someone could influence the outcome of the executor by precalculating
        // the outcome based on how much they stake and unfairly making themselves the executor
        _updateExecutor();
        _;
    }

    // Ensure the contract is fully collateralised every time
    modifier noFish() {
        _;
        // >= because someone could send some tokens to this contract and disable it if it was ==
        require(_AUTO.balanceOf(address(this)) >= _totalStaked, "SM: something fishy here");
    }

    function tokensReceived(
        address _operator,
        address _from,
        address _to,
        uint256 _amount,
        bytes calldata _data,
        bytes calldata _operatorData
    ) external override {
        require(msg.sender == address(_AUTO), "SM: non-AUTO token");
        require(keccak256(_operatorData) == keccak256(_stakingIndicator), "SM: sending by mistake");
    }

}

File 2 of 9 : IERC777.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC777Token standard as defined in the EIP.
 *
 * This contract uses the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
 * token holders and recipients react to token movements by using setting implementers
 * for the associated interfaces in said registry. See {IERC1820Registry} and
 * {ERC1820Implementer}.
 */
interface IERC777 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For most token contracts, this value will equal 1.
     */
    function granularity() external view returns (uint256);

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

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function send(
        address recipient,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external;

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See {operatorSend} and {operatorBurn}.
     */
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor}.
     *
     * Emits an {AuthorizedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external;

    /**
     * @dev Revoke an account's operator status for the caller.
     *
     * See {isOperatorFor} and {defaultOperators}.
     *
     * Emits a {RevokedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external;

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if {authorizeOperator} was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * {revokeOperator}, in which case {isOperatorFor} will return false.
     */
    function defaultOperators() external view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );

    event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

    event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}

File 3 of 9 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 4 of 9 : IERC777Recipient.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
 *
 * Accounts can be notified of {IERC777} tokens being sent to them by having a
 * contract implement this interface (contract holders can be their own
 * implementer) and registering it on the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
 *
 * See {IERC1820Registry} and {ERC1820Implementer}.
 */
interface IERC777Recipient {
    /**
     * @dev Called by an {IERC777} token contract whenever tokens are being
     * moved or created into a registered account (`to`). The type of operation
     * is conveyed by `from` being the zero address or not.
     *
     * This call occurs _after_ the token contract's state is updated, so
     * {IERC777-balanceOf}, etc., can be used to query the post-operation state.
     *
     * This function may revert to prevent the operation from being executed.
     */
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external;
}

File 5 of 9 : IERC1820Registry.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the global ERC1820 Registry, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
 * implementers for interfaces in this registry, as well as query support.
 *
 * Implementers may be shared by multiple accounts, and can also implement more
 * than a single interface for each account. Contracts can implement interfaces
 * for themselves, but externally-owned accounts (EOA) must delegate this to a
 * contract.
 *
 * {IERC165} interfaces can also be queried via the registry.
 *
 * For an in-depth explanation and source code analysis, see the EIP text.
 */
interface IERC1820Registry {
    /**
     * @dev Sets `newManager` as the manager for `account`. A manager of an
     * account is able to set interface implementers for it.
     *
     * By default, each account is its own manager. Passing a value of `0x0` in
     * `newManager` will reset the manager to this initial state.
     *
     * Emits a {ManagerChanged} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     */
    function setManager(address account, address newManager) external;

    /**
     * @dev Returns the manager for `account`.
     *
     * See {setManager}.
     */
    function getManager(address account) external view returns (address);

    /**
     * @dev Sets the `implementer` contract as ``account``'s implementer for
     * `interfaceHash`.
     *
     * `account` being the zero address is an alias for the caller's address.
     * The zero address can also be used in `implementer` to remove an old one.
     *
     * See {interfaceHash} to learn how these are created.
     *
     * Emits an {InterfaceImplementerSet} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
     * end in 28 zeroes).
     * - `implementer` must implement {IERC1820Implementer} and return true when
     * queried for support, unless `implementer` is the caller. See
     * {IERC1820Implementer-canImplementInterfaceForAddress}.
     */
    function setInterfaceImplementer(
        address account,
        bytes32 _interfaceHash,
        address implementer
    ) external;

    /**
     * @dev Returns the implementer of `interfaceHash` for `account`. If no such
     * implementer is registered, returns the zero address.
     *
     * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
     * zeroes), `account` will be queried for support of it.
     *
     * `account` being the zero address is an alias for the caller's address.
     */
    function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);

    /**
     * @dev Returns the interface hash for an `interfaceName`, as defined in the
     * corresponding
     * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
     */
    function interfaceHash(string calldata interfaceName) external pure returns (bytes32);

    /**
     * @notice Updates the cache with whether the contract implements an ERC165 interface or not.
     * @param account Address of the contract for which to update the cache.
     * @param interfaceId ERC165 interface for which to update the cache.
     */
    function updateERC165Cache(address account, bytes4 interfaceId) external;

    /**
     * @notice Checks whether a contract implements an ERC165 interface or not.
     * If the result is not cached a direct lookup on the contract address is performed.
     * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
     * {updateERC165Cache} with the contract address.
     * @param account Address of the contract to check.
     * @param interfaceId ERC165 interface to check.
     * @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);

    /**
     * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
     * @param account Address of the contract to check.
     * @param interfaceId ERC165 interface to check.
     * @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);

    event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);

    event ManagerChanged(address indexed account, address indexed newManager);
}

File 6 of 9 : IStakeManager.sol
pragma solidity 0.8.6;


import "IOracle.sol";


/**
* @title    StakeManager
* @notice   A lightweight Proof of Stake contract that allows
*           staking of AUTO tokens. Instead of a miner winning
*           the ability to produce a block, the algorithm selects
*           a staker for a period of 100 blocks to be the executor.
*           the executor has the exclusive right to execute requests
*           in the Registry contract. The Registry checks with StakeManager
*           who is allowed to execute requests at any given time
* @author   Quantaf1re (James Key)
*/
interface IStakeManager {

    struct Executor{
        address addr;
        uint96 forEpoch;
    }


    //////////////////////////////////////////////////////////////
    //                                                          //
    //                          Getters                         //
    //                                                          //
    //////////////////////////////////////////////////////////////
    
    function getOracle() external view returns (IOracle);

    function getAUTOAddr() external view returns (address);

    function getTotalStaked() external view returns (uint);

    function getStake(address staker) external view returns (uint);

    /**
     * @notice  Returns the array of stakes. Every element in the array represents
     *          `STAN_STAKE` amount of AUTO tokens staked for that address. Addresses
     *          can be in the array arbitrarily many times
     */
    function getStakes() external view returns (address[] memory);

    /**
     * @notice  The length of `_stakes`, i.e. the total staked when multiplied by `STAN_STAKE`
     */
    function getStakesLength() external view returns (uint);

    /**
     * @notice  The same as getStakes except it returns only part of the array - the
     *          array might grow so large that retrieving it costs more gas than the
     *          block gas limit and therefore brick the contract. E.g. for an array of
     *          x = [4, 5, 6, 7], x[1, 2] returns [5], the same as lists in Python
     * @param startIdx  [uint] The starting index from which to start getting the slice (inclusive)
     * @param endIdx    [uint] The ending index from which to start getting the slice (exclusive)
     */
    function getStakesSlice(uint startIdx, uint endIdx) external view returns (address[] memory);

    /**
     * @notice  Returns the current epoch. Goes in increments of 100. E.g. the epoch
     *          for 420 is 400, and 42069 is 42000
     */
    function getCurEpoch() external view returns (uint96);

    /**
     * @notice  Returns the currently stored Executor - which might be old,
     *          i.e. for a previous epoch
     */
    function getExecutor() external view returns (Executor memory);

    /**
     * @notice  Returns whether `addr` is the current executor for this epoch. If the executor
     *          is outdated (i.e. for a previous epoch), it'll return false regardless of `addr`
     * @param addr  [address] The address to check
     * @return  [bool] Whether or not `addr` is the current executor for this epoch
     */
    function isCurExec(address addr) external view returns (bool);

    /**
     * @notice  Returns what the result of updating the executor would be, but doesn't actually
     *          make any changes
     * @return epoch    Returns the relevant variables for determining the new executor if the executor
     *          can be updated currently. It can only be updated currently if the stored executor
     *          is for a previous epoch, and there is some stake in the system. If the executor
     *          can't be updated currently, then everything execpt `epoch` will return 0
     */
    function getUpdatedExecRes() external view returns (uint96 epoch, uint randNum, uint idxOfExecutor, address exec);

    //////////////////////////////////////////////////////////////
    //                                                          //
    //                          Staking                         //
    //                                                          //
    //////////////////////////////////////////////////////////////

    /**
     * @notice  Updates the executor. Calls `getUpdatedExecRes` to know. Makes the changes
     *          only if the executor can be updated
     * @return  Returns the relevant variables for determining the new executor if the executor
     *          can be updated currently
     */
    function updateExecutor() external returns (uint, uint, uint, address);

    /**
     * @notice  Checks if the stored executor is for the current epoch - if it is,
     *          then it returns whether `addr` is the current exec or not. If the epoch
     *          is old, then it updates the executor, then returns whether `addr` is the
     *          current executor or not. If there's no stake in the system, returns true
     * @param addr  [address] The address to check
     * @return  [bool] Returns whether or not `addr` is the current, updated executor
     */
    function isUpdatedExec(address addr) external returns (bool);

    /**
     * @notice  Stake a set amount of AUTO tokens. A set amount of tokens needs to be used
     *          so that a random number can be used to look up a specific index in the array.
     *          We want the staker to be chosen proportional to their stake, which requires
     *          knowing their stake in relation to everyone else. If you could stake any
     *          amount of AUTO tokens, then the contract would have to store that amount
     *          along with the staker and, crucially, would require iteration over the
     *          whole array. E.g. if the random number in this PoS system was 0.2, then
     *          you could calculate the amount of proportional stake that translates to.
     *          If the total stakes was 10^6, then whichever staker in the array at token
     *          position 200,000 would be the winner, but that requires going through every
     *          piece of staking info in the first part of the array in order to calculate
     *          the running cumulative and know who happens to have the slot where the
     *          cumulative stake is 200,000. This has problems when the staking array is
     *          so large that it costs more than the block gas limit to iterate over, which
     *          would brick the contract, but also just generally costs alot of gas. Having
     *          a set amount of AUTO tokens means you already know everything about every
     *          element in the array therefore don't need to iterate over it.
     *          Calling this will add the caller to the array. Calling this will first try
     *          and set the executor so that the caller can't precalculate and affect the outcome
     *          by deciding the size of `numStakes`
     * @param numStakes  [uint] The number of `STAN_STAKE` to stake and therefore how many
     *          slots in the array to add the user to
     */
    function stake(uint numStakes) external;

    /**
     * @notice  Unstake AUTO tokens. Calling this will first try and set the executor so that
     *          the caller can't precalculate and affect the outcome by deciding the size of
     *          `numStakes`
     * @dev     Instead of just deleting the array slot, this takes the last element, copies
     *          it to the slot being unstaked, and pops off the original copy of the replacement
     *          from the end of the array, so that there are no gaps left, such that 0x00...00
     *          can never be chosen as an executor
     * @param idxs  [uint[]] The indices of the user's slots, in order of which they'll be
     *              removed, which is not necessariy the current indices. E.g. if the `_staking`
     *              array is [a, b, c, b], and `idxs` = [1, 3], then i=1 will first get
     *              replaced by i=3 and look like [a, b, c], then it would try and replace i=3
     *              by the end of the array...but i=3 no longer exists, so it'll revert. In this
     *              case, `idxs` would need to be [1, 1], which would result in [a, c]. It's
     *              recommended to choose idxs in descending order so that you don't have to
     *              take account of this behaviour - that way you can just use indexes
     *              as they are already without alterations
     */
    function unstake(uint[] calldata idxs) external;
}

File 7 of 9 : IOracle.sol
pragma solidity 0.8.6;


import "IPriceOracle.sol";


interface IOracle {
    // Needs to output the same number for the whole epoch
    function getRandNum(uint salt) external view returns (uint);

    function getPriceOracle() external view returns (IPriceOracle);

    function getAUTOPerETH() external view returns (uint);

    function getGasPriceFast() external view returns (uint);

    function setPriceOracle(IPriceOracle newPriceOracle) external;

    function defaultPayIsAUTO() external view returns (bool);

    function setDefaultPayIsAUTO(bool newDefaultPayIsAUTO) external;
}

File 8 of 9 : IPriceOracle.sol
pragma solidity 0.8.6;


interface IPriceOracle {

    function getAUTOPerETH() external view returns (uint);

    function getGasPriceFast() external view returns (uint);
}

File 9 of 9 : Shared.sol
pragma solidity 0.8.6;


/**
* @title    Shared contract
* @notice   Holds constants and modifiers that are used in multiple contracts
* @dev      It would be nice if this could be a library, but modifiers can't be exported :(
* @author   Quantaf1re (James Key)
*/
abstract contract Shared {
    address constant internal _ADDR_0 = address(0);
    uint constant internal _E_18 = 10**18;


    /// @dev    Checks that a uint isn't nonzero/empty
    modifier nzUint(uint u) {
        require(u != 0, "Shared: uint input is empty");
        _;
    }

    /// @dev    Checks that a uint array isn't nonzero/empty
    modifier nzUintArr(uint[] calldata arr) {
        require(arr.length > 0, "Shared: uint arr input is empty");
        _;
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"contract IOracle","name":"oracle","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"BLOCKS_IN_EPOCH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAN_STAKE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAUTOAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurEpoch","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExecutor","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint96","name":"forEpoch","type":"uint96"}],"internalType":"struct IStakeManager.Executor","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakes","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIdx","type":"uint256"},{"internalType":"uint256","name":"endIdx","type":"uint256"}],"name":"getStakesSlice","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUpdatedExecRes","outputs":[{"internalType":"uint96","name":"epoch","type":"uint96"},{"internalType":"uint256","name":"randNum","type":"uint256"},{"internalType":"uint256","name":"idxOfExecutor","type":"uint256"},{"internalType":"address","name":"exec","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isCurExec","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isUpdatedExec","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC777","name":"AUTO","type":"address"}],"name":"setAUTO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numStakes","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_operatorData","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"idxs","type":"uint256[]"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateExecutor","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

60a06040526001805460ff60a01b19169055600060025534801561002257600080fd5b50604051611994380380611994833981016040819052610041916100ef565b6001600055606081901b6001600160601b0319166080526040516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156100d157600080fd5b505af11580156100e5573d6000803e3d6000fd5b505050505061011f565b60006020828403121561010157600080fd5b81516001600160a01b038116811461011857600080fd5b9392505050565b60805160601c61185061014460003960008181610255015261119f01526118506000f3fe608060405234801561001057600080fd5b50600436106101205760003560e01c8063833b1fce116100ad578063d34f304b11610071578063d34f304b146102de578063df4b4776146102ef578063e449f341146102f7578063ec8ea74f1461030a578063f862a7b31461034557600080fd5b8063833b1fce14610253578063885964a41461028d578063a694fc3a146102b0578063aba21dfd146102c3578063ac4a8703146102cb57600080fd5b80634bade67e116100f45780634bade67e146101795780635fce0b2a146101815780636c1032af146101b25780637776f8f91461020a5780637a7664601461022a57600080fd5b806223de29146101255780630917e7761461013a5780633fd51c471461015157806344c0e04c14610159575b600080fd5b6101386101333660046113d0565b610358565b005b6002545b6040519081526020015b60405180910390f35b61013e610452565b61016c610167366004611528565b610469565b6040516101489190611620565b60055461013e565b61018961054c565b604080519485526020850193909352918301526001600160a01b03166060820152608001610148565b6040805180820182526000808252602091820152815180830183526003546001600160a01b0381168083526001600160601b03600160a01b909204821692840192835284519081529151169181019190915201610148565b610212610641565b6040516001600160601b039091168152602001610148565b61013e6102383660046113ac565b6001600160a01b031660009081526004602052604090205490565b7f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b039091168152602001610148565b6102a061029b3660046113ac565b61065e565b6040519015158152602001610148565b6101386102be3660046114f6565b6106f4565b61013e606481565b6102a06102d93660046113ac565b610aed565b6001546001600160a01b0316610275565b61016c610c8e565b610138610305366004611481565b610cf0565b610312611156565b604080516001600160601b0390951685526020850193909352918301526001600160a01b03166060820152608001610148565b6101386103533660046113ac565b611286565b6001546001600160a01b031633146103ac5760405162461bcd60e51b815260206004820152601260248201527129a69d103737b716a0aaaa27903a37b5b2b760711b60448201526064015b60405180910390fd5b60408051808201825260078152667374616b696e6760c81b602090910152517f8f6d06a17e13511155ffa96004c22afae6a03438b8fed74cb1cf441168df3f12906103fa9084908490611597565b6040518091039020146104485760405162461bcd60e51b8152602060048201526016602482015275534d3a2073656e64696e67206279206d697374616b6560501b60448201526064016103a3565b5050505050505050565b610466670de0b6b3a7640000612710611707565b81565b606060006104778484611726565b67ffffffffffffffff81111561048f5761048f6117ec565b6040519080825280602002602001820160405280156104b8578160200160208202803683370190505b5090506000845b8481101561054257600581815481106104da576104da6117d6565b9060005260206000200160009054906101000a90046001600160a01b031683838151811061050a5761050a6117d6565b6001600160a01b03909216602092830291909101909101528161052c81611765565b925050808061053a90611765565b9150506104bf565b5090949350505050565b600080600080600260005414156105755760405162461bcd60e51b81526004016103a3906116a4565b6002600055610582611300565b6002546001546040516370a0823160e01b81523060048201526001600160601b0390961699509397509195509350916001600160a01b03909116906370a082319060240160206040518083038186803b1580156105de57600080fd5b505afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610616919061150f565b10156106345760405162461bcd60e51b81526004016103a39061166d565b6001600055929391929091565b6000606461064f81436116f3565b6106599190611707565b905090565b604080518082019091526003546001600160a01b0381168252600160a01b90046001600160601b03166020820152600090610697610641565b6001600160601b031681602001516001600160601b031614156106e457826001600160a01b031681600001516001600160a01b031614156106db5750600192915050565b50600092915050565b6005546106db5750600192915050565b80806107425760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016103a3565b600260005414156107655760405162461bcd60e51b81526004016103a3906116a4565b6002600055610772611300565b505050506000670de0b6b3a764000061271061078e9190611707565b6107989084611707565b336000908152600460205260408120805492935083929091906107bc9084906116db565b90915550506001546040516370a0823160e01b81523060048201526001600160a01b039091169060009082906370a082319060240160206040518083038186803b15801561080957600080fd5b505afa15801561081d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610841919061150f565b60408051808201825260078152667374616b696e6760c81b602082015290516362ad1b8360e01b81529192506001600160a01b038416916362ad1b839161089191339130918991906004016115a7565b600060405180830381600087803b1580156108ab57600080fd5b505af11580156108bf573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201528592508391506001600160a01b038516906370a082319060240160206040518083038186803b15801561090657600080fd5b505afa15801561091a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093e919061150f565b6109489190611726565b146109955760405162461bcd60e51b815260206004820152601d60248201527f534d3a207472616e736665722062616c20636865636b206661696c656400000060448201526064016103a3565b60005b858110156109f457600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b03191633179055806109ec81611765565b915050610998565b508260026000828254610a0791906116db565b909155505060408051338152602081018590527f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d910160405180910390a150506002546001546040516370a0823160e01b81523060048201529192506001600160a01b0316906370a082319060240160206040518083038186803b158015610a8e57600080fd5b505afa158015610aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac6919061150f565b1015610ae45760405162461bcd60e51b81526004016103a39061166d565b50506001600055565b600060026000541415610b125760405162461bcd60e51b81526004016103a3906116a4565b6002600055604080518082019091526003546001600160a01b0381168252600160a01b90046001600160601b03166020820152610b4d610641565b6001600160601b031681602001516001600160601b03161415610b9c57826001600160a01b031681600001516001600160a01b03161415610b92576001915050610be8565b6000915050610be8565b6000610ba6611300565b9350505050836001600160a01b0316816001600160a01b03161415610bd057600192505050610be8565b50600554610be2576001915050610be8565b60009150505b6002546001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610c2e57600080fd5b505afa158015610c42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c66919061150f565b1015610c845760405162461bcd60e51b81526004016103a39061166d565b6001600055919050565b60606005805480602002602001604051908101604052809291908181526020018280548015610ce657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610cc8575b5050505050905090565b818180610d3f5760405162461bcd60e51b815260206004820152601f60248201527f5368617265643a2075696e742061727220696e70757420697320656d7074790060448201526064016103a3565b60026000541415610d625760405162461bcd60e51b81526004016103a3906116a4565b6002600055610d6f611300565b505050506000670de0b6b3a7640000612710610d8b9190611707565b610d959085611707565b33600090815260046020526040902054909150811115610df75760405162461bcd60e51b815260206004820152601d60248201527f534d3a206e6f7420656e6f756768207374616b652c2070656173616e7400000060448201526064016103a3565b60005b84811015610fb957336005878784818110610e1757610e176117d6565b9050602002013581548110610e2e57610e2e6117d6565b6000918252602090912001546001600160a01b031614610e855760405162461bcd60e51b8152602060048201526012602482015271534d3a20696478206973206e6f7420796f7560701b60448201526064016103a3565b600554868683818110610e9a57610e9a6117d6565b9050602002013510610ee65760405162461bcd60e51b8152602060048201526015602482015274534d3a20696478206f7574206f6620626f756e647360581b60448201526064016103a3565b60058054610ef690600190611726565b81548110610f0657610f066117d6565b6000918252602090912001546001600160a01b03166005878784818110610f2f57610f2f6117d6565b9050602002013581548110610f4657610f466117d6565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506005805480610f8557610f856117c0565b600082815260209020810160001990810180546001600160a01b031916905501905580610fb181611765565b915050610dfa565b503360009081526004602052604081208054839290610fd9908490611726565b909155505060015460408051808201825260078152667374616b696e6760c81b60208201529051634decdde360e11b81526001600160a01b0390921691639bd9bbc69161102c91339186916004016115f0565b600060405180830381600087803b15801561104657600080fd5b505af115801561105a573d6000803e3d6000fd5b5050505080600260008282546110709190611726565b909155505060408051338152602081018390527f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75910160405180910390a1506002546001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156110f557600080fd5b505afa158015611109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112d919061150f565b101561114b5760405162461bcd60e51b81526004016103a39061166d565b505060016000555050565b600080600080611164610641565b600554600354919550906001600160601b03808716600160a01b90920416148015906111905750600081115b1561127f576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016636c3f914c6111cf60018861173d565b6040516001600160e01b031960e084901b1681526001600160601b03909116600482015260240160206040518083038186803b15801561120e57600080fd5b505afa158015611222573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611246919061150f565b93506112528185611780565b925060058381548110611267576112676117d6565b6000918252602090912001546001600160a01b031691505b5090919293565b600154600160a01b900460ff16156112d75760405162461bcd60e51b815260206004820152601460248201527314d34e8810555513c8185b1c9958591e481cd95d60621b60448201526064016103a3565b600180546001600160a01b039092166001600160a81b031990921691909117600160a01b179055565b60008060008061130e611156565b929650909450925090506001600160a01b0381161561135d57604080518082019091526001600160a01b0382168082526001600160601b0386166020909201829052600160a01b909102176003555b90919293565b60008083601f84011261137557600080fd5b50813567ffffffffffffffff81111561138d57600080fd5b6020830191508360208285010111156113a557600080fd5b9250929050565b6000602082840312156113be57600080fd5b81356113c981611802565b9392505050565b60008060008060008060008060c0898b0312156113ec57600080fd5b88356113f781611802565b9750602089013561140781611802565b9650604089013561141781611802565b955060608901359450608089013567ffffffffffffffff8082111561143b57600080fd5b6114478c838d01611363565b909650945060a08b013591508082111561146057600080fd5b5061146d8b828c01611363565b999c989b5096995094979396929594505050565b6000806020838503121561149457600080fd5b823567ffffffffffffffff808211156114ac57600080fd5b818501915085601f8301126114c057600080fd5b8135818111156114cf57600080fd5b8660208260051b85010111156114e457600080fd5b60209290920196919550909350505050565b60006020828403121561150857600080fd5b5035919050565b60006020828403121561152157600080fd5b5051919050565b6000806040838503121561153b57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561157057602081850181015186830182015201611554565b81811115611582576000602083870101525b50601f01601f19169290920160200192915050565b8183823760009101908152919050565b600060018060a01b03808716835280861660208401525083604083015260a06060830152600060a083015260c060808301526115e660c083018461154a565b9695505050505050565b60018060a01b0384168152826020820152606060408201526000611617606083018461154a565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156116615783516001600160a01b03168352928401929184019160010161163c565b50909695505050505050565b60208082526018908201527f534d3a20736f6d657468696e6720666973687920686572650000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082198211156116ee576116ee611794565b500190565b600082611702576117026117aa565b500490565b600081600019048311821515161561172157611721611794565b500290565b60008282101561173857611738611794565b500390565b60006001600160601b038381169083168181101561175d5761175d611794565b039392505050565b600060001982141561177957611779611794565b5060010190565b60008261178f5761178f6117aa565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461181757600080fd5b5056fea264697066735822122002554e406d64b8d61f59623828f04455c9c882ac6fdb0b4d5d4b85551322825164736f6c63430008060033000000000000000000000000388fba3ccaca682118bc80aa20a137dbb7b1c515

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

000000000000000000000000388fba3ccaca682118bc80aa20a137dbb7b1c515

-----Decoded View---------------
Arg [0] : oracle (address): 0x388fba3ccaca682118bc80aa20a137dbb7b1c515

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000388fba3ccaca682118bc80aa20a137dbb7b1c515


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading