Contract 0xa87171c62cc273b86b6c3579d5f76d3525149c13 1

 
Txn Hash Method
Index
From
To
Value
0x61a2c3734665ded42c8bdcde4adc66bb686a57dab3b6d84243f9c1717e2c55e50x6080604085096132022-05-18 6:10:13135 days 16 hrs ago0xa80481e3f9098602954b2e5cf306e6dee053ef3e IN  Create: ERC721StakingModuleFactory0 Ether0.0014559691080.001
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ERC721StakingModuleFactory

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
File 1 of 9 : ERC721StakingModuleFactory.sol
/*
ERC721StakingModuleFactory

https://github.com/gysr-io/core

SPDX-License-Identifier: MIT
*/

pragma solidity 0.8.4;

import "./interfaces/IModuleFactory.sol";
import "./ERC721StakingModule.sol";

/**
 * @title ERC721 staking module factory
 *
 * @notice this factory contract handles deployment for the
 * ERC721StakingModule contract
 *
 * @dev it is called by the parent PoolFactory and is responsible
 * for parsing constructor arguments before creating a new contract
 */
contract ERC721StakingModuleFactory is IModuleFactory {
    /**
     * @inheritdoc IModuleFactory
     */
    function createModule(bytes calldata data)
        external
        override
        returns (address)
    {
        // validate
        require(data.length == 32, "smnf1");

        // parse staking token
        address token;
        assembly {
            token := calldataload(68)
        }

        // create module
        ERC721StakingModule module =
            new ERC721StakingModule(token, address(this));
        module.transferOwnership(msg.sender);

        // output
        emit ModuleCreated(msg.sender, address(module));
        return address(module);
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
      * @dev Safely transfers `tokenId` token from `from` to `to`.
      *
      * Requirements:
      *
      * - `from` cannot be the zero address.
      * - `to` cannot be the zero address.
      * - `tokenId` token must exist and be owned by `from`.
      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
      *
      * Emits a {Transfer} event.
      */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 5 of 9 : IStakingModule.sol
/*
IStakingModule

https://github.com/gysr-io/core

SPDX-License-Identifier: MIT
*/

pragma solidity 0.8.4;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "./IEvents.sol";

import "../OwnerController.sol";

/**
 * @title Staking module interface
 *
 * @notice this contract defines the common interface that any staking module
 * must implement to be compatible with the modular Pool architecture.
 */
abstract contract IStakingModule is OwnerController, IEvents {
    // constants
    uint256 public constant DECIMALS = 18;

    /**
     * @return array of staking tokens
     */
    function tokens() external view virtual returns (address[] memory);

    /**
     * @notice get balance of user
     * @param user address of user
     * @return balances of each staking token
     */
    function balances(address user)
        external
        view
        virtual
        returns (uint256[] memory);

    /**
     * @return address of module factory
     */
    function factory() external view virtual returns (address);

    /**
     * @notice get total staked amount
     * @return totals for each staking token
     */
    function totals() external view virtual returns (uint256[] memory);

    /**
     * @notice stake an amount of tokens for user
     * @param user address of user
     * @param amount number of tokens to stake
     * @param data additional data
     * @return address of staking account
     * @return number of shares minted for stake
     */
    function stake(
        address user,
        uint256 amount,
        bytes calldata data
    ) external virtual returns (address, uint256);

    /**
     * @notice unstake an amount of tokens for user
     * @param user address of user
     * @param amount number of tokens to unstake
     * @param data additional data
     * @return address of staking account
     * @return number of shares burned for unstake
     */
    function unstake(
        address user,
        uint256 amount,
        bytes calldata data
    ) external virtual returns (address, uint256);

    /**
     * @notice quote the share value for an amount of tokens without unstaking
     * @param user address of user
     * @param amount number of tokens to claim with
     * @param data additional data
     * @return address of staking account
     * @return number of shares that the claim amount is worth
     */
    function claim(
        address user,
        uint256 amount,
        bytes calldata data
    ) external virtual returns (address, uint256);

    /**
     * @notice method called by anyone to update accounting
     * @param user address of user for update
     * @dev will only be called ad hoc and should not contain essential logic
     */
    function update(address user) external virtual;

    /**
     * @notice method called by owner to clean up and perform additional accounting
     * @dev will only be called ad hoc and should not contain any essential logic
     */
    function clean() external virtual;
}

File 6 of 9 : IModuleFactory.sol
/*
IModuleFactory

https://github.com/gysr-io/core

SPDX-License-Identifier: MIT
*/

pragma solidity 0.8.4;

/**
 * @title Module factory interface
 *
 * @notice this defines the common module factory interface used by the
 * main factory to create the staking and reward modules for a new Pool.
 */
interface IModuleFactory {
    // events
    event ModuleCreated(address indexed user, address module);

    /**
     * @notice create a new Pool module
     * @param data binary encoded construction parameters
     * @return address of newly created module
     */
    function createModule(bytes calldata data) external returns (address);
}

File 7 of 9 : IEvents.sol
/*
IEvents

https://github.com/gysr-io/core

SPDX-License-Identifier: MIT
 */

pragma solidity 0.8.4;

/**
 * @title GYSR event system
 *
 * @notice common interface to define GYSR event system
 */
interface IEvents {
    // staking
    event Staked(
        address indexed user,
        address indexed token,
        uint256 amount,
        uint256 shares
    );
    event Unstaked(
        address indexed user,
        address indexed token,
        uint256 amount,
        uint256 shares
    );
    event Claimed(
        address indexed user,
        address indexed token,
        uint256 amount,
        uint256 shares
    );

    // rewards
    event RewardsDistributed(
        address indexed user,
        address indexed token,
        uint256 amount,
        uint256 shares
    );
    event RewardsFunded(
        address indexed token,
        uint256 amount,
        uint256 shares,
        uint256 timestamp
    );
    event RewardsUnlocked(address indexed token, uint256 shares);
    event RewardsExpired(
        address indexed token,
        uint256 amount,
        uint256 shares,
        uint256 timestamp
    );

    // gysr
    event GysrSpent(address indexed user, uint256 amount);
    event GysrVested(address indexed user, uint256 amount);
    event GysrWithdrawn(uint256 amount);
}

File 8 of 9 : OwnerController.sol
/*
OwnerController

https://github.com/gysr-io/core

SPDX-License-Identifier: MIT
*/

pragma solidity 0.8.4;

/**
 * @title Owner controller
 *
 * @notice this base contract implements an owner-controller access model.
 *
 * @dev the contract is an adapted version of the OpenZeppelin Ownable contract.
 * It allows the owner to designate an additional account as the controller to
 * perform restricted operations.
 *
 * Other changes include supporting role verification with a require method
 * in addition to the modifier option, and removing some unneeded functionality.
 *
 * Original contract here:
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
 */
contract OwnerController {
    address private _owner;
    address private _controller;

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    event ControlTransferred(
        address indexed previousController,
        address indexed newController
    );

    constructor() {
        _owner = msg.sender;
        _controller = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
        emit ControlTransferred(address(0), _owner);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Returns the address of the current controller.
     */
    function controller() public view returns (address) {
        return _controller;
    }

    /**
     * @dev Modifier that throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(_owner == msg.sender, "oc1");
        _;
    }

    /**
     * @dev Modifier that throws if called by any account other than the controller.
     */
    modifier onlyController() {
        require(_controller == msg.sender, "oc2");
        _;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    function requireOwner() internal view {
        require(_owner == msg.sender, "oc1");
    }

    /**
     * @dev Throws if called by any account other than the controller.
     */
    function requireController() internal view {
        require(_controller == msg.sender, "oc2");
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`). This can
     * include renouncing ownership by transferring to the zero address.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual {
        requireOwner();
        require(newOwner != address(0), "oc3");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }

    /**
     * @dev Transfers control of the contract to a new account (`newController`).
     * Can only be called by the owner.
     */
    function transferControl(address newController) public virtual {
        requireOwner();
        require(newController != address(0), "oc4");
        emit ControlTransferred(_controller, newController);
        _controller = newController;
    }
}

File 9 of 9 : ERC721StakingModule.sol
/*
ERC721StakingModule

https://github.com/gysr-io/core

SPDX-License-Identifier: MIT
*/

pragma solidity 0.8.4;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

import "./interfaces/IStakingModule.sol";

/**
 * @title ERC721 staking module
 *
 * @notice this staking module allows users to deposit one or more ERC721
 * tokens in exchange for shares credited to their address. When the user
 * unstakes, these shares will be burned and a reward will be distributed.
 */
contract ERC721StakingModule is IStakingModule {
    // constant
    uint256 public constant SHARES_PER_TOKEN = 10**18;

    // members
    IERC721 private immutable _token;
    address private immutable _factory;

    mapping(address => uint256) public counts;
    mapping(uint256 => address) public owners;
    mapping(address => mapping(uint256 => uint256)) public tokenByOwner;
    mapping(uint256 => uint256) public tokenIndex;

    /**
     * @param token_ the token that will be rewarded
     * @param factory_ address of module factory
     */
    constructor(address token_, address factory_) {
        require(IERC165(token_).supportsInterface(0x80ac58cd), "smn1");
        _token = IERC721(token_);
        _factory = factory_;
    }

    /**
     * @inheritdoc IStakingModule
     */
    function tokens()
        external
        view
        override
        returns (address[] memory tokens_)
    {
        tokens_ = new address[](1);
        tokens_[0] = address(_token);
    }

    /**
     * @inheritdoc IStakingModule
     */
    function balances(address user)
        external
        view
        override
        returns (uint256[] memory balances_)
    {
        balances_ = new uint256[](1);
        balances_[0] = counts[user];
    }

    /**
     * @inheritdoc IStakingModule
     */
    function factory() external view override returns (address) {
        return _factory;
    }

    /**
     * @inheritdoc IStakingModule
     */
    function totals()
        external
        view
        override
        returns (uint256[] memory totals_)
    {
        totals_ = new uint256[](1);
        totals_[0] = _token.balanceOf(address(this));
    }

    /**
     * @inheritdoc IStakingModule
     */
    function stake(
        address user,
        uint256 amount,
        bytes calldata data
    ) external override onlyOwner returns (address, uint256) {
        // validate
        require(amount > 0, "smn2");
        require(amount <= _token.balanceOf(user), "smn3");
        require(data.length == 32 * amount, "smn4");

        uint256 count = counts[user];

        // stake
        for (uint256 i = 0; i < amount; i++) {
            // get token id
            uint256 id;
            uint256 pos = 132 + 32 * i;
            assembly {
                id := calldataload(pos)
            }

            // ownership mappings
            owners[id] = user;
            uint256 len = count + i;
            tokenByOwner[user][len] = id;
            tokenIndex[id] = len;

            // transfer to module
            _token.transferFrom(user, address(this), id);
        }

        // update position
        counts[user] = count + amount;

        // emit
        uint256 shares = amount * SHARES_PER_TOKEN;
        emit Staked(user, address(_token), amount, shares);

        return (user, shares);
    }

    /**
     * @inheritdoc IStakingModule
     */
    function unstake(
        address user,
        uint256 amount,
        bytes calldata data
    ) external override onlyOwner returns (address, uint256) {
        // validate
        require(amount > 0, "smn5");
        uint256 count = counts[user];
        require(amount <= count, "smn6");
        require(data.length == 32 * amount, "smn7");

        // unstake
        for (uint256 i = 0; i < amount; i++) {
            // get token id
            uint256 id;
            uint256 pos = 132 + 32 * i;
            assembly {
                id := calldataload(pos)
            }

            // ownership
            require(owners[id] == user, "smn8");
            delete owners[id];

            // clean up ownership mappings
            uint256 lastIndex = count - 1 - i;
            if (amount != count) {
                // reindex on partial unstake
                uint256 index = tokenIndex[id];
                if (index != lastIndex) {
                    uint256 lastId = tokenByOwner[user][lastIndex];
                    tokenByOwner[user][index] = lastId;
                    tokenIndex[lastId] = index;
                }
            }
            delete tokenByOwner[user][lastIndex];
            delete tokenIndex[id];

            // transfer to user
            _token.safeTransferFrom(address(this), user, id);
        }

        // update position
        counts[user] = count - amount;

        // emit
        uint256 shares = amount * SHARES_PER_TOKEN;
        emit Unstaked(user, address(_token), amount, shares);

        return (user, shares);
    }

    /**
     * @inheritdoc IStakingModule
     */
    function claim(
        address user,
        uint256 amount,
        bytes calldata
    ) external override onlyOwner returns (address, uint256) {
        // validate
        require(amount > 0, "smn9");
        require(amount <= counts[user], "smn10");

        uint256 shares = amount * SHARES_PER_TOKEN;
        emit Claimed(user, address(_token), amount, shares);
        return (user, shares);
    }

    /**
     * @inheritdoc IStakingModule
     */
    function update(address) external override {}

    /**
     * @inheritdoc IStakingModule
     */
    function clean() external override {}
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"ModuleCreated","type":"event"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"createModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50611b73806100206000396000f3fe608060405234801561001057600080fd5b506004361061002a5760003560e01c8062ee8fe51461002f575b600080fd5b61004261003d366004610215565b61006b565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6000602082146100db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f736d6e6631000000000000000000000000000000000000000000000000000000604482015260640160405180910390fd5b60006044359050600081306040516100f290610208565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f080158015610132573d6000803e3d6000fd5b506040517ff2fde38b00000000000000000000000000000000000000000000000000000000815233600482015290915073ffffffffffffffffffffffffffffffffffffffff82169063f2fde38b90602401600060405180830381600087803b15801561019d57600080fd5b505af11580156101b1573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681523392507ff708942ec477396a151a5285651961dcab8e8a82ea4f5b31a5236f92f6c92710915060200160405180910390a2949350505050565b6118bb8061028383390190565b60008060208385031215610227578182fd5b823567ffffffffffffffff8082111561023e578384fd5b818501915085601f830112610251578384fd5b81358181111561025f578485fd5b866020828501011115610270578485fd5b6020929092019691955090935050505056fe60c06040523480156200001157600080fd5b50604051620018bb380380620018bb8339810160408190526200003491620001b7565b60008054336001600160a01b0319918216811783556001805490921681179091556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600080546040516001600160a01b0390911691907fa06677f7b64342b4bcbde423684dbdb5356acfe41ad0285b6ecbe6dc4bf427f2908290a36040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038316906301ffc9a79060240160206040518083038186803b1580156200010057600080fd5b505afa15801562000115573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013b9190620001ee565b6200017b5760405162461bcd60e51b81526004016200017290602080825260049082015263736d6e3160e01b604082015260600190565b60405180910390fd5b6001600160601b0319606092831b8116608052911b1660a05262000217565b80516001600160a01b0381168114620001b257600080fd5b919050565b60008060408385031215620001ca578182fd5b620001d5836200019a565b9150620001e5602084016200019a565b90509250929050565b60006020828403121562000200578081fd5b8151801515811462000210578182fd5b9392505050565b60805160601c60a05160601c61164762000274600039600061032e01526000818161051b015281816107690152818161082501528181610b0001528181610bbc01528181610ca3015281816110e1015261119f01526116476000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80638c7a4638116100cd578063c4113b8811610081578063f2fde38b11610066578063f2fde38b14610352578063f77c479114610365578063fc4333cd1461021557600080fd5b8063c4113b8814610319578063c45a01551461032c57600080fd5b80638f0bc152116100b25780638f0bc152146102e95780639d63848a146102fc578063c038a38e1461031157600080fd5b80638c7a4638146102bc5780638da5cb5b146102cb57600080fd5b8063259fd221116101245780632e0f2625116101095780632e0f2625146102625780633e12170f1461026a5780636d16fa41146102a957600080fd5b8063259fd2211461021757806327e235e31461024257600080fd5b8063025e7c27146101565780630568e65e146101b65780630583e9f8146101e45780631c1b877214610204575b600080fd5b61018c61016436600461147b565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101d66101c43660046113af565b60026020526000908152604090205481565b6040519081526020016101ad565b6101d66101f236600461147b565b60056020526000908152604090205481565b6102156102123660046113af565b50565b005b6101d66102253660046113d0565b600460209081526000928352604080842090915290825290205481565b6102556102503660046113af565b610383565b6040516101ad9190611505565b6101d6601281565b61027d6102783660046113f9565b610415565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152016101ad565b6102156102b73660046113af565b6108be565b6101d6670de0b6b3a764000081565b60005473ffffffffffffffffffffffffffffffffffffffff1661018c565b61027d6102f73660046113f9565b6109b7565b610304610b98565b6040516101ad91906114ab565b610255610c52565b61027d6103273660046113f9565b610d7b565b7f000000000000000000000000000000000000000000000000000000000000000061018c565b6102156103603660046113af565b611225565b60015473ffffffffffffffffffffffffffffffffffffffff1661018c565b6040805160018082528183019092526060916020808301908036833750505073ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812054825192935091839190610404577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050919050565b60008054819073ffffffffffffffffffffffffffffffffffffffff1633146104845760405162461bcd60e51b815260206004820152600360248201527f6f6331000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600085116104d65760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3200000000000000000000000000000000000000000000000000000000604082015260600190565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301527f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b15801561055d57600080fd5b505afa158015610571573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105959190611493565b8511156105e65760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3300000000000000000000000000000000000000000000000000000000604082015260600190565b6105f1856020611555565b83146106415760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3400000000000000000000000000000000000000000000000000000000604082015260600190565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260026020526040812054905b868110156107db5760008061067f836020611555565b61068a90608461153d565b8035600081815260036020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8f161790559093509091506106e8848661153d565b73ffffffffffffffffffffffffffffffffffffffff8c8116600081815260046020818152604080842087855282528084208a905589845260059091529182902085905590517f23b872dd00000000000000000000000000000000000000000000000000000000815290810191909152306024820152604481018690529192507f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401600060405180830381600087803b1580156107ad57600080fd5b505af11580156107c1573d6000803e3d6000fd5b5050505050505080806107d3906115a9565b915050610669565b506107e6868261153d565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260026020526040812091909155610821670de0b6b3a764000088611555565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc89846040516108ab929190918252602082015260400190565b60405180910390a3969795505050505050565b6108c661131f565b73ffffffffffffffffffffffffffffffffffffffff81166109295760405162461bcd60e51b815260206004820152600360248201527f6f63340000000000000000000000000000000000000000000000000000000000604482015260640161047b565b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907fa06677f7b64342b4bcbde423684dbdb5356acfe41ad0285b6ecbe6dc4bf427f290600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008054819073ffffffffffffffffffffffffffffffffffffffff163314610a215760405162461bcd60e51b815260206004820152600360248201527f6f63310000000000000000000000000000000000000000000000000000000000604482015260640161047b565b60008511610a735760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3900000000000000000000000000000000000000000000000000000000604082015260600190565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260026020526040902054851115610ae85760405162461bcd60e51b815260206004820152600560248201527f736d6e3130000000000000000000000000000000000000000000000000000000604482015260640161047b565b6000610afc670de0b6b3a764000087611555565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2f6639d24651730c7bf57c95ddbf96d66d11477e4ec626876f92c22e5f365e688884604051610b86929190918252602082015260400190565b60405180910390a39596945050505050565b604080516001808252818301909252606091602080830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110610c15577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505090565b60408051600180825281830190925260609160208083019080368337019050506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b158015610cfa57600080fd5b505afa158015610d0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d329190611493565b81600081518110610d6c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505090565b60008054819073ffffffffffffffffffffffffffffffffffffffff163314610de55760405162461bcd60e51b815260206004820152600360248201527f6f63310000000000000000000000000000000000000000000000000000000000604482015260640161047b565b60008511610e375760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3500000000000000000000000000000000000000000000000000000000604082015260600190565b73ffffffffffffffffffffffffffffffffffffffff861660009081526002602052604090205480861115610eaf5760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3600000000000000000000000000000000000000000000000000000000604082015260600190565b610eba866020611555565b8414610f0a5760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3700000000000000000000000000000000000000000000000000000000604082015260600190565b60005b8681101561115557600080610f23836020611555565b610f2e90608461153d565b803560008181526003602052604090205490935090915073ffffffffffffffffffffffffffffffffffffffff8b8116911614610fae5760405162461bcd60e51b815260040161047b9060208082526004908201527f736d6e3800000000000000000000000000000000000000000000000000000000604082015260600190565b600082815260036020526040812080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905583610fee600187611592565b610ff89190611592565b9050848a146110605760008381526005602052604090205481811461105e5773ffffffffffffffffffffffffffffffffffffffff8c1660009081526004602090815260408083208584528252808320548484528184208190558352600590915290208190555b505b73ffffffffffffffffffffffffffffffffffffffff808c166000818152600460208181526040808420878552825280842084905588845260059091528083209290925590517f42842e0e00000000000000000000000000000000000000000000000000000000815230918101919091526024810191909152604481018590527f0000000000000000000000000000000000000000000000000000000000000000909116906342842e0e90606401600060405180830381600087803b15801561112757600080fd5b505af115801561113b573d6000803e3d6000fd5b50505050505050808061114d906115a9565b915050610f0d565b506111608682611592565b73ffffffffffffffffffffffffffffffffffffffff881660009081526002602052604081209190915561119b670de0b6b3a764000088611555565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f06cc7e90b4f2b554a9614b0caa84f909f3498c820ae47c731f490c28c07f7d3b89846040516108ab929190918252602082015260400190565b61122d61131f565b73ffffffffffffffffffffffffffffffffffffffff81166112905760405162461bcd60e51b815260206004820152600360248201527f6f63330000000000000000000000000000000000000000000000000000000000604482015260640161047b565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b565b60005473ffffffffffffffffffffffffffffffffffffffff16331461131d5760405162461bcd60e51b815260206004820152600360248201527f6f63310000000000000000000000000000000000000000000000000000000000604482015260640161047b565b803573ffffffffffffffffffffffffffffffffffffffff811681146113aa57600080fd5b919050565b6000602082840312156113c0578081fd5b6113c982611386565b9392505050565b600080604083850312156113e2578081fd5b6113eb83611386565b946020939093013593505050565b6000806000806060858703121561140e578182fd5b61141785611386565b935060208501359250604085013567ffffffffffffffff8082111561143a578384fd5b818701915087601f83011261144d578384fd5b81358181111561145b578485fd5b88602082850101111561146c578485fd5b95989497505060200194505050565b60006020828403121561148c578081fd5b5035919050565b6000602082840312156114a4578081fd5b5051919050565b6020808252825182820181905260009190848201906040850190845b818110156114f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016114c7565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156114f957835183529284019291840191600101611521565b60008219821115611550576115506115e2565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561158d5761158d6115e2565b500290565b6000828210156115a4576115a46115e2565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156115db576115db6115e2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122032164e63833f36353a64e20a2a186cfa69f3479ffb52add78c097b697a3cfb7e64736f6c63430008040033a26469706673582212203a03d925f05c280dbc3475b3976dda94a552c22a510e40f330ab80d779bedd7b64736f6c63430008040033

Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.