Contract 0x8764DE60236C5843D9faEB1B638fbCE962773B67 5

Txn Hash Method
Block
From
To
Value [Txn Fee]
0xca4453fa722974dba65ff6ea848372a9ef32a9c879d3494e693e143b0cd53cc1Stake385924272022-05-19 15:08:341 min ago0x6038e5f9697f4c5b39274fc7a93ee0f7069a07db IN  Tomb Finance: Masonry0 FTM0.023303990994
0xe5174b47331b76397b08e2e267f352739eae7bdc6bd25fb36b79cbf43e4918b6Exit385921862022-05-19 15:04:155 mins ago0x730b61bc31af989263789598aa4bc51f8f82be27 IN  Tomb Finance: Masonry0 FTM0.02368153699
0xdc1fffd2d5e12a8711fe5c8daa70fff0288a3b10219c20715f0fbc6137181818Stake385919032022-05-19 14:59:3710 mins ago0x62615faddea7d2aa3e859e7e23344148011c8920 IN  Tomb Finance: Masonry0 FTM0.027955035189
0x766c090c1ba9857494a78cf37840a05d8d9358ecf2edc69ac392d257cadee34cExit385916862022-05-19 14:55:3214 mins ago0xc05befd8dd6e0c4006ee4616e6ad4a79b7437e50 IN  Tomb Finance: Masonry0 FTM0.038898806885
0x64e388cad434e37144918b28579aa5c4131334dfe1e24872ad2bde50bb523f73Stake385913872022-05-19 14:50:2619 mins ago0xafb20573ca4665b86e652e9eb93fda22f448ffa9 IN  Tomb Finance: Masonry0 FTM0.021302160628
0x06b35ab6d5f7978ab52cd5e7926d1d4553335cf9c5a1f1f9bcd7bc7eae9ca283Stake385913822022-05-19 14:50:1419 mins ago0xafb20573ca4665b86e652e9eb93fda22f448ffa9 IN  Tomb Finance: Masonry0 FTM0.050176428658
0x39cc1d4d23278423fa998d0d72d94ef440b96c2a907c1cdd3e3b0fd67bca0992Stake385912832022-05-19 14:48:0921 mins ago0x5e8f0e72d895dff16c5bf76228b9f4a32ea3eed6 IN  Tomb Finance: Masonry0 FTM0.028430780357
0xa589b74fe7fac626fcc2e1040a40698469617247579d9cda10d9b4fe9d0834d5Stake385908202022-05-19 14:40:0429 mins ago0x422240df3d5145a8db3dac5df9fb43a4d74906e1 IN  Tomb Finance: Masonry0 FTM0.032636790433
0x59031ea2d24f8240e5ef595979ecb75c2857ca5df0d8c9bdb9bd4eeb4a2e5dc6Stake385903062022-05-19 14:31:2238 mins ago0xaa506dfaf254a4dbb2e7010623cbe367d1085259 IN  Tomb Finance: Masonry0 FTM0.036843640974
0xd37c12d33ac69fd7425b37c8f591a32732c14ebd6df035da4ad3a8eac941c9c4Stake385902752022-05-19 14:30:4938 mins ago0xb6c9cf6ac73c0ca2781b5935caa3a1f64ed0c961 IN  Tomb Finance: Masonry0 FTM0.035056247021
0xe8322c1c9ca742d42c54f48eaf48720831e9d5e524acb0f3730d6ec64f6660e3Claim Reward385902502022-05-19 14:30:2139 mins ago0xb6c9cf6ac73c0ca2781b5935caa3a1f64ed0c961 IN  Tomb Finance: Masonry0 FTM0.030212166525
0xb5498aa9e2e807fd8a3ec576e8b185c15e23c8d4d2e6611364a1769457a2f7f2Stake385898452022-05-19 14:21:2548 mins ago0xe99cdadf2973529702a9bfd6fe60f892107635a4 IN  Tomb Finance: Masonry0 FTM0.029736132991
0xf2655ff42edcf0534b9bdc08e6331fc2874105a79e1f70818eb98af1d2cd3cecStake385894422022-05-19 14:13:3256 mins ago0xdf1af0a140e8821d3f2e0d28ee54a3d69eff7446 IN  Tomb Finance: Masonry0 FTM0.031085692078
0xb3bc537e5e7ec6d096d5d612fe51561f9f384c2186b284821a2d150c84aa36c0Stake385894232022-05-19 14:12:5756 mins ago0xd48bbbcd7ad73be90949b972e98b328453ea3064 IN  Tomb Finance: Masonry0 FTM0.028408385455
0xe75fa7ad8ec70ed54aa3b6d6865b2e354671f3302248c2b27068f94df9e39eb5Withdraw385894172022-05-19 14:12:4956 mins ago0x53de09a5097b3853d45f03849dd67a2ea8671ff6 IN  Tomb Finance: Masonry0 FTM0.025105439773
0x5eb1c743e17bc39c3108c6abe46036c53137e8ebd28f0353050d50f18d0cae4bExit385893792022-05-19 14:11:5757 mins ago0x6826d18bdc61327e1ab21f3222fcf53ec3affa32 IN  Tomb Finance: Masonry0 FTM0.035461151287
0x4264236cf91843b5101a7b31b7225d73b7e4b8508299ddc92bc57ac9aa882fd3Stake385890242022-05-19 14:05:171 hr 4 mins ago0xc39f703aaf0f7d27c6e646e3e0b341b3b4642a48 IN  Tomb Finance: Masonry0 FTM0.027859340305
0x3bd425c161a253c2658a0e76f5a3e591178968a98883567cae391bf9a536cf47Stake385888472022-05-19 14:00:341 hr 9 mins ago0xd4d9c70fcc8a3e920ad48d1cb1596f8f097c96b7 IN  Tomb Finance: Masonry0 FTM0.017847662759
0x728391e3802b45e58166d92f139e2475df342fb36efdad689db2893724c37209Stake385885322022-05-19 13:53:461 hr 15 mins ago0xb9ecdd15a28986284140f52313ef2737af6add5e IN  Tomb Finance: Masonry0 FTM0.024047904388
0xac18454ab2ad50fc899f97ea8f85365acbd0d75780878e7f96c219e65e620aafStake385884542022-05-19 13:51:561 hr 17 mins ago0x5b3067c5e26fec823d6fbf8f315e43632658d2f6 IN  Tomb Finance: Masonry0 FTM0.02363148159
0x879abf89a3bcbf87d1498af10dc85fbbc679b5032090d96ed31d64aaea351414Withdraw385877352022-05-19 13:38:251 hr 31 mins ago0x0d4736132c277a9f5fd20e0a38c7914373a14221 IN  Tomb Finance: Masonry0 FTM0.027742162421
0xd49472a114a76607d00fdcee9b47a26914f9cd47eb6270acc75c2bb02a092ec4Withdraw385873442022-05-19 13:31:201 hr 38 mins ago0xfa2e2231bd40c1ba88d811e075deeec9c2ef9afd IN  Tomb Finance: Masonry0 FTM0.026605972653
0xfd4be99406024e555e8935ef883cf127bb045b69b989817a31f2340c092089ecStake385871872022-05-19 13:28:411 hr 41 mins ago0x15b883da52396a4322e8f5e7a638eb37656afe63 IN  Tomb Finance: Masonry0 FTM0.033079621055
0xad72de4c4545962703328f659ed0ef158742315538359fc0f1ee967e45905b8fWithdraw385869842022-05-19 13:25:081 hr 44 mins ago0x3433c17a157ea1eda6a5f286dee99bd1ca4ff091 IN  Tomb Finance: Masonry0 FTM0.035121093268
0x51752bbb489147ab03773a071b1bbfa2b1f61b9fdd61b12e638257eb444e4a2fStake385868272022-05-19 13:22:321 hr 47 mins ago0x862ad68efcedfd9e82038a2b4dfbde27de4b4c6f IN  Tomb Finance: Masonry0 FTM0.031859759875
[ Download CSV Export 
Latest 20 internal transactions
Parent Txn Hash Block From To Value
0x6699133779c0dc0539b316008790e0a0e99dd91f7a25b8dda7a92738193a5d38318975512022-02-24 23:51:4983 days 15 hrs ago 0x50f0c0d2dbfcab8330db75a3ac86de1a03a40bc4 Tomb Finance: Masonry2 FTM
0x59afedbf9f570a808c5cc5173673230072d1c0860cd9d7dc85795df7add30455318975252022-02-24 23:51:1183 days 15 hrs ago 0x50f0c0d2dbfcab8330db75a3ac86de1a03a40bc4 Tomb Finance: Masonry1 FTM
0x3f7b54ed331263bfcb829c2663055a8a5caabedd009faba403e902c0ecd07301318722722022-02-24 15:01:5384 days 7 mins ago 0x50f0c0d2dbfcab8330db75a3ac86de1a03a40bc4 Tomb Finance: Masonry1 FTM
0xf1e46cb67bd169a5b7940556d54eff933d7215fc60bb7b89b3f43537eb775799303592092022-02-08 12:36:50100 days 2 hrs ago 0xebf4fbb9c81b84dd5cf89bc75588e5d0018501b3 Tomb Finance: Masonry291.698 FTM
0x7894bbe44f4de887959563af645e9c78fc15dddb982b54af4fb2dbbfeff7457a302663142022-02-07 12:12:26101 days 2 hrs ago 0xfe975bbb4b265c33d5917f4ed5441a16862a4b03 Tomb Finance: Masonry0.0168046558919852 FTM
0x7263ce3419788532bb5b6634fe4259d91609bd38809c16d6cc5e27c89fa6544d284697302022-01-19 19:22:36119 days 19 hrs ago 0x7e79bdf4739f6b42d20617a2ca56b96ed87463b6 Tomb Finance: Masonry0.3 FTM
0x4f85150f871612efb6fca49de12edd88428ca47ef0335f82d63e46872b438761284524322022-01-19 15:04:04120 days 5 mins ago 0x41cc8b8c6b20a7d51668a163a0abef1202b76c34 Tomb Finance: Masonry9.9 FTM
0x3d6ed36718682fd949b5695137118930df4577ded9d2d213551fa9e354f71442283606632022-01-18 17:16:52120 days 21 hrs ago 0xfc1663e0e7637ce7c29343624ce31230d6d2035d Tomb Finance: Masonry0.05 FTM
0xc377f13ed4075d0afcbf4eff3b1328c019746aa21ea83b28d2d61ddd73ade698283605862022-01-18 17:15:19120 days 21 hrs ago 0xfc1663e0e7637ce7c29343624ce31230d6d2035d Tomb Finance: Masonry0.05 FTM
0x7fcf0da55721a857879653a825b5b70f6a603ca513f7321fce8e3c4e4cae102a276387922022-01-11 9:46:27128 days 5 hrs ago 0x0d0707963952f2fba59dd06f2b425ace40b492fe Tomb Finance: Masonry9 FTM
0x3f85682d73db5c76433a2ecafc3ea0346e1dd74b57cd0a358ce1905a41d9bedd276368602022-01-11 9:17:09128 days 5 hrs ago 0x0d0707963952f2fba59dd06f2b425ace40b492fe Tomb Finance: Masonry9 FTM
0x958e2f468c83fd8aad6bf50bffe408046bbb0f34fdfdeafb39452c7f6b429f8d268070582022-01-02 21:58:17136 days 17 hrs ago 0x24d5b5a211a1568041367b75bf5d3f7b70d80035 Tomb Finance: Masonry0.5 FTM
0x7701e72e798d38500b33fc88d917c9fa8247b2d4e7212fc22f20373fe9cd71ca266754042022-01-01 13:33:11138 days 1 hr ago 0xb89ef9197a66d14488c39a69eee0c3b43e8adbbd Tomb Finance: Masonry0.2 FTM
0x9d2de7fd85ffb126b8d88553a43a04245bb00a3665df10b8ab888e4dd5d0fefa266749472022-01-01 13:26:42138 days 1 hr ago 0xb89ef9197a66d14488c39a69eee0c3b43e8adbbd Tomb Finance: Masonry0.1 FTM
0xf5c1e29aa1de88e6e0cb3aeb515b1295101aa2f746b5546f0b12ecbbbfcbe942264553342021-12-30 6:10:32140 days 8 hrs ago 0xb3a96a051ac22ae08c7624d4ca266f4b8b293ec8 Tomb Finance: Masonry2 FTM
0xf1858210f7b56c6011f23e525843a14c1e1beb0839c76a072690269418480d01261114712021-12-26 16:57:28143 days 22 hrs ago 0xebf4fbb9c81b84dd5cf89bc75588e5d0018501b3 Tomb Finance: Masonry149.99 FTM
0x84abfb2403a2487dea2d660f074fcadc3904a4dfd052aea0acbd698fa1f80be8210452062021-11-04 12:53:38196 days 2 hrs ago 0x18e9290d03bb2eec64e5ec517fbfcd5637b8ed15 Tomb Finance: Masonry1 FTM
0x55a0e4c22e385fa994a7efb2ef7c1190cebb1562881a67b789c0f6f3d21275ad210451182021-11-04 12:52:01196 days 2 hrs ago 0x18e9290d03bb2eec64e5ec517fbfcd5637b8ed15 Tomb Finance: Masonry1 FTM
0x002fde9cae137dea9119bafd728fc14fdad3e9db38acf60bba89abfa82f18fca185016082021-10-07 7:35:32224 days 7 hrs ago 0xebf4fbb9c81b84dd5cf89bc75588e5d0018501b3 Tomb Finance: Masonry4.99 FTM
0xebc9679489ee59512c6d770a898e8899174ee68e1b1d6c32f25b8f1d72f1136893877442021-06-10 23:32:37342 days 15 hrs ago Tomb Finance: Deployer  Contract Creation0 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Masonry

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 8 : Masonry.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;

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

import "./utils/ContractGuard.sol";
import "./interfaces/IBasisAsset.sol";
import "./interfaces/ITreasury.sol";

contract ShareWrapper {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    IERC20 public share;

    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    function stake(uint256 amount) public virtual {
        _totalSupply = _totalSupply.add(amount);
        _balances[msg.sender] = _balances[msg.sender].add(amount);
        share.safeTransferFrom(msg.sender, address(this), amount);
    }

    function withdraw(uint256 amount) public virtual {
        uint256 masonShare = _balances[msg.sender];
        require(masonShare >= amount, "Masonry: withdraw request greater than staked amount");
        _totalSupply = _totalSupply.sub(amount);
        _balances[msg.sender] = masonShare.sub(amount);
        share.safeTransfer(msg.sender, amount);
    }
}

/*
  ______                __       _______
 /_  __/___  ____ ___  / /_     / ____(_)___  ____ _____  ________
  / / / __ \/ __ `__ \/ __ \   / /_  / / __ \/ __ `/ __ \/ ___/ _ \
 / / / /_/ / / / / / / /_/ /  / __/ / / / / / /_/ / / / / /__/  __/
/_/  \____/_/ /_/ /_/_.___/  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/

    http://tomb.finance
*/
contract Masonry is ShareWrapper, ContractGuard {
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;

    /* ========== DATA STRUCTURES ========== */

    struct Masonseat {
        uint256 lastSnapshotIndex;
        uint256 rewardEarned;
        uint256 epochTimerStart;
    }

    struct MasonrySnapshot {
        uint256 time;
        uint256 rewardReceived;
        uint256 rewardPerShare;
    }

    /* ========== STATE VARIABLES ========== */

    // governance
    address public operator;

    // flags
    bool public initialized = false;

    IERC20 public tomb;
    ITreasury public treasury;

    mapping(address => Masonseat) public masons;
    MasonrySnapshot[] public masonryHistory;

    uint256 public withdrawLockupEpochs;
    uint256 public rewardLockupEpochs;

    /* ========== EVENTS ========== */

    event Initialized(address indexed executor, uint256 at);
    event Staked(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);
    event RewardAdded(address indexed user, uint256 reward);

    /* ========== Modifiers =============== */

    modifier onlyOperator() {
        require(operator == msg.sender, "Masonry: caller is not the operator");
        _;
    }

    modifier masonExists {
        require(balanceOf(msg.sender) > 0, "Masonry: The mason does not exist");
        _;
    }

    modifier updateReward(address mason) {
        if (mason != address(0)) {
            Masonseat memory seat = masons[mason];
            seat.rewardEarned = earned(mason);
            seat.lastSnapshotIndex = latestSnapshotIndex();
            masons[mason] = seat;
        }
        _;
    }

    modifier notInitialized {
        require(!initialized, "Masonry: already initialized");
        _;
    }

    /* ========== GOVERNANCE ========== */

    function initialize(
        IERC20 _tomb,
        IERC20 _share,
        ITreasury _treasury
    ) public notInitialized {
        tomb = _tomb;
        share = _share;
        treasury = _treasury;

        MasonrySnapshot memory genesisSnapshot = MasonrySnapshot({time : block.number, rewardReceived : 0, rewardPerShare : 0});
        masonryHistory.push(genesisSnapshot);

        withdrawLockupEpochs = 6; // Lock for 6 epochs (36h) before release withdraw
        rewardLockupEpochs = 3; // Lock for 3 epochs (18h) before release claimReward

        initialized = true;
        operator = msg.sender;
        emit Initialized(msg.sender, block.number);
    }

    function setOperator(address _operator) external onlyOperator {
        operator = _operator;
    }

    function setLockUp(uint256 _withdrawLockupEpochs, uint256 _rewardLockupEpochs) external onlyOperator {
        require(_withdrawLockupEpochs >= _rewardLockupEpochs && _withdrawLockupEpochs <= 56, "_withdrawLockupEpochs: out of range"); // <= 2 week
        withdrawLockupEpochs = _withdrawLockupEpochs;
        rewardLockupEpochs = _rewardLockupEpochs;
    }

    /* ========== VIEW FUNCTIONS ========== */

    // =========== Snapshot getters

    function latestSnapshotIndex() public view returns (uint256) {
        return masonryHistory.length.sub(1);
    }

    function getLatestSnapshot() internal view returns (MasonrySnapshot memory) {
        return masonryHistory[latestSnapshotIndex()];
    }

    function getLastSnapshotIndexOf(address mason) public view returns (uint256) {
        return masons[mason].lastSnapshotIndex;
    }

    function getLastSnapshotOf(address mason) internal view returns (MasonrySnapshot memory) {
        return masonryHistory[getLastSnapshotIndexOf(mason)];
    }

    function canWithdraw(address mason) external view returns (bool) {
        return masons[mason].epochTimerStart.add(withdrawLockupEpochs) <= treasury.epoch();
    }

    function canClaimReward(address mason) external view returns (bool) {
        return masons[mason].epochTimerStart.add(rewardLockupEpochs) <= treasury.epoch();
    }

    function epoch() external view returns (uint256) {
        return treasury.epoch();
    }

    function nextEpochPoint() external view returns (uint256) {
        return treasury.nextEpochPoint();
    }

    function getTombPrice() external view returns (uint256) {
        return treasury.getTombPrice();
    }

    // =========== Mason getters

    function rewardPerShare() public view returns (uint256) {
        return getLatestSnapshot().rewardPerShare;
    }

    function earned(address mason) public view returns (uint256) {
        uint256 latestRPS = getLatestSnapshot().rewardPerShare;
        uint256 storedRPS = getLastSnapshotOf(mason).rewardPerShare;

        return balanceOf(mason).mul(latestRPS.sub(storedRPS)).div(1e18).add(masons[mason].rewardEarned);
    }

    /* ========== MUTATIVE FUNCTIONS ========== */

    function stake(uint256 amount) public override onlyOneBlock updateReward(msg.sender) {
        require(amount > 0, "Masonry: Cannot stake 0");
        super.stake(amount);
        masons[msg.sender].epochTimerStart = treasury.epoch(); // reset timer
        emit Staked(msg.sender, amount);
    }

    function withdraw(uint256 amount) public override onlyOneBlock masonExists updateReward(msg.sender) {
        require(amount > 0, "Masonry: Cannot withdraw 0");
        require(masons[msg.sender].epochTimerStart.add(withdrawLockupEpochs) <= treasury.epoch(), "Masonry: still in withdraw lockup");
        claimReward();
        super.withdraw(amount);
        emit Withdrawn(msg.sender, amount);
    }

    function exit() external {
        withdraw(balanceOf(msg.sender));
    }

    function claimReward() public updateReward(msg.sender) {
        uint256 reward = masons[msg.sender].rewardEarned;
        if (reward > 0) {
            require(masons[msg.sender].epochTimerStart.add(rewardLockupEpochs) <= treasury.epoch(), "Masonry: still in reward lockup");
            masons[msg.sender].epochTimerStart = treasury.epoch(); // reset timer
            masons[msg.sender].rewardEarned = 0;
            tomb.safeTransfer(msg.sender, reward);
            emit RewardPaid(msg.sender, reward);
        }
    }

    function allocateSeigniorage(uint256 amount) external onlyOneBlock onlyOperator {
        require(amount > 0, "Masonry: Cannot allocate 0");
        require(totalSupply() > 0, "Masonry: Cannot allocate when totalSupply is 0");

        // Create & add new snapshot
        uint256 prevRPS = getLatestSnapshot().rewardPerShare;
        uint256 nextRPS = prevRPS.add(amount.mul(1e18).div(totalSupply()));

        MasonrySnapshot memory newSnapshot = MasonrySnapshot({
            time: block.number,
            rewardReceived: amount,
            rewardPerShare: nextRPS
        });
        masonryHistory.push(newSnapshot);

        tomb.safeTransferFrom(msg.sender, address(this), amount);
        emit RewardAdded(msg.sender, amount);
    }

    function governanceRecoverUnsupported(IERC20 _token, uint256 _amount, address _to) external onlyOperator {
        // do not allow to drain core tokens
        require(address(_token) != address(tomb), "tomb");
        require(address(_token) != address(share), "share");
        _token.safeTransfer(_to, _amount);
    }
}

File 2 of 8 : IBasisAsset.sol
pragma solidity ^0.6.0;

interface IBasisAsset {
    function mint(address recipient, uint256 amount) external returns (bool);

    function burn(uint256 amount) external;

    function burnFrom(address from, uint256 amount) external;

    function isOperator() external returns (bool);

    function operator() external view returns (address);

    function transferOperator(address newOperator_) external;
}

File 3 of 8 : ITreasury.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;

interface ITreasury {
    function epoch() external view returns (uint256);

    function nextEpochPoint() external view returns (uint256);

    function getTombPrice() external view returns (uint256);

    function buyBonds(uint256 amount, uint256 targetPrice) external;

    function redeemBonds(uint256 amount, uint256 targetPrice) external;
}

File 4 of 8 : ContractGuard.sol
pragma solidity 0.6.12;

contract ContractGuard {
    mapping(uint256 => mapping(address => bool)) private _status;

    function checkSameOriginReentranted() internal view returns (bool) {
        return _status[block.number][tx.origin];
    }

    function checkSameSenderReentranted() internal view returns (bool) {
        return _status[block.number][msg.sender];
    }

    modifier onlyOneBlock() {
        require(!checkSameOriginReentranted(), "ContractGuard: one block, one function");
        require(!checkSameSenderReentranted(), "ContractGuard: one block, one function");

        _;

        _status[block.number][tx.origin] = true;
        _status[block.number][msg.sender] = true;
    }
}

File 5 of 8 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 6 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 7 of 8 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 8 of 8 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"at","type":"uint256"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"allocateSeigniorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"mason","type":"address"}],"name":"canClaimReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"mason","type":"address"}],"name":"canWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mason","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mason","type":"address"}],"name":"getLastSnapshotIndexOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTombPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"governanceRecoverUnsupported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_tomb","type":"address"},{"internalType":"contract IERC20","name":"_share","type":"address"},{"internalType":"contract ITreasury","name":"_treasury","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestSnapshotIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"masonryHistory","outputs":[{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"uint256","name":"rewardReceived","type":"uint256"},{"internalType":"uint256","name":"rewardPerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"masons","outputs":[{"internalType":"uint256","name":"lastSnapshotIndex","type":"uint256"},{"internalType":"uint256","name":"rewardEarned","type":"uint256"},{"internalType":"uint256","name":"epochTimerStart","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextEpochPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardLockupEpochs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawLockupEpochs","type":"uint256"},{"internalType":"uint256","name":"_rewardLockupEpochs","type":"uint256"}],"name":"setLockUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"share","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tomb","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawLockupEpochs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040526004805460ff60a01b1916905534801561001d57600080fd5b506127798061002d6000396000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806361d027b311610104578063a8d5fd65116100a2578063c0c53b8b11610071578063c0c53b8b146104b6578063c5967c26146104fb578063e0f6dc9e14610503578063e9fad8ee14610536576101ce565b8063a8d5fd651461046b578063b3ab15fb14610473578063b88a802f146104a6578063c040f23a146104ae576101ce565b80638cd9a27f116100de5780638cd9a27f146103ee578063900cf0cf1461042957806397ffe1d714610431578063a694fc3a1461044e576101ce565b806361d027b31461038057806370a0823114610388578063714b4658146103bb576101ce565b80631e85cd65116101715780633f9e3f041161014b5780633f9e3f04146102fc578063446a2ec81461030457806354575af41461030c578063570ca7351461034f576101ce565b80631e85cd65146102b25780632e1a7d4d146102ba5780632ffaaa09146102d9576101ce565b806309bb4f92116101ad57806309bb4f9214610267578063158ef93e1461026f57806318160ddd1461027757806319262d301461027f576101ce565b80628cc262146101d3578063022ba18d14610218578063046335d014610220575b600080fd5b610206600480360360208110156101e957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661053e565b60408051918252519081900360200190f35b6102066105cc565b6102536004803603602081101561023657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166105d2565b604080519115158252519081900360200190f35b6102066106a6565b610253610742565b610206610763565b6102536004803603602081101561029557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610769565b610206610835565b6102d7600480360360208110156102d057600080fd5b503561083b565b005b6102d7600480360360408110156102ef57600080fd5b5080359060200135610c29565b610206610d0a565b610206610d20565b6102d76004803603606081101561032257600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359160409091013516610d33565b610357610edf565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610357610efb565b6102066004803603602081101561039e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610f17565b610206600480360360208110156103d157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610f3f565b61040b6004803603602081101561040457600080fd5b5035610f67565b60408051938452602084019290925282820152519081900360600190f35b610206610f97565b6102d76004803603602081101561044757600080fd5b5035611002565b6102d76004803603602081101561046457600080fd5b50356113a0565b6103576116c5565b6102d76004803603602081101561048957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166116e1565b6102d7611798565b610357611a9a565b6102d7600480360360608110156104cc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013582169160409091013516611ab6565b610206611cfc565b61040b6004803603602081101561051957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611d67565b6102d7611d88565b600080610549611d9b565b604001519050600061055a84611df3565b60409081015173ffffffffffffffffffffffffffffffffffffffff86166000908152600760205291909120600101549091506105c4906105be670de0b6b3a76400006105b86105a98787611e4e565b6105b28a610f17565b90611eca565b90611f44565b90611fc5565b949350505050565b600a5481565b600654604080517f900cf0cf000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163900cf0cf916004808301926020929190829003018186803b15801561063d57600080fd5b505afa158015610651573d6000803e3d6000fd5b505050506040513d602081101561066757600080fd5b5051600a5473ffffffffffffffffffffffffffffffffffffffff841660009081526007602052604090206002015461069e91611fc5565b111592915050565b600654604080517f09bb4f92000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916309bb4f92916004808301926020929190829003018186803b15801561071157600080fd5b505afa158015610725573d6000803e3d6000fd5b505050506040513d602081101561073b57600080fd5b5051905090565b60045474010000000000000000000000000000000000000000900460ff1681565b60015490565b600654604080517f900cf0cf000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163900cf0cf916004808301926020929190829003018186803b1580156107d457600080fd5b505afa1580156107e8573d6000803e3d6000fd5b505050506040513d60208110156107fe57600080fd5b505160095473ffffffffffffffffffffffffffffffffffffffff841660009081526007602052604090206002015461069e91611fc5565b60095481565b610843612039565b15610899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061271e6026913960400191505060405180910390fd5b6108a161205a565b156108f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061271e6026913960400191505060405180910390fd5b600061090233610f17565b11610958576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806126b26021913960400191505060405180910390fd5b338015610a0c576109676125c7565b5073ffffffffffffffffffffffffffffffffffffffff811660009081526007602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091526109bd8261053e565b60208201526109ca610d0a565b815273ffffffffffffffffffffffffffffffffffffffff8216600090815260076020908152604091829020835181559083015160018201559101516002909101555b60008211610a7b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d61736f6e72793a2043616e6e6f742077697468647261772030000000000000604482015290519081900360640190fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663900cf0cf6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ae357600080fd5b505afa158015610af7573d6000803e3d6000fd5b505050506040513d6020811015610b0d57600080fd5b505160095433600090815260076020526040902060020154610b2e91611fc5565b1115610b85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806126d36021913960400191505060405180910390fd5b610b8d611798565b610b968261207b565b60408051838152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a25050436000908152600360209081526040808320328452909152808220805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091821681179092553384529190922080549091169091179055565b60045473ffffffffffffffffffffffffffffffffffffffff163314610c99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061264b6023913960400191505060405180910390fd5b808210158015610caa575060388211155b610cff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061268f6023913960400191505060405180910390fd5b600991909155600a55565b600854600090610d1b906001611e4e565b905090565b6000610d2a611d9b565b60400151905090565b60045473ffffffffffffffffffffffffffffffffffffffff163314610da3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061264b6023913960400191505060405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff84811691161415610e2f57604080517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048083019190915260248201527f746f6d6200000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60005473ffffffffffffffffffffffffffffffffffffffff84811691161415610eb957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f7368617265000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610eda73ffffffffffffffffffffffffffffffffffffffff84168284612132565b505050565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205490565b60088181548110610f7457fe5b600091825260209091206003909102018054600182015460029092015490925083565b600654604080517f900cf0cf000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163900cf0cf916004808301926020929190829003018186803b15801561071157600080fd5b61100a612039565b15611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061271e6026913960400191505060405180910390fd5b61106861205a565b156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061271e6026913960400191505060405180910390fd5b60045473ffffffffffffffffffffffffffffffffffffffff16331461112e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061264b6023913960400191505060405180910390fd5b6000811161119d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d61736f6e72793a2043616e6e6f7420616c6c6f636174652030000000000000604482015290519081900360640190fd5b60006111a7610763565b116111fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806125e9602e913960400191505060405180910390fd5b6000611207611d9b565b604001519050600061123661122f61121d610763565b6105b886670de0b6b3a7640000611eca565b8390611fc5565b90506112406125c7565b5060408051606081018252438152602081018581529181018381526008805460018101825560009190915282517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee360039092029182015592517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee4840155517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee59092019190915560055461130b9073ffffffffffffffffffffffffffffffffffffffff163330876121bf565b60408051858152905133917fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e29919081900360200190a25050436000908152600360209081526040808320328452909152808220805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00918216811790925533845291909220805490911690911790555050565b6113a8612039565b156113fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061271e6026913960400191505060405180910390fd5b61140661205a565b1561145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061271e6026913960400191505060405180910390fd5b3380156115105761146b6125c7565b5073ffffffffffffffffffffffffffffffffffffffff811660009081526007602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091526114c18261053e565b60208201526114ce610d0a565b815273ffffffffffffffffffffffffffffffffffffffff8216600090815260076020908152604091829020835181559083015160018201559101516002909101555b6000821161157f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d61736f6e72793a2043616e6e6f74207374616b652030000000000000000000604482015290519081900360640190fd5b6115888261225a565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663900cf0cf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115f057600080fd5b505afa158015611604573d6000803e3d6000fd5b505050506040513d602081101561161a57600080fd5b505133600081815260076020908152604091829020600201939093558051858152905191927f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d92918290030190a25050436000908152600360209081526040808320328452909152808220805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091821681179092553384529190922080549091169091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314611751576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061264b6023913960400191505060405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b33801561184c576117a76125c7565b5073ffffffffffffffffffffffffffffffffffffffff811660009081526007602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091526117fd8261053e565b602082015261180a610d0a565b815273ffffffffffffffffffffffffffffffffffffffff8216600090815260076020908152604091829020835181559083015160018201559101516002909101555b336000908152600760205260409020600101548015611a9657600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663900cf0cf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118cd57600080fd5b505afa1580156118e1573d6000803e3d6000fd5b505050506040513d60208110156118f757600080fd5b5051600a543360009081526007602052604090206002015461191891611fc5565b111561198557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d61736f6e72793a207374696c6c20696e20726577617264206c6f636b757000604482015290519081900360640190fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663900cf0cf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119ed57600080fd5b505afa158015611a01573d6000803e3d6000fd5b505050506040513d6020811015611a1757600080fd5b50513360008181526007602052604081206002810193909355600190920191909155600554611a5f9173ffffffffffffffffffffffffffffffffffffffff9091169083612132565b60408051828152905133917fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486919081900360200190a25b5050565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60045474010000000000000000000000000000000000000000900460ff1615611b4057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4d61736f6e72793a20616c726561647920696e697469616c697a656400000000604482015290519081900360640190fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600080548584169083161790556006805492841692909116919091179055611baa6125c7565b50604080516060810182524380825260006020808401828152848601838152600880546001810182559452855160039485027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915591517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee4830155517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee5909101556006600955600a91909155600480547fffffffffffffffffffffffff00000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90911674010000000000000000000000000000000000000000171633908117909155845192835293519293927f25ff68dd81b34665b5ba7e553ee5511bf6812e12adb4a7e2c0d9e26b3099ce799281900390910190a250505050565b600654604080517fc5967c26000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163c5967c26916004808301926020929190829003018186803b15801561071157600080fd5b60076020526000908152604090208054600182015460029092015490919083565b611d99611d9433610f17565b61083b565b565b611da36125c7565b6008611dad610d0a565b81548110611db757fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b611dfb6125c7565b6008611e0683610f3f565b81548110611e1057fe5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050919050565b600082821115611ebf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600082611ed957506000611ec4565b82820282848281611ee657fe5b0414611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061266e6021913960400191505060405180910390fd5b9392505050565b6000808211611fb457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611fbd57fe5b049392505050565b600082820183811015611f3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b43600090815260036020908152604080832032845290915290205460ff1690565b43600090815260036020908152604080832033845290915290205460ff1690565b33600090815260026020526040902054818110156120e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806126176034913960400191505060405180910390fd5b6001546120f19083611e4e565b6001556120fe8183611e4e565b336000818152600260205260408120929092559054611a969173ffffffffffffffffffffffffffffffffffffffff90911690845b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610eda9084906122c0565b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526122549085906122c0565b50505050565b6001546122679082611fc5565b600155336000908152600260205260409020546122849082611fc5565b3360008181526002602052604081209290925590546122bd9173ffffffffffffffffffffffffffffffffffffffff9091169030846121bf565b50565b6060612322826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123989092919063ffffffff16565b805190915015610eda5780806020019051602081101561234157600080fd5b5051610eda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806126f4602a913960400191505060405180910390fd5b60606105c48484600085856123ac85612503565b61241757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061248157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612444565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146124e3576040519150601f19603f3d011682016040523d82523d6000602084013e6124e8565b606091505b50915091506124f8828286612509565b979650505050505050565b3b151590565b60608315612518575081611f3d565b8251156125285782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561258c578181015183820152602001612574565b50505050905090810190601f1680156125b95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6040518060600160405280600081526020016000815260200160008152509056fe4d61736f6e72793a2043616e6e6f7420616c6c6f63617465207768656e20746f74616c537570706c7920697320304d61736f6e72793a20776974686472617720726571756573742067726561746572207468616e207374616b656420616d6f756e744d61736f6e72793a2063616c6c6572206973206e6f7420746865206f70657261746f72536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775f77697468647261774c6f636b757045706f6368733a206f7574206f662072616e67654d61736f6e72793a20546865206d61736f6e20646f6573206e6f742065786973744d61736f6e72793a207374696c6c20696e207769746864726177206c6f636b75705361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564436f6e747261637447756172643a206f6e6520626c6f636b2c206f6e652066756e6374696f6ea2646970667358221220a6645096338dd5e3d913a80041514a19e5c793c09575a44dee9b1c164936414264736f6c634300060c0033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
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.