ETH Price: $3,504.96 (+2.58%)
Gas: 11 Gwei

Contract

0x03d103c547B43b5a76df7e652BD0Bb61bE0BD70d
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Ownersh...189191912024-01-02 10:45:35196 days ago1704192335IN
0x03d103c5...1bE0BD70d
0 ETH0.0003906113.69373287
Activate186905062023-12-01 8:54:59228 days ago1701420899IN
0x03d103c5...1bE0BD70d
0 ETH0.0019708331.90650551

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
186484212023-11-25 11:29:35234 days ago1700911775  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenAdmin

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion
File 1 of 8 : TokenAdmin.sol
// SPDX-License-Identifier: GPL-3.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity ^0.8.0;

import {Owned} from "solmate/auth/Owned.sol";
import {ReentrancyGuard} from "solmate/utils/ReentrancyGuard.sol";

import {IMinter} from "./interfaces/IMinter.sol";
import {ITokenAdmin} from "./interfaces/ITokenAdmin.sol";
import {IERC20Mintable} from "./interfaces/IERC20Mintable.sol";

// solhint-disable not-rely-on-time

/**
 * @title Token Admin
 * @notice This contract holds all admin powers over the token passing through calls.
 *
 * In addition, calls to the mint function must respect the inflation schedule as defined in this contract.
 * As this contract is the only way to mint tokens this ensures that the maximum allowed supply is enforced
 * @dev This contract exists as a consequence of the gauge systems needing to know a fixed inflation schedule
 * in order to know how much tokens a gauge is allowed to mint. As this does not exist within the token itself
 * it is defined here, we must then wrap the token's minting functionality in order for this to be meaningful.
 */
contract TokenAdmin is ITokenAdmin, ReentrancyGuard, Owned {
    // Initial inflation rate of 2M tokens per week.
    uint256 public constant override INITIAL_RATE = (2_000_000 * 1e18) / uint256(1 weeks); // token has 18 decimals
    uint256 public constant override RATE_REDUCTION_TIME = 91 days; // 13 weeks (Nov 30 - Feb 29)
    uint256 public constant override RATE_REDUCTION_COEFFICIENT = 1.0271 * 1e18 ;
    uint256 public constant override RATE_DENOMINATOR = 1e18;

    IERC20Mintable private immutable _token;

    event MiningParametersUpdated(uint256 rate, uint256 supply);

    // Supply Variables
    uint256 private _miningEpoch;
    uint256 private _startEpochTime = type(uint256).max; // Sentinel value for contract not being activated
    uint256 private _startEpochSupply;
    uint256 private _rate;

    IMinter public immutable minter;

    constructor(IERC20Mintable token, IMinter minter_, address owner_) Owned(owner_) {
        _token = token;
        minter = minter_;
    }

    /**
     * @dev Returns the token being controlled.
     */
    function getToken() external view override returns (IERC20Mintable) {
        return _token;
    }

    /**
     * @notice Initiate token inflation schedule
     */
    function activate() external override nonReentrant onlyOwner {
        require(_startEpochTime == type(uint256).max, "Already activated");

        // initialise the relevant variables.
        _startEpochSupply = _token.totalSupply();
        _startEpochTime = block.timestamp;
        _rate = INITIAL_RATE;
        emit MiningParametersUpdated(INITIAL_RATE, _startEpochSupply);
    }

    /**
     * @notice Mint tokens subject to the defined inflation schedule
     */
    function mint(address to, uint256 amount) external override {
        require(msg.sender == address(minter), "NOT_MINTER");

        // Check if we've passed into a new epoch such that we should calculate available supply with a smaller rate.
        if (block.timestamp >= _startEpochTime + RATE_REDUCTION_TIME) {
            _updateMiningParameters();
        }

        require(_token.totalSupply() + amount <= _availableSupply(), "Mint amount exceeds remaining available supply");
        _token.mint(to, amount);
    }

    /**
     * @notice Returns the current epoch number.
     */
    function getMiningEpoch() external view returns (uint256) {
        return _miningEpoch;
    }

    /**
     * @notice Returns the start timestamp of the current epoch.
     */
    function getStartEpochTime() external view returns (uint256) {
        return _startEpochTime;
    }

    /**
     * @notice Returns the start timestamp of the next epoch.
     */
    function getFutureEpochTime() external view returns (uint256) {
        return _startEpochTime + RATE_REDUCTION_TIME;
    }

    /**
     * @notice Returns the available supply at the beginning of the current epoch.
     */
    function getStartEpochSupply() external view returns (uint256) {
        return _startEpochSupply;
    }

    /**
     * @notice Returns the current inflation rate of tokens per second
     */
    function getInflationRate() external view returns (uint256) {
        return _rate;
    }

    /**
     * @notice Maximum allowable number of tokens in existence (claimed or unclaimed)
     */
    function getAvailableSupply() external view returns (uint256) {
        return _availableSupply();
    }

    /**
     * @notice Get timestamp of the current mining epoch start while simultaneously updating mining parameters
     * @return Timestamp of the current epoch
     */
    function startEpochTimeWrite() external override returns (uint256) {
        return _startEpochTimeWrite();
    }

    /**
     * @notice Get timestamp of the next mining epoch start while simultaneously updating mining parameters
     * @return Timestamp of the next epoch
     */
    function futureEpochTimeWrite() external returns (uint256) {
        return _startEpochTimeWrite() + RATE_REDUCTION_TIME;
    }

    /**
     * @notice Update mining rate and supply at the start of the epoch
     * @dev Callable by any address, but only once per epoch
     * Total supply becomes slightly larger if this function is called late
     */
    function updateMiningParameters() external {
        require(block.timestamp >= _startEpochTime + RATE_REDUCTION_TIME, "Epoch has not finished yet");
        _updateMiningParameters();
    }

    /**
     * @notice How much supply is mintable from start timestamp till end timestamp
     * @param start Start of the time interval (timestamp)
     * @param end End of the time interval (timestamp)
     * @return Tokens mintable from `start` till `end`
     */
    function mintableInTimeframe(uint256 start, uint256 end) external view returns (uint256) {
        return _mintableInTimeframe(start, end);
    }

    // Internal functions

    /**
     * @notice Maximum allowable number of tokens in existence (claimed or unclaimed)
     */
    function _availableSupply() internal view returns (uint256) {
        uint256 newSupplyFromCurrentEpoch = (block.timestamp - _startEpochTime) * _rate;
        return _startEpochSupply + newSupplyFromCurrentEpoch;
    }

    /**
     * @notice Get timestamp of the current mining epoch start while simultaneously updating mining parameters
     * @return Timestamp of the current epoch
     */
    function _startEpochTimeWrite() internal returns (uint256) {
        uint256 startEpochTime = _startEpochTime;
        if (block.timestamp >= startEpochTime + RATE_REDUCTION_TIME) {
            _updateMiningParameters();
            return _startEpochTime;
        }
        return startEpochTime;
    }

    function _updateMiningParameters() internal {
        uint256 inflationRate = _rate;
        uint256 startEpochSupply = _startEpochSupply + (inflationRate * RATE_REDUCTION_TIME);
        inflationRate = inflationRate * RATE_DENOMINATOR / RATE_REDUCTION_COEFFICIENT;

        ++_miningEpoch;
        _startEpochTime += RATE_REDUCTION_TIME;
        _rate = inflationRate;
        _startEpochSupply = startEpochSupply;

        emit MiningParametersUpdated(inflationRate, startEpochSupply);
    }

    /**
     * @notice How much supply is mintable from start timestamp till end timestamp
     * @param start Start of the time interval (timestamp)
     * @param end End of the time interval (timestamp)
     * @return Tokens mintable from `start` till `end`
     */
    function _mintableInTimeframe(uint256 start, uint256 end) internal view returns (uint256) {
        require(start <= end, "start > end");

        uint256 currentEpochTime = _startEpochTime;
        uint256 currentRate = _rate;

        // It shouldn't be possible to over/underflow in here but we add checked maths to be safe

        // Special case if end is in future (not yet minted) epoch
        if (end > currentEpochTime + RATE_REDUCTION_TIME) {
            currentEpochTime += RATE_REDUCTION_TIME;
            currentRate = currentRate * RATE_DENOMINATOR / RATE_REDUCTION_COEFFICIENT;
        }

        require(end <= currentEpochTime + RATE_REDUCTION_TIME, "too far in future");

        uint256 toMint = 0;
        for (uint256 epoch = 0; epoch < 999; ++epoch) {
            if (end >= currentEpochTime) {
                uint256 currentEnd = end;
                if (currentEnd > currentEpochTime + RATE_REDUCTION_TIME) {
                    currentEnd = currentEpochTime + RATE_REDUCTION_TIME;
                }

                uint256 currentStart = start;
                if (currentStart >= currentEpochTime + RATE_REDUCTION_TIME) {
                    // We should never get here but what if...
                    break;
                } else if (currentStart < currentEpochTime) {
                    currentStart = currentEpochTime;
                }

                toMint += currentRate * (currentEnd - currentStart);

                if (start >= currentEpochTime) {
                    break;
                }
            }

            currentEpochTime -= RATE_REDUCTION_TIME;
            // double-division with rounding made rate a bit less => good
            currentRate = currentRate * RATE_REDUCTION_COEFFICIENT / RATE_DENOMINATOR;
            assert(currentRate <= INITIAL_RATE);
        }

        return toMint;
    }

    // The below functions are duplicates of functions available above.
    // They are included for ABI compatibility with snake_casing as used in vyper contracts.
    // solhint-disable func-name-mixedcase

    function rate() external view override returns (uint256) {
        return _rate;
    }

    function available_supply() external view returns (uint256) {
        return _availableSupply();
    }

    /**
     * @notice Get timestamp of the current mining epoch start while simultaneously updating mining parameters
     * @return Timestamp of the current epoch
     */
    function start_epoch_time_write() external returns (uint256) {
        return _startEpochTimeWrite();
    }

    /**
     * @notice Get timestamp of the next mining epoch start while simultaneously updating mining parameters
     * @return Timestamp of the next epoch
     */
    function future_epoch_time_write() external returns (uint256) {
        return _startEpochTimeWrite() + RATE_REDUCTION_TIME;
    }

    /**
     * @notice Update mining rate and supply at the start of the epoch
     * @dev Callable by any address, but only once per epoch
     * Total supply becomes slightly larger if this function is called late
     */
    function update_mining_parameters() external {
        require(block.timestamp >= _startEpochTime + RATE_REDUCTION_TIME, "Epoch has not finished yet");
        _updateMiningParameters();
    }

    /**
     * @notice How much supply is mintable from start timestamp till end timestamp
     * @param start Start of the time interval (timestamp)
     * @param end End of the time interval (timestamp)
     * @return Tokens mintable from `start` till `end`
     */
    function mintable_in_timeframe(uint256 start, uint256 end) external view returns (uint256) {
        return _mintableInTimeframe(start, end);
    }
}

File 2 of 8 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 3 of 8 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

File 4 of 8 : IMinter.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.7.0 <0.9.0;

import {IERC20} from "forge-std/interfaces/IERC20.sol";

import {ITokenAdmin} from "./ITokenAdmin.sol";
import {IGaugeController} from "./IGaugeController.sol";

interface IMinter {
    event Minted(address indexed recipient, address gauge, uint256 minted);

    /**
     * @notice Returns the address of the minted token
     */
    function getToken() external view returns (IERC20);

    /**
     * @notice Returns the address of the Token Admin contract
     */
    function getTokenAdmin() external view returns (ITokenAdmin);

    /**
     * @notice Returns the address of the Gauge Controller
     */
    function getGaugeController() external view returns (IGaugeController);

    /**
     * @notice Mint everything which belongs to `msg.sender` and send to them
     * @param gauge `LiquidityGauge` address to get mintable amount from
     */
    function mint(address gauge) external returns (uint256);

    /**
     * @notice Mint everything which belongs to `msg.sender` across multiple gauges
     * @param gauges List of `LiquidityGauge` addresses
     */
    function mintMany(address[] calldata gauges) external returns (uint256);

    /**
     * @notice Mint tokens for `user`
     * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf
     * @param gauge `LiquidityGauge` address to get mintable amount from
     * @param user Address to mint to
     */
    function mintFor(address gauge, address user) external returns (uint256);

    /**
     * @notice Mint tokens for `user` across multiple gauges
     * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf
     * @param gauges List of `LiquidityGauge` addresses
     * @param user Address to mint to
     */
    function mintManyFor(address[] calldata gauges, address user) external returns (uint256);

    /**
     * @notice The total number of tokens minted for `user` from `gauge`
     */
    function minted(address user, address gauge) external view returns (uint256);

    /**
     * @notice Whether `minter` is approved to mint tokens for `user`
     */
    function getMinterApproval(address minter, address user) external view returns (bool);

    /**
     * @notice Set whether `minter` is approved to mint tokens on your behalf
     */
    function setMinterApproval(address minter, bool approval) external;

    // The below functions are near-duplicates of functions available above.
    // They are included for ABI compatibility with snake_casing as used in vyper contracts.
    // solhint-disable func-name-mixedcase

    /**
     * @notice Whether `minter` is approved to mint tokens for `user`
     */
    function allowed_to_mint_for(address minter, address user) external view returns (bool);

    /**
     * @notice Mint everything which belongs to `msg.sender` across multiple gauges
     * @dev This function is not recommended as `mintMany()` is more flexible and gas efficient
     * @param gauges List of `LiquidityGauge` addresses
     */
    function mint_many(address[8] calldata gauges) external;

    /**
     * @notice Mint tokens for `user`
     * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf
     * @param gauge `LiquidityGauge` address to get mintable amount from
     * @param user Address to mint to
     */
    function mint_for(address gauge, address user) external;

    /**
     * @notice Toggle whether `minter` is approved to mint tokens for `user`
     */
    function toggle_approve_mint(address minter) external;
}

File 5 of 8 : ITokenAdmin.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.7.0 <0.9.0;

import {IERC20Mintable} from "./IERC20Mintable.sol";

interface ITokenAdmin {
    // solhint-disable func-name-mixedcase
    function INITIAL_RATE() external view returns (uint256);

    function RATE_REDUCTION_TIME() external view returns (uint256);

    function RATE_REDUCTION_COEFFICIENT() external view returns (uint256);

    function RATE_DENOMINATOR() external view returns (uint256);

    // solhint-enable func-name-mixedcase
    function getToken() external view returns (IERC20Mintable);

    function activate() external;

    function rate() external view returns (uint256);

    function startEpochTimeWrite() external returns (uint256);

    function mint(address to, uint256 amount) external;
}

File 6 of 8 : IERC20Mintable.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

import {IERC20} from "forge-std/interfaces/IERC20.sol";

interface IERC20Mintable is IERC20 {
    function mint(address to, uint256 amount) external;
}

File 7 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @dev This includes the optional name, symbol, and decimals metadata.
interface IERC20 {
    /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`
    /// is the new allowance.
    event Approval(address indexed owner, address indexed spender, uint256 value);

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

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

    /// @notice Moves `amount` tokens from the caller's account to `to`.
    function transfer(address to, uint256 amount) external returns (bool);

    /// @notice Returns the remaining number of tokens that `spender` is allowed
    /// to spend on behalf of `owner`
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
    /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    function approve(address spender, uint256 amount) external returns (bool);

    /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.
    /// `amount` is then deducted from the caller's allowance.
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /// @notice Returns the name of the token.
    function name() external view returns (string memory);

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

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

File 8 of 8 : IGaugeController.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.11;

// https://github.com/swervefi/swerve/edit/master/packages/swerve-contracts/interfaces/IGaugeController.sol

interface IGaugeController {
    struct Point {
        uint256 bias;
        uint256 slope;
    }

    struct VotedSlope {
        uint256 slope;
        uint256 power;
        uint256 end;
    }

    // Public variables
    function admin() external view returns (address);

    function token() external view returns (address);

    function voting_escrow() external view returns (address);

    function n_gauge_types() external view returns (int128);

    function n_gauges() external view returns (int128);

    function gauge_type_names(int128) external view returns (string memory);

    function gauges(uint256) external view returns (address);

    function vote_user_slopes(address, address) external view returns (VotedSlope memory);

    function vote_user_power(address) external view returns (uint256);

    function last_user_vote(address, address) external view returns (uint256);

    function points_weight(address, uint256) external view returns (Point memory);

    function time_weight(address) external view returns (uint256);

    function points_sum(int128, uint256) external view returns (Point memory);

    function time_sum(uint256) external view returns (uint256);

    function points_total(uint256) external view returns (uint256);

    function time_total() external view returns (uint256);

    function points_type_weight(int128, uint256) external view returns (uint256);

    function time_type_weight(uint256) external view returns (uint256);

    // Getter functions
    function gauge_types(address) external view returns (int128);

    function gauge_relative_weight(address) external view returns (uint256);

    function gauge_relative_weight(address, uint256) external view returns (uint256);

    function get_gauge_weight(address) external view returns (uint256);

    function get_type_weight(int128) external view returns (uint256);

    function get_total_weight() external view returns (uint256);

    function get_weights_sum_per_type(int128) external view returns (uint256);

    // External functions
    function add_gauge(address, int128, uint256) external;

    function checkpoint() external;

    function checkpoint_gauge(address) external;

    function gauge_relative_weight_write(address) external returns (uint256);

    function gauge_relative_weight_write(address, uint256) external returns (uint256);

    function add_type(string memory, uint256) external;

    function change_type_weight(int128, uint256) external;

    function change_gauge_weight(address, uint256) external;

    function vote_for_gauge_weights(address, uint256) external;

    function change_pending_admin(address newPendingAdmin) external;

    function claim_admin() external;
}

Settings
{
  "remappings": [
    "solmate/=lib/solmate/src/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/popcorn/lib/openzeppelin-contracts-upgradeable/contracts/",
    "create3-factory/=lib/create3-factory/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/popcorn/lib/openzeppelin-contracts-upgradeable/contracts/",
    "popcorn/=lib/popcorn/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20Mintable","name":"token","type":"address"},{"internalType":"contract IMinter","name":"minter_","type":"address"},{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"MiningParametersUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"INITIAL_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_REDUCTION_COEFFICIENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_REDUCTION_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"available_supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"futureEpochTimeWrite","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"future_epoch_time_write","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAvailableSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFutureEpochTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInflationRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMiningEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStartEpochSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStartEpochTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getToken","outputs":[{"internalType":"contract IERC20Mintable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"mintableInTimeframe","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"mintable_in_timeframe","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"contract IMinter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startEpochTimeWrite","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start_epoch_time_write","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateMiningParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"update_mining_parameters","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052600160005560001960035534801561001b57600080fd5b506040516110aa3803806110aa83398101604081905261003a916100b7565b600180546001600160a01b0319166001600160a01b0383169081179091556040518291906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350506001600160a01b039182166080521660a052610104565b6001600160a01b03811681146100b457600080fd5b50565b6000806000606084860312156100cc57600080fd5b83516100d78161009f565b60208501519093506100e88161009f565b60408501519092506100f98161009f565b809150509250925092565b60805160a051610f65610145600039600081816101b801526105ef015260008181610239015281816104ab015281816106a001526108110152610f656000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80637efad8e0116100ee578063b87b561611610097578063cb626ae211610071578063cb626ae2146102f4578063d43b40fa146102f4578063d725a9ca146102e1578063f2fde38b146102fc57600080fd5b8063b87b5616146102d7578063c167d1cd1461025d578063c3b03fa8146102e157600080fd5b8063a228bced116100c8578063a228bced146102cf578063adc4cf43146102cf578063b26b238e1461026557600080fd5b80637efad8e0146102a0578063819df2c41461026d5780638da5cb5b146102af57600080fd5b806324f92a251161015b57806340c10f191161013557806340c10f19146102755780634d2fa413146102885780634dbac7331461029057806355f741761461029857600080fd5b806324f92a251461025d578063277dbafb146102655780632c4e722e1461026d57600080fd5b80630f15f4c01161018c5780630f15f4c01461021e57806321609bbf1461022857806321df0da71461023757600080fd5b806307546172146101b3578063087905c9146102045780630dfbdce414610216575b600080fd5b6101da7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6002545b6040519081526020016101fb565b61020861030f565b610226610327565b005b610208670e40fe0218cdc00081565b7f00000000000000000000000000000000000000000000000000000000000000006101da565b6102086105b5565b6102086105bf565b600554610208565b610226610283366004610da1565b6105d7565b600354610208565b610208610871565b600454610208565b610208670de0b6b3a764000081565b6001546101da9073ffffffffffffffffffffffffffffffffffffffff1681565b61020861088c565b6102086277f88081565b6102086102ef366004610dcb565b610896565b6102266108ab565b61022661030a366004610ded565b61092f565b60006277f8806003546103229190610e37565b905090565b600054600114610398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600260005560015473ffffffffffffffffffffffffffffffffffffffff16331461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161038f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600354146104a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f416c726561647920616374697661746564000000000000000000000000000000604482015260640161038f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105389190610e4a565b6004554260035561055762093a806a01a784379d99db42000000610e63565b6005557fa96ad9a0b81b29565fbe231714a2f2c152b759e603c91bf87144a3f61944f0a561059362093a806a01a784379d99db42000000610e63565b6004546040805192835260208301919091520160405180910390a16001600055565b6000610322610a21565b60006277f8806105cd610a55565b6103229190610e37565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e54455200000000000000000000000000000000000000000000604482015260640161038f565b6277f8806003546106879190610e37565b421061069557610695610a83565b61069d610a21565b817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610709573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072d9190610e4a565b6107379190610e37565b11156107c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d696e7420616d6f756e7420657863656564732072656d61696e696e6720617660448201527f61696c61626c6520737570706c79000000000000000000000000000000000000606482015260840161038f565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561085557600080fd5b505af1158015610869573d6000803e3d6000fd5b505050505050565b61088962093a806a01a784379d99db42000000610e63565b81565b6000610322610a55565b60006108a28383610b42565b90505b92915050565b6277f8806003546108bc9190610e37565b421015610925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45706f636820686173206e6f742066696e697368656420796574000000000000604482015260640161038f565b61092d610a83565b565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161038f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b60008060055460035442610a359190610e9e565b610a3f9190610eb1565b905080600454610a4f9190610e37565b91505090565b600354600090610a686277f88082610e37565b4210610a7e57610a76610a83565b505060035490565b919050565b6005546000610a956277f88083610eb1565b600454610aa29190610e37565b9050670e40fe0218cdc000610abf670de0b6b3a764000084610eb1565b610ac99190610e63565b9150600260008154610ada90610ec8565b919050819055506277f88060036000828254610af69190610e37565b90915550506005829055600481905560408051838152602081018390527fa96ad9a0b81b29565fbe231714a2f2c152b759e603c91bf87144a3f61944f0a5910160405180910390a15050565b600081831115610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f7374617274203e20656e64000000000000000000000000000000000000000000604482015260640161038f565b600354600554610bc16277f88083610e37565b841115610bff57610bd56277f88083610e37565b9150670e40fe0218cdc000610bf2670de0b6b3a764000083610eb1565b610bfc9190610e63565b90505b610c0c6277f88083610e37565b841115610c75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f746f6f2066617220696e20667574757265000000000000000000000000000000604482015260640161038f565b6000805b6103e7811015610d7357838610610d065785610c986277f88086610e37565b811115610caf57610cac6277f88086610e37565b90505b87610cbd6277f88087610e37565b8110610cca575050610d73565b85811015610cd55750845b610cdf8183610e9e565b610ce99086610eb1565b610cf39085610e37565b9350858910610d03575050610d73565b50505b610d136277f88085610e9e565b9350670de0b6b3a7640000610d30670e40fe0218cdc00085610eb1565b610d3a9190610e63565b9250610d5462093a806a01a784379d99db42000000610e63565b831115610d6357610d63610f00565b610d6c81610ec8565b9050610c79565b5095945050505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a7e57600080fd5b60008060408385031215610db457600080fd5b610dbd83610d7d565b946020939093013593505050565b60008060408385031215610dde57600080fd5b50508035926020909101359150565b600060208284031215610dff57600080fd5b6108a282610d7d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108a5576108a5610e08565b600060208284031215610e5c57600080fd5b5051919050565b600082610e99577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156108a5576108a5610e08565b80820281158282048414176108a5576108a5610e08565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ef957610ef9610e08565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea26469706673582212205558e67e04d90cb98142f8c330facfc6a1b5e51da9a30a31153701b60c3603ea64736f6c63430008130033000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca200000000000000000000000049f095b38ee6d8541758af51c509332e7793d4b00000000000000000000000002c3b135cd7dc6c673b358bef214843dab3464278

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c80637efad8e0116100ee578063b87b561611610097578063cb626ae211610071578063cb626ae2146102f4578063d43b40fa146102f4578063d725a9ca146102e1578063f2fde38b146102fc57600080fd5b8063b87b5616146102d7578063c167d1cd1461025d578063c3b03fa8146102e157600080fd5b8063a228bced116100c8578063a228bced146102cf578063adc4cf43146102cf578063b26b238e1461026557600080fd5b80637efad8e0146102a0578063819df2c41461026d5780638da5cb5b146102af57600080fd5b806324f92a251161015b57806340c10f191161013557806340c10f19146102755780634d2fa413146102885780634dbac7331461029057806355f741761461029857600080fd5b806324f92a251461025d578063277dbafb146102655780632c4e722e1461026d57600080fd5b80630f15f4c01161018c5780630f15f4c01461021e57806321609bbf1461022857806321df0da71461023757600080fd5b806307546172146101b3578063087905c9146102045780630dfbdce414610216575b600080fd5b6101da7f00000000000000000000000049f095b38ee6d8541758af51c509332e7793d4b081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6002545b6040519081526020016101fb565b61020861030f565b610226610327565b005b610208670e40fe0218cdc00081565b7f000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca26101da565b6102086105b5565b6102086105bf565b600554610208565b610226610283366004610da1565b6105d7565b600354610208565b610208610871565b600454610208565b610208670de0b6b3a764000081565b6001546101da9073ffffffffffffffffffffffffffffffffffffffff1681565b61020861088c565b6102086277f88081565b6102086102ef366004610dcb565b610896565b6102266108ab565b61022661030a366004610ded565b61092f565b60006277f8806003546103229190610e37565b905090565b600054600114610398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600260005560015473ffffffffffffffffffffffffffffffffffffffff16331461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161038f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600354146104a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f416c726561647920616374697661746564000000000000000000000000000000604482015260640161038f565b7f000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca273ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105389190610e4a565b6004554260035561055762093a806a01a784379d99db42000000610e63565b6005557fa96ad9a0b81b29565fbe231714a2f2c152b759e603c91bf87144a3f61944f0a561059362093a806a01a784379d99db42000000610e63565b6004546040805192835260208301919091520160405180910390a16001600055565b6000610322610a21565b60006277f8806105cd610a55565b6103229190610e37565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000049f095b38ee6d8541758af51c509332e7793d4b01614610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e54455200000000000000000000000000000000000000000000604482015260640161038f565b6277f8806003546106879190610e37565b421061069557610695610a83565b61069d610a21565b817f000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca273ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610709573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072d9190610e4a565b6107379190610e37565b11156107c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d696e7420616d6f756e7420657863656564732072656d61696e696e6720617660448201527f61696c61626c6520737570706c79000000000000000000000000000000000000606482015260840161038f565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca216906340c10f1990604401600060405180830381600087803b15801561085557600080fd5b505af1158015610869573d6000803e3d6000fd5b505050505050565b61088962093a806a01a784379d99db42000000610e63565b81565b6000610322610a55565b60006108a28383610b42565b90505b92915050565b6277f8806003546108bc9190610e37565b421015610925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45706f636820686173206e6f742066696e697368656420796574000000000000604482015260640161038f565b61092d610a83565b565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161038f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b60008060055460035442610a359190610e9e565b610a3f9190610eb1565b905080600454610a4f9190610e37565b91505090565b600354600090610a686277f88082610e37565b4210610a7e57610a76610a83565b505060035490565b919050565b6005546000610a956277f88083610eb1565b600454610aa29190610e37565b9050670e40fe0218cdc000610abf670de0b6b3a764000084610eb1565b610ac99190610e63565b9150600260008154610ada90610ec8565b919050819055506277f88060036000828254610af69190610e37565b90915550506005829055600481905560408051838152602081018390527fa96ad9a0b81b29565fbe231714a2f2c152b759e603c91bf87144a3f61944f0a5910160405180910390a15050565b600081831115610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f7374617274203e20656e64000000000000000000000000000000000000000000604482015260640161038f565b600354600554610bc16277f88083610e37565b841115610bff57610bd56277f88083610e37565b9150670e40fe0218cdc000610bf2670de0b6b3a764000083610eb1565b610bfc9190610e63565b90505b610c0c6277f88083610e37565b841115610c75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f746f6f2066617220696e20667574757265000000000000000000000000000000604482015260640161038f565b6000805b6103e7811015610d7357838610610d065785610c986277f88086610e37565b811115610caf57610cac6277f88086610e37565b90505b87610cbd6277f88087610e37565b8110610cca575050610d73565b85811015610cd55750845b610cdf8183610e9e565b610ce99086610eb1565b610cf39085610e37565b9350858910610d03575050610d73565b50505b610d136277f88085610e9e565b9350670de0b6b3a7640000610d30670e40fe0218cdc00085610eb1565b610d3a9190610e63565b9250610d5462093a806a01a784379d99db42000000610e63565b831115610d6357610d63610f00565b610d6c81610ec8565b9050610c79565b5095945050505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a7e57600080fd5b60008060408385031215610db457600080fd5b610dbd83610d7d565b946020939093013593505050565b60008060408385031215610dde57600080fd5b50508035926020909101359150565b600060208284031215610dff57600080fd5b6108a282610d7d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108a5576108a5610e08565b600060208284031215610e5c57600080fd5b5051919050565b600082610e99577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156108a5576108a5610e08565b80820281158282048414176108a5576108a5610e08565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ef957610ef9610e08565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea26469706673582212205558e67e04d90cb98142f8c330facfc6a1b5e51da9a30a31153701b60c3603ea64736f6c63430008130033

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

000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca200000000000000000000000049f095b38ee6d8541758af51c509332e7793d4b00000000000000000000000002c3b135cd7dc6c673b358bef214843dab3464278

-----Decoded View---------------
Arg [0] : token (address): 0xaFa52E3860b4371ab9d8F08E801E9EA1027C0CA2
Arg [1] : minter_ (address): 0x49f095B38eE6d8541758af51c509332e7793D4b0
Arg [2] : owner_ (address): 0x2C3B135cd7dc6C673b358BEF214843DAb3464278

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000afa52e3860b4371ab9d8f08e801e9ea1027c0ca2
Arg [1] : 00000000000000000000000049f095b38ee6d8541758af51c509332e7793d4b0
Arg [2] : 0000000000000000000000002c3b135cd7dc6c673b358bef214843dab3464278


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.