Contract 0x647507a70ff598f386cb96ae5046486389368c66 1

Gnosis 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x35d6d2aa4d2552998210dda8c0a0d5e320d588e30ff505c610fbfb7a6c1800670x39aca1c1282540262023-06-02 15:26:201 day 2 hrs ago0x0c3bca67f311df655ed8948f836e86efa1fab852 IN  Gnosis: mGNO0 xDAI0.000740901927
0x532b7cb91e9c806e37e28a4d4e4be1d30ff5daa82ee7d68329f81b6bff30f6c50x39aca1c1282149352023-05-31 6:52:053 days 11 hrs ago0x5697ce38fce437fb0510839047cbe00174923bb2 IN  Gnosis: mGNO0 xDAI0.000246040501
0xe45f05ea45ea882c40ec8b6864cd099b7ace5c41a5165aae03070705a369bee90x39aca1c1281543202023-05-27 12:05:057 days 5 hrs ago0x9c57027b1eca93093a6f446422c59c85a5a3fa52 IN  Gnosis: mGNO0 xDAI0.000288494721
0x4cbde6ca687d60c8524dc7db7d723f8d37822ea9bcb97bab6e4a468e7fbee06f0x39aca1c1281205612023-05-25 11:01:159 days 6 hrs ago0xe95be2366862b39819c74be94996e6c6cf262139 IN  Gnosis: mGNO0 xDAI0.000408948259
0xb1dd5f194fc7737d261266fc3ceca0dac83c54bd2d0073a8f40930da3bd15f170x39aca1c1281124662023-05-24 23:20:359 days 18 hrs ago0xdb03b65bc09c3f0c8b0dcaf12eda57e5946c1838 IN  Gnosis: mGNO0 xDAI0.000701054812
0xa88bfe05e6082b37a1cb7925602480f775401e9ffe2a17086856fcc339ba84c70x39aca1c1281110432023-05-24 21:18:109 days 20 hrs ago0xa91be77843a6eb469f5732d359ea2754a98a8144 IN  Gnosis: mGNO0 xDAI0.000436739859
0x040c396b8512afeaa6c4d7d73b3e061c1625b794299a03dcac1dd65c52c660b70x39aca1c1281001582023-05-24 5:33:3010 days 12 hrs ago0xfbc0459312ad9cec9ac780a67c6af4f831df2d3c IN  Gnosis: mGNO0 xDAI0.001168436468
0xb19f3566872dcaa30e61b770dad7dcdd7dd5949e110a605202667a568b77a7440x39aca1c1280689832023-05-22 8:25:2012 days 9 hrs ago0x7822159ee394d14745cde63a706f965fb73c7ac8 IN  Gnosis: mGNO0 xDAI0.000362220001
0x4f82d90fa9e1664ac8f6a30e8cd4776878a370bff32a01cd62a90ea0f4d130e60x39aca1c1279764552023-05-16 18:36:0517 days 23 hrs ago0x9f620ccbcb854f15575bcefffc41dac3173f2b48 IN  Gnosis: mGNO0 xDAI0.000158828021
0xc246ab02764e9624abfe8d39439544e17ef740d599d6774a257b49f270451f500x39aca1c1279754992023-05-16 17:11:5518 days 43 mins ago0x9f620ccbcb854f15575bcefffc41dac3173f2b48 IN  Gnosis: mGNO0 xDAI0.000262082341
0xa71e29698b0695a2c9d2eda410162ac314e78dfa7080f2169ce52b6a43278b050x39aca1c1278762192023-05-10 17:16:1524 days 39 mins ago0xc508a94614fc4b2bfc428d926871bde66efcc8e5 IN  Gnosis: mGNO0 xDAI0.000447939421
0x4fa02ff35c201a9fe773c2bad2eb330f8a8117536f01254479ded40be00ad5ee0x39aca1c1278759742023-05-10 16:55:2024 days 1 hr ago0xc508a94614fc4b2bfc428d926871bde66efcc8e5 IN  Gnosis: mGNO0 xDAI0.000775296
0x4351af5288b802388bb4305c85fd56e0790788839337dee4f76e768399e727b80x39aca1c1278374152023-05-08 8:53:0026 days 9 hrs ago0xc508a94614fc4b2bfc428d926871bde66efcc8e5 IN  Gnosis: mGNO0 xDAI0.000914833497
0xe3afca79f3c4955eca877c317f02f91cbf69f44fdb33a394304544cd64d2d4350x39aca1c1277634172023-05-03 21:33:2030 days 20 hrs ago0xcaa74debeae8b73de8a894e16ceef7625c69c7ff IN  Gnosis: mGNO0 xDAI0.0002031968
0x1a5bc5ee896d937b8ce6f1cbf34ff99c5147972591bd8538db04f6bdc16519830x39aca1c1277304892023-05-01 21:52:2532 days 20 hrs ago0xf564ae3860106514d6dee5c480bb884f298df6f6 IN  Gnosis: mGNO0 xDAI0.00054094281
0xda14207f302e67d710223d93f20c5c7e382ab8f4be180302b4181849de4158ed0x39aca1c1277020162023-04-30 4:37:2534 days 13 hrs ago0xc61336b9f40ea1e03f0200cd0f636256ac806aed IN  Gnosis: mGNO0 xDAI0.000482240985
0x135a02793491ca74a35c5c9b753e6d25fa1ac7d1282f6507181c106a9758d99c0x39aca1c1276770772023-04-28 16:34:3536 days 1 hr ago0x8be77092bb7cb74c8c584d11f1d7250c2fafd537 IN  Gnosis: mGNO0 xDAI0.000594982674
0xced78a186594ab0c139ac3fea24aaaa536da969ed6ab70b21372288948c9108a0x39aca1c1276728992023-04-28 10:29:3536 days 7 hrs ago0x86b888563e448af5554ca200189eeef65697ea01 IN  Gnosis: mGNO0 xDAI0.000543273
0x890e7bc931c7f52451bd6c6ad4ce292209c09ba301c6715efa0954c7928cd1130x39aca1c1276547072023-04-27 7:52:2537 days 10 hrs ago0xbc8f162d0b906d5614ff6b91fcb25c7f746a96ee IN  Gnosis: mGNO0 xDAI0.00037534926
0xa5eea4371c1331875d6190c88f0e6004dec403cec2706ce55727cda29de036750x39aca1c1276048362023-04-24 7:14:1040 days 10 hrs ago0xbc8f162d0b906d5614ff6b91fcb25c7f746a96ee IN  Gnosis: mGNO0 xDAI0.000364088782
0x10e3e63786a140def92039a16576677078fcc50d9c6ce68654db868702c1c8350x39aca1c1275470772023-04-20 18:38:5543 days 23 hrs ago0xbc8f162d0b906d5614ff6b91fcb25c7f746a96ee IN  Gnosis: mGNO0 xDAI0.000210112828
0xd06f2510c1eb7fe96529c56d6e5d689cbc1acc9e6999235a8c6e6df9ccd772050x39aca1c1274583752023-04-15 9:40:1549 days 8 hrs ago0xf1f858f1f59899d03bd42617f9eb7db4210188ad IN  Gnosis: mGNO0 xDAI0.00054506886
0x7e44553e8af6f23c2f7d6f815517fae95a4308a7489f2265629979fc2d0cdbf60x39aca1c1274301202023-04-13 16:57:1051 days 58 mins ago0x2c4b15ca7760627591c3247428e50b6efacb92ca IN  Gnosis: mGNO0 xDAI0.000404040793
0xe7cd6eaea0b9a04ce3d6a9c2f4a00d1355cf6cb914a8bfe7fe6cb0bf88535b9d0x39aca1c1273411142023-04-08 8:29:4556 days 9 hrs ago0xbc8f162d0b906d5614ff6b91fcb25c7f746a96ee IN  Gnosis: mGNO0 xDAI0.00037539873
0x345deb5c28c6f3ef7e5e77c950c3bf891eeab44b4152a253e320c368a7b35ee50x39aca1c1272843832023-04-04 21:38:0559 days 20 hrs ago0xbc8f162d0b906d5614ff6b91fcb25c7f746a96ee IN  Gnosis: mGNO0 xDAI0.000193479
[ Download CSV Export 
View more zero value Internal Transactions in Advanced View mode
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
SBCWrapperProxy

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 5000000 runs

Other Settings:
default evmVersion, Unlicense license
File 1 of 18 : SBCWrapperProxy.sol:SBCWrapperProxy
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

import "./utils/EIP1967Proxy.sol";
import "./SBCWrapper.sol";

/**
 * @title SBCWrapperProxy
 * @dev Upgradeable version of the underlying SBCWrapper.
 */
contract SBCWrapperProxy is EIP1967Proxy {
    constructor(address _admin, address _sbcWrapper) {
        _setAdmin(_admin);
        _setImplementation(_sbcWrapper);
    }
}

File 2 of 18 : PausableEIP1967Admin.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

import "@openzeppelin/contracts/security/Pausable.sol";
import "contracts/EIP1967Admin.sol";

/**
 * @title PausableEIP1967Admin
 * @dev Pausable contract, controlled by the current EIP1967 proxy owner.
 */
contract PausableEIP1967Admin is EIP1967Admin, Pausable {
    function pause() external onlyAdmin {
        _pause();
    }

    function unpause() external onlyAdmin {
        _unpause();
    }
}

File 3 of 18 : EIP1967Proxy.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

import "contracts/utils/PausableEIP1967Admin.sol";

/**
 * @title EIP1967Proxy
 * @dev Upgradeable proxy pattern implementation according to minimalistic EIP1967.
 */
contract EIP1967Proxy is EIP1967Admin {
    // EIP 1967
    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
    uint256 internal constant EIP1967_IMPLEMENTATION_STORAGE =
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    event Upgraded(address indexed implementation);
    event AdminChanged(address previousAdmin, address newAdmin);

    function admin() public view returns (address) {
        return _admin();
    }

    function implementation() public view returns (address res) {
        assembly {
            res := sload(EIP1967_IMPLEMENTATION_STORAGE)
        }
    }

    function setAdmin(address _admin) external onlyAdmin {
        _setAdmin(_admin);
    }

    function upgradeTo(address _implementation) external onlyAdmin {
        _setImplementation(_implementation);
    }

    /**
     * @dev Fallback function allowing to perform a delegatecall to the given implementation.
     * This function will return whatever the implementation call returns
     */
    fallback() external payable {
        address impl = implementation();
        require(impl != address(0));
        assembly {
            // Copy msg.data. We take full control of memory in this inline assembly
            // block because it will not return to Solidity code. We overwrite the
            // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

            // Call the implementation.
            // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @dev Internal function for transfer current admin rights to a different account.
     * @param _admin address of the new administrator.
     */
    function _setAdmin(address _admin) internal {
        address previousAdmin = admin();
        require(_admin != address(0));
        require(previousAdmin != _admin);
        assembly {
            sstore(EIP1967_ADMIN_STORAGE, _admin)
        }
        emit AdminChanged(previousAdmin, _admin);
    }

    /**
     * @dev Internal function for setting a new implementation address.
     * @param _implementation address of the new implementation contract.
     */
    function _setImplementation(address _implementation) internal {
        require(_implementation != address(0));
        require(implementation() != _implementation);
        assembly {
            sstore(EIP1967_IMPLEMENTATION_STORAGE, _implementation)
        }
        emit Upgraded(_implementation);
    }
}

File 4 of 18 : EIP1967Admin.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

/**
 * @title EIP1967Admin
 * @dev Upgradeable proxy pattern implementation according to minimalistic EIP1967.
 */
contract EIP1967Admin {
    // EIP 1967
    // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
    uint256 internal constant EIP1967_ADMIN_STORAGE =
        0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    modifier onlyAdmin() {
        require(msg.sender == _admin());
        _;
    }

    function _admin() internal view returns (address res) {
        assembly {
            res := sload(EIP1967_ADMIN_STORAGE)
        }
    }
}

File 5 of 18 : Claimable.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

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

/**
 * @title Claimable
 * @dev Implementation of the claiming utils that can be useful for withdrawing accidentally sent tokens.
 */
contract Claimable {
    /**
     * @dev Withdraws the erc20 tokens or native coins from this contract.
     * @param _token address of the claimed token or address(0) for native coins.
     * @param _to address of the tokens/coins receiver.
     */
    function _claimValues(address _token, address _to) internal {
        if (_token == address(0)) {
            _claimNativeCoins(_to);
        } else {
            _claimERC20Tokens(_token, _to);
        }
    }

    /**
     * @dev Internal function for withdrawing all native coins from the contract.
     * @param _to address of the coins receiver.
     */
    function _claimNativeCoins(address _to) internal {
        uint256 balance = address(this).balance;
        payable(_to).transfer(balance);
    }

    /**
     * @dev Internal function for withdrawing all tokens of some particular ERC20 contract from this contract.
     * @param _token address of the claimed ERC20 token.
     * @param _to address of the tokens receiver.
     */
    function _claimERC20Tokens(address _token, address _to) internal {
        uint256 balance = IERC20(_token).balanceOf(address(this));
        IERC20(_token).transfer(_to, balance);
    }
}

File 6 of 18 : IERC677Receiver.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

interface IERC677Receiver {
    function onTokenTransfer(
        address from,
        uint256 value,
        bytes calldata data
    ) external returns (bool);
}

File 7 of 18 : IERC677.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

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

interface IERC677 is IERC20 {
    function transferAndCall(
        address to,
        uint256 amount,
        bytes calldata data
    ) external;
}

File 8 of 18 : SBCWrapper.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "contracts/utils/PausableEIP1967Admin.sol";
import "./SBCToken.sol";

/**
 * @title SBCWrapper
 * @dev Wrapper engine contract for minting wrapped tokens that can be deposited into SBC.
 * Used for wrapping of STAKE and other possible ERC20 tokens.
 */
contract SBCWrapper is IERC677Receiver, PausableEIP1967Admin, Claimable, ReentrancyGuard {
    using SafeERC20 for IERC20;

    enum TokenStatus {
        DISABLED,
        ENABLED,
        PAUSED
    }

    mapping(address => TokenStatus) public tokenStatus;
    // if tokenRate[A] = X, then user will receive Y * X / 10**18 wrapped tokens for locking Y of A tokens.
    mapping(address => uint256) public tokenRate;

    SBCToken public immutable sbcToken;

    event Swap(address indexed token, address indexed user, uint256 amount, uint256 received);
    event SwapRateUpdated(address indexed token, uint256 rate);
    event TokenSwapEnabled(address indexed token);
    event TokenSwapPaused(address indexed token);

    constructor(SBCToken _sbcToken) {
        sbcToken = _sbcToken;
    }

    /**
     * @dev Enables swapping of new token into wrapped SBC token at a given rate.
     * Only admin can call this method.
     * @param _token address of the enabled or reenabled token contract.
     * @param _rate exchange rate for the new pair, multiplied by 10**18.
     */
    function enableToken(address _token, uint256 _rate) external onlyAdmin {
        require(_rate > 0, "SBCWrapper: invalid rate");

        TokenStatus oldStatus = tokenStatus[_token];
        tokenStatus[_token] = TokenStatus.ENABLED;
        tokenRate[_token] = _rate;

        if (oldStatus != TokenStatus.ENABLED) {
            emit TokenSwapEnabled(_token);
        }
        emit SwapRateUpdated(_token, _rate);
    }

    /**
     * @dev Temporary pauses swapping of some particular token, which can be reenaled later.
     * Only admin can call this method.
     * @param _token address of the paused token contract.
     */
    function pauseToken(address _token) external onlyAdmin {
        require(tokenStatus[_token] == TokenStatus.ENABLED, "SBCWrapper: token is not enabled");

        tokenStatus[_token] = TokenStatus.PAUSED;
        emit TokenSwapPaused(_token);
    }

    /**
     * @dev Swaps some of the whitelisted tokens for the newly created wrapped tokens.
     * Tokens must be pre-approved before calling this function.
     * @param _token address of the swapped token contract.
     * @param _amount amount of tokens to swap.
     * @param _permitData optional permit calldata to use for preliminary token approval.
     * supports STAKE permit and EIP2612 standards.
     */
    function swap(
        address _token,
        uint256 _amount,
        bytes calldata _permitData
    ) external nonReentrant whenNotPaused {
        require(tokenStatus[_token] == TokenStatus.ENABLED, "SBCWrapper: token is not enabled");

        if (_permitData.length > 4) {
            // supported signatures:
            // permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)
            // permit(address,address,uint256,uint256,uint8,bytes32,bytes32)
            require(
                bytes4(_permitData[0:4]) == bytes4(0x8fcbaf0c) || bytes4(_permitData[0:4]) == bytes4(0xd505accf),
                "SBCWrapper: invalid permit signature"
            );
            (bool status, ) = _token.call(_permitData);
            require(status, "SBCWrapper: permit failed");
        }

        address sender = _msgSender();

        // We do not plan to support any deflationary or rebasing tokens in this contract
        // so it is not required to check that ERC20 balance has indeed change.
        // It is an admin responsibility to carefully check that enabled token correctly implements ERC20 standard.
        IERC20(_token).safeTransferFrom(sender, address(this), _amount);

        _swapTokens(sender, _token, _amount);
    }

    /**
     * @dev ERC677 callback for swapping tokens in the simpler way during transferAndCall.
     * @param from address of the received token contract.
     * @param value amount of the received tokens.
     */
    function onTokenTransfer(
        address from,
        uint256 value,
        bytes calldata
    ) external override nonReentrant whenNotPaused returns (bool) {
        address token = _msgSender();
        require(tokenStatus[token] == TokenStatus.ENABLED, "SBCWrapper: token is not enabled");

        _swapTokens(from, token, value);
        return true;
    }

    /**
     * @dev Allows to transfer any locked token from this contract.
     * Only admin can call this method.
     * While it is not allowed to claim previously enabled or paused tokens,
     * the admin should still verify that the claimed token is a valid ERC20 token contract.
     * @param _token address of the token, if it is not provided (0x00..00), native coins will be transferred.
     * @param _to address that will receive the locked tokens on this contract.
     */
    function claimTokens(address _token, address _to) external onlyAdmin {
        require(tokenStatus[_token] == TokenStatus.DISABLED, "SBCWrapper: token already swappable");

        _claimValues(_token, _to);
    }

    function _swapTokens(
        address _receiver,
        address _token,
        uint256 _amount
    ) internal {
        uint256 acquired = (_amount * tokenRate[_token]) / 1 ether;
        require(acquired > 0, "SBCWrapper: invalid amount");

        sbcToken.mint(_receiver, acquired);

        emit Swap(_token, _receiver, _amount, acquired);
    }
}

File 9 of 18 : SBCToken.sol
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import "./utils/Claimable.sol";
import "contracts/utils/PausableEIP1967Admin.sol";
import "./interfaces/IERC677.sol";
import "./interfaces/IERC677Receiver.sol";

/**
 * @title SBCToken
 * @dev Wrapped token used for depositing into SBC.
 */
contract SBCToken is IERC677, ERC20Pausable, PausableEIP1967Admin, Claimable {
    address private _minter;

    constructor() ERC20("", "") {}

    /**
     * @dev Initialization setter for the minter address.
     * Only admin can call this method.
     * @param minter address of the SBCWrapper contract.
     */
    function setMinter(address minter) external onlyAdmin {
        require(_minter == address(0), "SBCToken: minter already set");
        _minter = minter;
    }

    /**
     * @dev Mints new tokens.
     * Only configured minter is allowed to mint tokens, which should be a SBCWrapper contract.
     * @param _to tokens receiver.
     * @param _amount amount of tokens to mint.
     */
    function mint(address _to, uint256 _amount) external {
        require(_msgSender() == _minter, "SBCToken: not a minter");
        _mint(_to, _amount);
    }

    /**
     * @dev Implements the ERC677 transferAndCall standard.
     * Executes a regular transfer, but calls the receiver's function to handle them in the same transaction.
     * @param _to tokens receiver.
     * @param _amount amount of sent tokens.
     * @param _data extra data to pass to the callback function.
     */
    function transferAndCall(
        address _to,
        uint256 _amount,
        bytes calldata _data
    ) external override {
        address sender = _msgSender();
        _transfer(sender, _to, _amount);
        require(IERC677Receiver(_to).onTokenTransfer(sender, _amount, _data), "SBCToken: ERC677 callback failed");
    }

    /**
     * @dev Allows to transfer any locked token from this contract.
     * Only admin can call this method.
     * @param _token address of the token, if it is not provided (0x00..00), native coins will be transferred.
     * @param _to address that will receive the locked tokens from this contract.
     */
    function claimTokens(address _token, address _to) external onlyAdmin {
        _claimValues(_token, _to);
    }
}

File 10 of 18 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

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

pragma solidity ^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;
        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");

        (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");

        (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");

        (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");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 12 of 18 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "contracts/token/ERC20/IERC20.sol";
import "contracts/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 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'
        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) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _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
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 13 of 18 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 14 of 18 : ERC20Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "contracts/ERC20.sol";
import "../../../security/Pausable.sol";

/**
 * @dev ERC20 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC20Pausable is ERC20, Pausable {
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
}

File 15 of 18 : 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 16 of 18 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "contracts/token/ERC20/IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "contracts/utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 17 of 18 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

File 18 of 18 : Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "contracts/utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_sbcWrapper","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"res","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_implementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506040516106b73803806106b783398101604081905261002f916101a8565b61003882610048565b610041816100df565b50506101db565b600061005261016f565b90506001600160a01b03821661006757600080fd5b816001600160a01b0316816001600160a01b0316141561008657600080fd5b600080516020610677833981519152829055604080516001600160a01b038084168252841660208201527f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6001600160a01b0381166100f257600080fd5b6001600160a01b0381166101126000805160206106978339815191525490565b6001600160a01b0316141561012657600080fd5b6000805160206106978339815191528190556040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006101876000805160206106778339815191525490565b905090565b80516001600160a01b03811681146101a357600080fd5b919050565b600080604083850312156101bb57600080fd5b6101c48361018c565b91506101d26020840161018c565b90509250929050565b61048d806101ea6000396000f3fe60806040526004361061003f5760003560e01c80633659cfe6146100af5780635c60da1b146100d1578063704b6c021461012a578063f851a4401461014a575b60006100697f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff811661008b57600080fd5b3660008037600080366000845af43d6000803e8080156100aa573d6000f35b3d6000fd5b3480156100bb57600080fd5b506100cf6100ca36600461041a565b61015f565b005b3480156100dd57600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b34801561013657600080fd5b506100cf61014536600461041a565b6101c4565b34801561015657600080fd5b50610101610226565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101b857600080fd5b6101c181610255565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461021d57600080fd5b6101c18161033d565b60006102507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b73ffffffffffffffffffffffffffffffffffffffff811661027557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166102b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b73ffffffffffffffffffffffffffffffffffffffff1614156102d557600080fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6000610347610226565b905073ffffffffffffffffffffffffffffffffffffffff821661036957600080fd5b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103a257600080fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038290556040805173ffffffffffffffffffffffffffffffffffffffff8084168252841660208201527f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b60006020828403121561042c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461045057600080fd5b939250505056fea2646970667358221220537509b2923ef2610f8625711f3b98e75adc8ac112cd1d7a28d11708f5ef5e6864736f6c63430008090033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc0000000000000000000000007c6ec14c8da5bf4f67c5021f4d41a1c6c14fb98f000000000000000000000000dab42ebb620203a41b956d22da223625254e33b3

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

0000000000000000000000007c6ec14c8da5bf4f67c5021f4d41a1c6c14fb98f000000000000000000000000dab42ebb620203a41b956d22da223625254e33b3

-----Decoded View---------------
Arg [0] : _admin (address): 0x7c6ec14c8da5bf4f67c5021f4d41a1c6c14fb98f
Arg [1] : _sbcWrapper (address): 0xdab42ebb620203a41b956d22da223625254e33b3

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007c6ec14c8da5bf4f67c5021f4d41a1c6c14fb98f
Arg [1] : 000000000000000000000000dab42ebb620203a41b956d22da223625254e33b3


Deployed ByteCode Sourcemap

216:173:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1297:12:16;1312:16;808:30;802:37;;702:153;1312:16;1297:31;-1:-1:-1;1346:18:16;;;1338:27;;;;;;1643:14;1640:1;1637;1624:34;1847:1;1844;1828:14;1825:1;1819:4;1812:5;1799:50;1923:16;1920:1;1917;1902:38;1961:6;2028:66;;;;2143:16;2140:1;2133:27;2028:66;2063:16;2060:1;2053:27;954:115;;;;;;;;;;-1:-1:-1;954:115:16;;;;;:::i;:::-;;:::i;:::-;;702:153;;;;;;;;;;-1:-1:-1;808:30:16;802:37;702:153;;;504:42:18;492:55;;;474:74;;462:2;447:18;702:153:16;;;;;;;861:87;;;;;;;;;;-1:-1:-1;861:87:16;;;;;:::i;:::-;;:::i;617:79::-;;;;;;;;;;;;;:::i;954:115::-;599:21:4;593:28;452:22;;:10;:22;;;444:31;;;;;;1027:35:16::1;1046:15;1027:18;:35::i;:::-;954:115:::0;:::o;861:87::-;599:21:4;593:28;452:22;;:10;:22;;;444:31;;;;;;924:17:16::1;934:6;924:9;:17::i;617:79::-:0;655:7;681:8;599:21:4;593:28;;499:138;681:8:16;674:15;;617:79;:::o;2825:308::-;2905:29;;;2897:38;;;;;;2973:15;2953:35;;:16;808:30;802:37;;702:153;2953:16;:35;;;;2945:44;;;;;;3029:30;3022:55;;;3101:25;;;;;;;;;;;2825:308;:::o;2355:302::-;2409:21;2433:7;:5;:7::i;:::-;2409:31;-1:-1:-1;2458:20:16;;;2450:29;;;;;;2514:6;2497:23;;:13;:23;;;;2489:32;;;;;;2561:21;2554:37;;;2615:35;;;743:42:18;812:15;;;794:34;;864:15;;859:2;844:18;;837:43;2615:35:16;;706:18:18;2615:35:16;;;;;;;2399:258;2355:302;:::o;14:309:18:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;181:9;168:23;231:42;224:5;220:54;213:5;210:65;200:93;;289:1;286;279:12;200:93;312:5;14:309;-1:-1:-1;;;14:309:18:o

Swarm Source

ipfs://537509b2923ef2610f8625711f3b98e75adc8ac112cd1d7a28d11708f5ef5e68
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.