Moonbase Alpha Testnet

Contract

0x80E7CAeB210E92f842b52E7261eF4366Cda13bbd

Overview

DEV Balance

Moonbase Alpha LogoMoonbase Alpha LogoMoonbase Alpha Logo0 DEV

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Approve102912592025-01-11 12:59:5414 days ago1736600394IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000001870.03125
Approve79808642024-07-25 8:18:24185 days ago1721895504IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve79808522024-07-25 8:17:00185 days ago1721895420IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve79808482024-07-25 8:15:36185 days ago1721895336IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve79808392024-07-25 8:14:42185 days ago1721895282IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve79808282024-07-25 8:13:30185 days ago1721895210IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve75322612024-06-21 0:32:00219 days ago1718929920IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve75322552024-06-21 0:31:24219 days ago1718929884IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000007550.125
Approve60721952024-02-15 4:07:36346 days ago1707970056IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000003030.125
Approve60082192024-02-05 19:09:18355 days ago1707160158IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000039461.625
Approve58311792024-01-05 8:38:00387 days ago1704443880IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000039461.625
Approve53140892023-10-18 1:23:36466 days ago1697592216IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000039461.625
Approve50598932023-09-06 16:23:42507 days ago1694017422IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000039461.625
Approve43365662023-05-13 0:24:06624 days ago1683937446IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000039461.625
Approve37771042023-02-18 14:11:30707 days ago1676729490IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000036461.5012502
Approve34133032022-12-23 23:59:36764 days ago1671839976IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34130082022-12-23 22:53:48764 days ago1671836028IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34121702022-12-23 19:40:30764 days ago1671824430IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34109392022-12-23 15:01:42764 days ago1671807702IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34109222022-12-23 14:58:12764 days ago1671807492IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34107382022-12-23 14:17:00764 days ago1671805020IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34107112022-12-23 14:11:12764 days ago1671804672IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34105042022-12-23 13:25:24764 days ago1671801924IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34099452022-12-23 11:19:00764 days ago1671794340IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5
Approve34098772022-12-23 11:03:48764 days ago1671793428IN
0x80E7CAeB...6Cda13bbd
0 DEV0.000116432.5

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
37655412023-02-16 20:53:54709 days ago1676580834
0x80E7CAeB...6Cda13bbd
0 DEV
37160282023-02-09 15:09:30716 days ago1675955370
0x80E7CAeB...6Cda13bbd
0 DEV
37129492023-02-09 4:24:06717 days ago1675916646
0x80E7CAeB...6Cda13bbd
0 DEV
37062732023-02-08 5:06:12718 days ago1675832772
0x80E7CAeB...6Cda13bbd
0 DEV
36944872023-02-06 11:47:06719 days ago1675684026
0x80E7CAeB...6Cda13bbd
0 DEV
36927592023-02-06 5:48:00720 days ago1675662480
0x80E7CAeB...6Cda13bbd
0 DEV
36927462023-02-06 5:45:24720 days ago1675662324
0x80E7CAeB...6Cda13bbd
0 DEV
36927412023-02-06 5:44:18720 days ago1675662258
0x80E7CAeB...6Cda13bbd
0 DEV
36864762023-02-05 8:02:30721 days ago1675584150
0x80E7CAeB...6Cda13bbd
0 DEV
36773852023-02-04 0:40:06722 days ago1675471206
0x80E7CAeB...6Cda13bbd
0 DEV
36725792023-02-03 7:57:48723 days ago1675411068
0x80E7CAeB...6Cda13bbd
0 DEV
36613542023-02-01 16:23:18724 days ago1675268598
0x80E7CAeB...6Cda13bbd
0 DEV
36449802023-01-30 3:22:18727 days ago1675048938
0x80E7CAeB...6Cda13bbd
0 DEV
34182582022-12-24 18:45:54763 days ago1671907554
0x80E7CAeB...6Cda13bbd
0 DEV
34182532022-12-24 18:44:42763 days ago1671907482
0x80E7CAeB...6Cda13bbd
0 DEV
34182432022-12-24 18:42:24763 days ago1671907344
0x80E7CAeB...6Cda13bbd
0 DEV
34182352022-12-24 18:40:42763 days ago1671907242
0x80E7CAeB...6Cda13bbd
0 DEV
34182092022-12-24 18:32:48763 days ago1671906768
0x80E7CAeB...6Cda13bbd
0 DEV
34181812022-12-24 18:24:42763 days ago1671906282
0x80E7CAeB...6Cda13bbd
0 DEV
34176392022-12-24 16:24:18763 days ago1671899058
0x80E7CAeB...6Cda13bbd
0 DEV
34174002022-12-24 15:29:42763 days ago1671895782
0x80E7CAeB...6Cda13bbd
0 DEV
34172102022-12-24 14:46:30763 days ago1671893190
0x80E7CAeB...6Cda13bbd
0 DEV
34171392022-12-24 14:30:54763 days ago1671892254
0x80E7CAeB...6Cda13bbd
0 DEV
34170252022-12-24 14:05:12763 days ago1671890712
0x80E7CAeB...6Cda13bbd
0 DEV
34169472022-12-24 13:44:00763 days ago1671889440
0x80E7CAeB...6Cda13bbd
0 DEV
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
QodaERC20

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 12 : QodaERC20.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./interfaces/IQodaERC20.sol";
import "./interfaces/IQAdmin.sol";

contract QodaERC20 is ERC20, IQodaERC20 {

  /// @notice Contract storing all global Qoda parameters
  IQAdmin private _qAdmin;

  uint private immutable _SUPPLY_CAP;
  
  constructor(address qAdminAddress, uint supplyCap_) ERC20("Qoda Token", "QODA") {
    _qAdmin = IQAdmin(qAdminAddress);
    _SUPPLY_CAP = supplyCap_;    
  }

  /// @notice Modifier which checks that the caller has the minter role
  modifier onlyMinter() {
    require(_qAdmin.hasRole(_qAdmin.MINTER_ROLE(), msg.sender), "QodaERC20: only minter");
    _;
  }

  /// @notice Mints tokens to a recipient, as long as it is under the
  /// supply cap. Reverts if the caller does not have the minter role.
  /// Mint will fail without revert if total supply exceeds `_SUPPLY_CAP`.
  /// @param recipient Account to mint tokens to
  /// @param amount Amount of tokens to mint
  /// @return bool True if mint successful, false otherwise
  function mint(address recipient, uint amount) external onlyMinter returns(bool){
    if(totalSupply() + amount <= _SUPPLY_CAP) {
      _mint(recipient, amount);
      return true;
    }
    return false;
  }
  
  function supplyCap() external view returns(uint) {
    return _SUPPLY_CAP;
  }
}

File 2 of 12 : IQodaERC20.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

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

interface IQodaERC20 is IERC20, IERC20Metadata {
  
  /// @notice Mints tokens to a recipient, as long as it is under the
  /// supply cap. Reverts if the caller does not have the minter role.
  /// @param recipient Account to mint tokens to
  /// @param amount Amount of tokens to mint
  function mint(address recipient, uint amount) external returns(bool);
  
  function supplyCap() external view returns(uint);
}

File 3 of 12 : IQAdmin.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IFixedRateMarket.sol";
import "../libraries/QTypes.sol";

interface IQAdmin is IAccessControlUpgradeable {

  /// @notice Emitted when a new FixedRateMarket is deployed
  event CreateFixedRateMarket(address indexed marketAddress, address indexed tokenAddress, uint maturity);
  
  /// @notice Emitted when a new `Asset` is added
  event AddAsset(
                 address indexed tokenAddress,
                 bool isYieldBearing,
                 address oracleFeed,
                 uint collateralFactor,
                 uint marketFactor);

  /// @notice Emitted when setting `_qollateralManager`
  event SetQollateralManager(address qollateralManagerAddress);

  /// @notice Emitted when setting `_stakingEmissionsQontroller`
  event SetStakingEmissionsQontroller(address stakingEmissionsQontrollerAddress);

  /// @notice Emitted when setting `_tradingEmissionsQontroller`
  event SetTradingEmissionsQontroller(address tradingEmissionsQontrollerAddress);

  /// @notice Emitted when setting `_feeEmissionsQontroller`
  event SetFeeEmissionsQontroller(address feeEmissionsQontrollerAddress);

  /// @notice Emitted when setting `_veQoda`
  event SetVeQoda(address veQodaAddress);
  
  /// @notice Emitted when setting `collateralFactor`
  event SetCollateralFactor(address indexed tokenAddress, uint oldValue, uint newValue);

  /// @notice Emitted when setting `marketFactor`
  event SetMarketFactor(address indexed tokenAddress, uint oldValue, uint newValue);

  /// @notice Emitted when setting `minQuoteSize`
  event SetMinQuoteSize(address indexed tokenAddress, uint oldValue, uint newValue);
  
  /// @notice Emitted when `_initCollateralRatio` gets updated
  event SetInitCollateralRatio(uint oldValue, uint newValue);

  /// @notice Emitted when `_closeFactor` gets updated
  event SetCloseFactor(uint oldValue, uint newValue);

  /// @notice Emitted when `_repaymentGracePeriod` gets updated
  event SetRepaymentGracePeriod(uint oldValue, uint newValue);
  
  /// @notice Emitted when `_maturityGracePeriod` gets updated
  event SetMaturityGracePeriod(uint oldValue, uint newValue);
  
  /// @notice Emitted when `_liquidationIncentive` gets updated
  event SetLiquidationIncentive(uint oldValue, uint newValue);

  /// @notice Emitted when `_protocolFee` gets updated
  event SetProtocolFee(uint oldValue, uint newValue);
  
  /// @notice Emitted when `creditLimit` gets updated
  event SetCreditLimit(address accountAddress, uint oldValue, uint newValue); 
  
  /** ADMIN FUNCTIONS **/

  /// @notice Call upon initialization after deploying `QollateralManager` contract
  /// @param qollateralManagerAddress Address of `QollateralManager` deployment
  function _setQollateralManager(address qollateralManagerAddress) external;

  /// @notice Call upon initialization after deploying `StakingEmissionsQontroller` contract
  /// @param stakingEmissionsQontrollerAddress Address of `StakingEmissionsQontroller` deployment
  function _setStakingEmissionsQontroller(address stakingEmissionsQontrollerAddress) external;

  /// @notice Call upon initialization after deploying `TradingEmissionsQontroller` contract
  /// @param tradingEmissionsQontrollerAddress Address of `TradingEmissionsQontroller` deployment
  function _setTradingEmissionsQontroller(address tradingEmissionsQontrollerAddress) external;

  /// @notice Call upon initialization after deploying `FeeEmissionsQontroller` contract
  /// @param feeEmissionsQontrollerAddress Address of `FeeEmissionsQontroller` deployment
  function _setFeeEmissionsQontroller(address feeEmissionsQontrollerAddress) external;

  /// @notice Call upon initialization after deploying `veQoda` contract
  /// @param veQodaAddress Address of `veQoda` deployment
  function _setVeQoda(address veQodaAddress) external;
  
  /// @notice Call to adjust allowed limit in USD for given address to do uncollateralized borrow
  /// Note that if credit limit is lowered, there might be chance where user's loan is subjected to 
  /// instant liquidations. So it's crucial to notify the user in advance before attempting the action.
  /// @param accountAddress accoutn for credit limit adjustment
  /// @param creditLimit_ new credit limit in USD, scaled by 1e6
  function _setCreditLimit(address accountAddress, uint creditLimit_) external;

  /// @notice Admin function for adding new Assets. An Asset must be added before it
  /// can be used as collateral or borrowed. Note: We can create functionality for
  /// allowing borrows of a token but not using it as collateral by setting
  /// `collateralFactor` to zero.
  /// @param token ERC20 token corresponding to the Asset
  /// @param isYieldBearing True if token bears interest (eg aToken, cToken, mToken, etc)
  /// @param underlying Address of the underlying token
  /// @param oracleFeed Chainlink price feed address
  /// @param collateralFactor 0.0 to 1.0 (scaled to 1e8) for discounting risky assets
  /// @param marketFactor 0.0 to 1.0 (scaled to 1e8) for premium on risky borrows
  function _addAsset(
                     IERC20 token,
                     bool isYieldBearing,
                     address underlying,
                     address oracleFeed,
                     uint collateralFactor,
                     uint marketFactor
                     ) external;

  /// @notice Adds a new `FixedRateMarket` contract into the internal mapping of
  /// whitelisted market addresses
  /// @param market New `FixedRateMarket` contract
  function _addFixedRateMarket(IFixedRateMarket market) external;
  
  /// @notice Update the `collateralFactor` for a given `Asset`
  /// @param token ERC20 token corresponding to the Asset
  /// @param collateralFactor 0.0 to 1.0 (scaled to 1e8) for discounting risky assets
  function _setCollateralFactor(IERC20 token, uint collateralFactor) external;

  /// @notice Update the `marketFactor` for a given `Asset`
  /// @param token Address of the token corresponding to the Asset
  /// @param marketFactor 0.0 to 1.0 (scaled to 1e8) for discounting risky assets
  function _setMarketFactor(IERC20 token, uint marketFactor) external;

  /// @notice Set the minimum quote size for a particular `FixedRateMarket`
  /// @param market Address of the `FixedRateMarket` contract
  /// @param minQuoteSize_ Size in PV terms, local currency
  function _setMinQuoteSize(IFixedRateMarket market, uint minQuoteSize_) external;
  
  /// @notice Set the global initial collateral ratio
  /// @param initCollateralRatio_ New collateral ratio value
  function _setInitCollateralRatio(uint initCollateralRatio_) external;

  /// @notice Set the global close factor
  /// @param closeFactor_ New close factor value
  function _setCloseFactor(uint closeFactor_) external;

  /// @notice Set the global repayment grace period
  /// @param repaymentGracePeriod_ New repayment grace period
  function _setRepaymentGracePeriod(uint repaymentGracePeriod_) external;

  /// @notice Set the global maturity grace period
  /// @param maturityGracePeriod_ New maturity grace period
  function _setMaturityGracePeriod(uint maturityGracePeriod_) external;
  
  /// @notice Set the global liquidation incetive
  /// @param liquidationIncentive_ New liquidation incentive value
  function _setLiquidationIncentive(uint liquidationIncentive_) external;

  /// @notice Set the global annualized protocol fees for each market in basis points
  /// @param market Address of the `FixedRateMarket` contract
  /// @param protocolFee_ New protocol fee value (scaled to 1e4)
  function _setProtocolFee(IFixedRateMarket market, uint protocolFee_) external;
  
  /// @notice Set the global threshold in USD for protocol fee transfer
  /// @param thresholdUSD_ New threshold USD value (scaled by 1e6)
  function _setThresholdUSD(uint thresholdUSD_) external;
  
  /** VIEW FUNCTIONS **/

  function ADMIN_ROLE() external view returns(bytes32);

  function MARKET_ROLE() external view returns(bytes32);

  function MINTER_ROLE() external view returns(bytes32);

  function VETOKEN_ROLE() external view returns(bytes32);
  
  /// @notice Get the address of the `QollateralManager` contract
  function qollateralManager() external view returns(address);

  /// @notice Get the address of the `QPriceOracle` contract
  function qPriceOracle() external view returns(address);

  /// @notice Get the address of the `StakingEmissionsQontroller` contract
  function stakingEmissionsQontroller() external view returns(address);

  /// @notice Get the address of the `TradingEmissionsQontroller` contract
  function tradingEmissionsQontroller() external view returns(address);

  /// @notice Get the address of the `FeeEmissionsQontroller` contract
  function feeEmissionsQontroller() external view returns(address);

  /// @notice Get the address of the `veQoda` contract
  function veQoda() external view returns(address);

  /// @notice Get the credit limit with associated address, scaled by 1e6
  function creditLimit(address accountAddress) external view returns(uint);
  
  /// @notice Gets the `Asset` mapped to the address of a ERC20 token
  /// @param token ERC20 token
  /// @return QTypes.Asset Associated `Asset`
  function assets(IERC20 token) external view returns(QTypes.Asset memory);

  /// @notice Get all enabled `Asset`s
  /// @return address[] iterable list of enabled `Asset`s
  function allAssets() external view returns(address[] memory);
  
  /// @notice Gets the `CollateralFactor` associated with a ERC20 token
  /// @param token ERC20 token
  /// @return uint Collateral Factor, scaled by 1e8
  function collateralFactor(IERC20 token) external view returns(uint);

  /// @notice Gets the `MarketFactor` associated with a ERC20 token
  /// @param token ERC20 token
  /// @return uint Market Factor, scaled by 1e8
  function marketFactor(IERC20 token) external view returns(uint);

  /// @notice Gets the `maturities` associated with a ERC20 token
  /// @param token ERC20 token
  /// @return uint[] array of UNIX timestamps (in seconds) of the maturity dates
  function maturities(IERC20 token) external view returns(uint[] memory);
  
  /// @notice Get the MToken market corresponding to any underlying ERC20
  /// tokenAddress => mTokenAddress
  function underlyingToMToken(IERC20 token) external view returns(address);
  
  /// @notice Gets the address of the `FixedRateMarket` contract
  /// @param token ERC20 token
  /// @param maturity UNIX timestamp of the maturity date
  /// @return IFixedRateMarket Address of `FixedRateMarket` contract
  function fixedRateMarkets(IERC20 token, uint maturity) external view returns(IFixedRateMarket);

  /// @notice Check whether an address is a valid FixedRateMarket address.
  /// Can be used for checks for inter-contract admin/restricted function call.
  /// @param market `FixedRateMarket` contract
  /// @return bool True if valid false otherwise
  function isMarketEnabled(IFixedRateMarket market) external view returns(bool);

  function minQuoteSize(IFixedRateMarket market) external view returns(uint);
  
  function minCollateralRatio() external view returns(uint);

  function initCollateralRatio() external view returns(uint);

  function closeFactor() external view returns(uint);

  function repaymentGracePeriod() external view returns(uint);
  
  function maturityGracePeriod() external view returns(uint);
  
  function liquidationIncentive() external view returns(uint);

  /// @notice Annualized protocol fee in basis points, scaled by 1e4
  function protocolFee(IFixedRateMarket market) external view returns(uint);

  /// @notice threshold in USD where protocol fee from each market will be transferred into `FeeEmissionsQontroller`
  /// once this amount is reached, scaled by 1e6
  function thresholdUSD() external view returns(uint);
  
  /// @notice 2**256 - 1
  function UINT_MAX() external pure returns(uint);
  
  /// @notice Generic mantissa corresponding to ETH decimals
  function MANTISSA_DEFAULT() external pure returns(uint);

  /// @notice Mantissa for stablecoins
  function MANTISSA_STABLECOIN() external pure returns(uint);
  
  /// @notice Mantissa for collateral ratio
  function MANTISSA_COLLATERAL_RATIO() external pure returns(uint);

  /// @notice `assetFactor` and `marketFactor` have up to 8 decimal places precision
  function MANTISSA_FACTORS() external pure returns(uint);

  /// @notice Basis points have 4 decimal place precision
  function MANTISSA_BPS() external pure returns(uint);

  /// @notice Staked Qoda has 6 decimal place precision
  function MANTISSA_STAKING() external pure returns(uint);

  /// @notice `collateralFactor` cannot be above 1.0
  function MAX_COLLATERAL_FACTOR() external pure returns(uint);

  /// @notice `marketFactor` cannot be above 1.0
  function MAX_MARKET_FACTOR() external pure returns(uint);

  /// @notice version number of this contract, will be bumped upon contractual change
  function VERSION_NUMBER() external pure returns(string memory);
}

File 4 of 12 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../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:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, 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}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, 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}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, 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) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, 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) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * 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:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, 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 Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - 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 5 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 6 of 12 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../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 7 of 12 : QTypes.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

library QTypes {

  /// @notice Contains all the details of an Asset. Assets  must be defined
  /// before they can be used as collateral.
  /// @member isEnabled True if an asset is defined, false otherwise
  /// @member isYieldBearing True if token bears interest (eg aToken, cToken, mToken, etc)
  /// @member underlying Address of the underlying token
  /// @member oracleFeed Address of the corresponding chainlink oracle feed
  /// @member collateralFactor 0.0 to 1.0 (scaled to 1e8) for discounting risky assets
  /// @member marketFactor 0.0 1.0 for premium on risky borrows
  /// @member maturities Iterable storage for all enabled maturities
  struct Asset {
    bool isEnabled;
    bool isYieldBearing;
    address underlying;
    address oracleFeed;
    uint collateralFactor;
    uint marketFactor;
    uint[] maturities;
  }

  /// @notice Contains all the fields of a published Quote
  /// @notice quoteId ID of the quote - this is the keccak256 hash of signature
  /// @param marketAddress Address of `FixedRateLoanMarket` contract
  /// @param quoter Account of the Quoter
  /// @param quoteType 0 for PV+APR, 1 for FV+APR
  /// @param side 0 if Quoter is borrowing, 1 if Quoter is lending
  /// @param quoteExpiryTime Timestamp after which the quote is no longer valid
  /// @param APR In decimal form scaled by 1e4 (ex. 10.52% = 1052)
  /// @param cashflow Can be PV or FV depending on `quoteType`
  /// @param nonce For uniqueness of signature
  /// @param signature Signed hash of the Quote message
  struct Quote {
    bytes32 quoteId;
    address marketAddress;
    address quoter;
    uint8 quoteType;
    uint8 side;
    uint64 quoteExpiryTime; //if 0, then quote never expires
    uint64 APR;
    uint cashflow;
    uint nonce;
    bytes signature;
  }
  

}

File 8 of 12 : IFixedRateMarket.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IFixedRateMarket is IERC20Upgradeable, IERC20MetadataUpgradeable {

  /// @notice Emitted when a borrower repays borrow.
  /// Boolean flag `withQTokens`= true if repaid via qTokens, false otherwise.
  event RepayBorrow(address indexed borrower, uint amount, bool withQTokens);

  /// @notice Emitted when a borrower is liquidated
  event LiquidateBorrow(
    address indexed borrower,
    address indexed liquidator,
    uint amount,
    address collateralTokenAddress,
    uint reward
  );

  /// @notice Emitted when a borrower and lender are matched for a fixed rate loan
  event FixedRateLoan(
    bytes32 indexed quoteId,
    address indexed borrower,
    address indexed lender,
    uint amountPV,
    uint amountFV,
    uint feeIncurred);

  /// @notice Emitted when an account cancels their Quote
  event CancelQuote(address indexed account, uint nonce);

  /// @notice Emitted when an account redeems their qTokens
  event RedeemQTokens(address indexed account, uint amount);
    
  /** USER INTERFACE **/

  /// @notice Execute against Quote as a borrower.
  /// @param amountPV Amount that the borrower wants to execute as PV
  /// @param lender Account of the lender
  /// @param quoteType *Lender's* type preference, 0 for PV+APR, 1 for FV+APR
  /// @param quoteExpiryTime Timestamp after which the quote is no longer valid
  /// @param APR In decimal form scaled by 1e4 (ex. 10.52% = 1052)
  /// @param cashflow Can be PV or FV depending on `quoteType`
  /// @param nonce For uniqueness of signature
  /// @param signature signed hash of the Quote message
  /// @return uint, uint Loan amount (`amountPV`) and repayment amount (`amountFV`)
  function borrow(
                  uint amountPV,
                  address lender,
                  uint8 quoteType,
                  uint64 quoteExpiryTime,
                  uint64 APR,
                  uint cashflow,
                  uint nonce,
                  bytes memory signature
                  ) external returns(uint, uint);

  /// @notice Execute against Quote as a lender.
  /// @param amountPV Amount that the lender wants to execute as PV
  /// @param borrower Account of the borrower
  /// @param quoteType *Borrower's* type preference, 0 for PV+APR, 1 for FV+APR
  /// @param quoteExpiryTime Timestamp after which the quote is no longer valid
  /// @param APR In decimal form scaled by 1e4 (ex. 10.52% = 1052)
  /// @param cashflow Can be PV or FV depending on `quoteType`
  /// @param nonce For uniqueness of signature
  /// @param signature signed hash of the Quote message
  /// @return uint, uint Loan amount (`amountPV`) and repayment amount (`amountFV`)
  function lend(
                uint amountPV,
                address borrower,
                uint8 quoteType,
                uint64 quoteExpiryTime,
                uint64 APR,
                uint cashflow,
                uint nonce,
                bytes memory signature
                ) external returns(uint, uint);
  
  /// @notice Borrower will make repayments to the smart contract, which
  /// holds the value in escrow until maturity to release to lenders.
  /// @param amount Amount to repay
  /// @return uint Remaining account borrow amount
  function repayBorrow(uint amount) external returns(uint);

  /// @notice By setting the nonce in `_voidNonces` to true, this is equivalent to
  /// invalidating the Quote (i.e. cancelling the quote)
  /// param nonce Nonce of the Quote to be cancelled
  function cancelQuote(uint nonce) external;

  /// @notice This function allows net lenders to redeem qTokens for the
  /// underlying token. Redemptions may only be permitted after loan maturity
  /// plus `_maturityGracePeriod`. The public interface redeems specified amount
  /// of qToken from existing balance.
  /// @param amount Amount of qTokens to redeem
  /// @return uint Amount of qTokens redeemed
  function redeemQTokensByRatio(uint amount) external returns(uint);

  /// @notice This function allows net lenders to redeem qTokens for the
  /// underlying token. Redemptions may only be permitted after loan maturity
  /// plus `_maturityGracePeriod`. The public interface redeems the entire qToken
  /// balance.
  /// @return uint Amount of qTokens redeemed
  function redeemAllQTokensByRatio() external returns(uint);

  /// @notice Get amount of qTokens user can redeem based on current loan repayment ratio
  /// @return uint amount of qTokens user can redeem
  function redeemableQTokens() external view returns(uint);

  /// @notice If an account is in danger of being undercollateralized (i.e.
  /// collateralRatio < 1.0) or has not repaid past maturity plus `_repaymentGracePeriod`,
  /// any user may liquidate that account by paying back the loan on behalf of the account. 
  /// In return, the liquidator receives collateral belonging to the account equal in value to 
  /// the repayment amount in USD plus the liquidation incentive amount as a bonus.
  /// @param borrower Address of account that is undercollateralized
  /// @param amount Amount to repay on behalf of account
  /// @param collateralToken Liquidator's choice of which currency to be paid in
  function liquidateBorrow(
                           address borrower,
                           uint amount,
                           IERC20 collateralToken
                           ) external;
  
  /** VIEW FUNCTIONS **/
  
  /// @notice Get the address of the `QollateralManager`
  /// @return address
  function qollateralManager() external view returns(address);

  /// @notice Get the address of the ERC20 token which the loan will be denominated
  /// @return IERC20
  function underlyingToken() external view returns(IERC20);

  /// @notice Get the UNIX timestamp (in seconds) when the market matures
  /// @return uint
  function maturity() external view returns(uint);

  /// @notice Get the minimum quote size for this market
  /// @return uint Minimum quote size, in PV terms, local currency
  function minQuoteSize() external view returns(uint);
  
  /// @notice True if a nonce for a Quote is voided, false otherwise.
  /// Used for checking if a Quote is a duplicated.
  /// @param account Account to query
  /// @param nonce Nonce to query
  /// @return bool True if used, false otherwise
  function isNonceVoid(address account, uint nonce) external view returns(bool);

  /// @notice Get the total balance of borrows by user
  /// @param account Account to query
  /// @return uint Borrows
  function accountBorrows(address account) external view returns(uint);

  /// @notice Get the current total partial fill for a Quote
  /// @param quoteId ID of the Quote - this is the keccak256 hash of the signature
  /// @return uint Partial fill
  function quoteFill(bytes32 quoteId) external view returns(uint);

  /// @notice Get the `protocolFee` associated with this market
  /// @return uint annualized protocol fee, scaled by 1e4
  function protocolFee() external view returns(uint);

  /// @notice Get the `protocolFee` associated with this market, prorated by time till maturity 
  /// @param amount loan amount
  /// @param timeNow block timestamp for calculating time till maturity 
  /// @return uint prorated protocol fee, scaled by 1e4
  function proratedProtocolFee(uint amount, uint timeNow) external view returns(uint);

  /// @notice Get the `protocolFee` associated with this market, prorated by time till maturity from now 
  /// @param amount loan amount
  /// @return uint prorated protocol fee, scaled by 1e4
  function proratedProtocolFeeNow(uint amount) external view returns(uint);

  /// @notice Gets the current `redemptionRatio` where owned qTokens can be redeemed up to
  /// @return uint redemption ratio, scaled by 1e18
  function redemptionRatio() external view returns(uint);

  /// @notice Tokens redeemed across all users so far
  /// @return uint redeemed amount of qToken
  function tokensRedeemedTotal() external view returns(uint);

  /// @notice Get total protocol fee accrued in this market so far, in local currency
  /// @return uint accrued fee
  function totalAccruedFees() external view returns(uint);

}

File 9 of 12 : IAccessControlUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControlUpgradeable {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 10 of 12 : IERC20Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20Upgradeable {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 11 of 12 : IERC20MetadataUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20Upgradeable.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
    /**
     * @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 12 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

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;
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"qAdminAddress","type":"address"},{"internalType":"uint256","name":"supplyCap_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b5060405162000d7f38038062000d7f83398101604081905262000034916200016b565b604080518082018252600a81526928b7b230902a37b5b2b760b11b602080830191825283518085019094526004845263514f444160e01b9084015281519192916200008291600391620000c5565b50805162000098906004906020840190620000c5565b5050600580546001600160a01b0319166001600160a01b03949094169390931790925560805250620001e4565b828054620000d390620001a7565b90600052602060002090601f016020900481019282620000f7576000855562000142565b82601f106200011257805160ff191683800117855562000142565b8280016001018555821562000142579182015b828111156200014257825182559160200191906001019062000125565b506200015092915062000154565b5090565b5b8082111562000150576000815560010162000155565b600080604083850312156200017f57600080fd5b82516001600160a01b03811681146200019757600080fd5b6020939093015192949293505050565b600181811c90821680620001bc57607f821691505b60208210811415620001de57634e487b7160e01b600052602260045260246000fd5b50919050565b608051610b78620002076000396000818161019a01526104190152610b786000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c57806395d89b411161006657806395d89b41146101be578063a457c2d7146101c6578063a9059cbb146101d9578063dd62ed3e146101ec57600080fd5b806340c10f191461015c57806370a082311461016f5780638f770ad01461019857600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd14610127578063313ce5671461013a5780633950935114610149575b600080fd5b6100dc6101ff565b6040516100e9919061097a565b60405180910390f35b6101056101003660046109eb565b610291565b60405190151581526020016100e9565b6002545b6040519081526020016100e9565b610105610135366004610a15565b6102ab565b604051601281526020016100e9565b6101056101573660046109eb565b6102cf565b61010561016a3660046109eb565b6102f1565b61011961017d366004610a51565b6001600160a01b031660009081526020819052604090205490565b7f0000000000000000000000000000000000000000000000000000000000000000610119565b6100dc61046c565b6101056101d43660046109eb565b61047b565b6101056101e73660046109eb565b6104f6565b6101196101fa366004610a73565b610504565b60606003805461020e90610aa6565b80601f016020809104026020016040519081016040528092919081815260200182805461023a90610aa6565b80156102875780601f1061025c57610100808354040283529160200191610287565b820191906000526020600020905b81548152906001019060200180831161026a57829003601f168201915b5050505050905090565b60003361029f81858561052f565b60019150505b92915050565b6000336102b9858285610653565b6102c48585856106cd565b506001949350505050565b60003361029f8185856102e28383610504565b6102ec9190610ae1565b61052f565b6005546040805163d539139360e01b815290516000926001600160a01b0316916391d1485491839163d53913939160048083019260209291908290030181865afa158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610b07565b6040516001600160e01b031960e084901b1681526004810191909152336024820152604401602060405180830381865afa1580156103a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cd9190610b20565b6104175760405162461bcd60e51b815260206004820152601660248201527528b7b230a2a92199181d1037b7363c9036b4b73a32b960511b60448201526064015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008261044260025490565b61044c9190610ae1565b116104635761045b838361089b565b5060016102a5565b50600092915050565b60606004805461020e90610aa6565b600033816104898286610504565b9050838110156104e95760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161040e565b6102c4828686840361052f565b60003361029f8185856106cd565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166105915760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161040e565b6001600160a01b0382166105f25760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161040e565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061065f8484610504565b905060001981146106c757818110156106ba5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161040e565b6106c7848484840361052f565b50505050565b6001600160a01b0383166107315760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161040e565b6001600160a01b0382166107935760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161040e565b6001600160a01b0383166000908152602081905260409020548181101561080b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161040e565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290610842908490610ae1565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161088e91815260200190565b60405180910390a36106c7565b6001600160a01b0382166108f15760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161040e565b80600260008282546109039190610ae1565b90915550506001600160a01b03821660009081526020819052604081208054839290610930908490610ae1565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600060208083528351808285015260005b818110156109a75785810183015185820160400152820161098b565b818111156109b9576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146109e657600080fd5b919050565b600080604083850312156109fe57600080fd5b610a07836109cf565b946020939093013593505050565b600080600060608486031215610a2a57600080fd5b610a33846109cf565b9250610a41602085016109cf565b9150604084013590509250925092565b600060208284031215610a6357600080fd5b610a6c826109cf565b9392505050565b60008060408385031215610a8657600080fd5b610a8f836109cf565b9150610a9d602084016109cf565b90509250929050565b600181811c90821680610aba57607f821691505b60208210811415610adb57634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115610b0257634e487b7160e01b600052601160045260246000fd5b500190565b600060208284031215610b1957600080fd5b5051919050565b600060208284031215610b3257600080fd5b81518015158114610a6c57600080fdfea2646970667358221220d573892c840f6dbdab2ef0becb36d6df5110ed98640e3398592e7a2b6e39ca9764736f6c634300080a0033000000000000000000000000b575a3d12d95e72249acbfce0f90abe28515d9f90000000000000000000000000000000000000000033b2e3c9fd0803ce8000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c57806395d89b411161006657806395d89b41146101be578063a457c2d7146101c6578063a9059cbb146101d9578063dd62ed3e146101ec57600080fd5b806340c10f191461015c57806370a082311461016f5780638f770ad01461019857600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd14610127578063313ce5671461013a5780633950935114610149575b600080fd5b6100dc6101ff565b6040516100e9919061097a565b60405180910390f35b6101056101003660046109eb565b610291565b60405190151581526020016100e9565b6002545b6040519081526020016100e9565b610105610135366004610a15565b6102ab565b604051601281526020016100e9565b6101056101573660046109eb565b6102cf565b61010561016a3660046109eb565b6102f1565b61011961017d366004610a51565b6001600160a01b031660009081526020819052604090205490565b7f0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000610119565b6100dc61046c565b6101056101d43660046109eb565b61047b565b6101056101e73660046109eb565b6104f6565b6101196101fa366004610a73565b610504565b60606003805461020e90610aa6565b80601f016020809104026020016040519081016040528092919081815260200182805461023a90610aa6565b80156102875780601f1061025c57610100808354040283529160200191610287565b820191906000526020600020905b81548152906001019060200180831161026a57829003601f168201915b5050505050905090565b60003361029f81858561052f565b60019150505b92915050565b6000336102b9858285610653565b6102c48585856106cd565b506001949350505050565b60003361029f8185856102e28383610504565b6102ec9190610ae1565b61052f565b6005546040805163d539139360e01b815290516000926001600160a01b0316916391d1485491839163d53913939160048083019260209291908290030181865afa158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610b07565b6040516001600160e01b031960e084901b1681526004810191909152336024820152604401602060405180830381865afa1580156103a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cd9190610b20565b6104175760405162461bcd60e51b815260206004820152601660248201527528b7b230a2a92199181d1037b7363c9036b4b73a32b960511b60448201526064015b60405180910390fd5b7f0000000000000000000000000000000000000000033b2e3c9fd0803ce80000008261044260025490565b61044c9190610ae1565b116104635761045b838361089b565b5060016102a5565b50600092915050565b60606004805461020e90610aa6565b600033816104898286610504565b9050838110156104e95760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161040e565b6102c4828686840361052f565b60003361029f8185856106cd565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166105915760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161040e565b6001600160a01b0382166105f25760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161040e565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061065f8484610504565b905060001981146106c757818110156106ba5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161040e565b6106c7848484840361052f565b50505050565b6001600160a01b0383166107315760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161040e565b6001600160a01b0382166107935760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161040e565b6001600160a01b0383166000908152602081905260409020548181101561080b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161040e565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290610842908490610ae1565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161088e91815260200190565b60405180910390a36106c7565b6001600160a01b0382166108f15760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161040e565b80600260008282546109039190610ae1565b90915550506001600160a01b03821660009081526020819052604081208054839290610930908490610ae1565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600060208083528351808285015260005b818110156109a75785810183015185820160400152820161098b565b818111156109b9576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146109e657600080fd5b919050565b600080604083850312156109fe57600080fd5b610a07836109cf565b946020939093013593505050565b600080600060608486031215610a2a57600080fd5b610a33846109cf565b9250610a41602085016109cf565b9150604084013590509250925092565b600060208284031215610a6357600080fd5b610a6c826109cf565b9392505050565b60008060408385031215610a8657600080fd5b610a8f836109cf565b9150610a9d602084016109cf565b90509250929050565b600181811c90821680610aba57607f821691505b60208210811415610adb57634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115610b0257634e487b7160e01b600052601160045260246000fd5b500190565b600060208284031215610b1957600080fd5b5051919050565b600060208284031215610b3257600080fd5b81518015158114610a6c57600080fdfea2646970667358221220d573892c840f6dbdab2ef0becb36d6df5110ed98640e3398592e7a2b6e39ca9764736f6c634300080a0033

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

000000000000000000000000b575a3d12d95e72249acbfce0f90abe28515d9f90000000000000000000000000000000000000000033b2e3c9fd0803ce8000000

-----Decoded View---------------
Arg [0] : qAdminAddress (address): 0xb575A3d12d95e72249acBfce0f90Abe28515D9F9
Arg [1] : supplyCap_ (uint256): 1000000000000000000000000000

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b575a3d12d95e72249acbfce0f90abe28515d9f9
Arg [1] : 0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000


Block Transaction Gas Used Reward
view all blocks collator

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
[ 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.