Quantillon Protocol

Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

QEUROToken

Git Source

Inherits: Initializable, ERC20Upgradeable, AccessControlUpgradeable, PausableUpgradeable, SecureUpgradeable

Author: Quantillon Labs - Nicolas Bellengé - @chewbaccoin

Euro-pegged stablecoin token for the Quantillon protocol

Main characteristics:

  • Standard ERC20 with 18 decimals
  • Mint/Burn controlled only by the vault
  • Emergency pause in case of issues
  • Upgradeable via UUPS pattern
  • Dynamic supply cap for governance flexibility
  • Blacklist/whitelist functionality for compliance
  • Rate limiting for mint/burn operations
  • Decimal precision handling for external price feeds

Security features:

  • Role-based access control for all critical operations
  • Emergency pause mechanism for crisis situations
  • Rate limiting to prevent abuse
  • Blacklist/whitelist for regulatory compliance
  • Upgradeable architecture for future improvements

Tokenomics:

  • Initial supply: 0 (all tokens minted through vault operations)
  • Maximum supply: Configurable by governance (default 100M QEURO)
  • Decimals: 18 (standard for ERC20 tokens)
  • Peg: 1:1 with Euro (managed by vault operations)

Note: security-contact: team@quantillon.money

State Variables

MINTER_ROLE

Role for minting tokens (assigned to QuantillonVault only)

keccak256 hash avoids role collisions with other contracts

Only the vault should have this role to maintain tokenomics

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE")

BURNER_ROLE

Role for burning tokens (assigned to QuantillonVault only)

keccak256 hash avoids role collisions with other contracts

Only the vault should have this role to maintain tokenomics

bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE")

PAUSER_ROLE

Role for pausing the contract in emergency situations

keccak256 hash avoids role collisions with other contracts

Should be assigned to governance or emergency multisig

bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE")

COMPLIANCE_ROLE

Role for managing blacklist/whitelist for compliance

keccak256 hash avoids role collisions with other contracts

Should be assigned to compliance team or governance

bytes32 public constant COMPLIANCE_ROLE = keccak256("COMPLIANCE_ROLE")

DEFAULT_MAX_SUPPLY

Default maximum supply limit (100 million QEURO)

Can be updated by governance through updateMaxSupply()

Value: 100,000,000 * 10^18 = 100,000,000 QEURO

uint256 public constant DEFAULT_MAX_SUPPLY = 100_000_000 * 1e18

MAX_RATE_LIMIT

Maximum rate limit for mint/burn operations (per reset period)

Prevents abuse and provides time for emergency response

Value: 10,000,000 * 10^18 = 10,000,000 QEURO per reset period (~300 blocks)

uint256 public constant MAX_RATE_LIMIT = 10_000_000 * 1e18

RATE_LIMIT_RESET_PERIOD

Rate limit reset period in blocks (~1 hour assuming 12 second blocks)

Using block numbers instead of timestamps for security against miner manipulation

uint256 public constant RATE_LIMIT_RESET_PERIOD = 300

PRECISION

Precision for decimal calculations (18 decimals)

Standard precision used throughout the protocol

Value: 10^18

uint256 public constant PRECISION = 1e18

MAX_BATCH_SIZE

Maximum batch size for mint operations to prevent DoS

Prevents out-of-gas attacks through large arrays

uint256 public constant MAX_BATCH_SIZE = 100

MAX_COMPLIANCE_BATCH_SIZE

Maximum batch size for compliance operations to prevent DoS

Prevents out-of-gas attacks through large blacklist/whitelist arrays

uint256 public constant MAX_COMPLIANCE_BATCH_SIZE = 50

maxSupply

Current maximum supply limit (updatable by governance)

Initialized to DEFAULT_MAX_SUPPLY, can be changed by governance

Prevents infinite minting and maintains tokenomics

uint256 public maxSupply

rateLimitCaps

RateLimitCaps public rateLimitCaps

rateLimitInfo

RateLimitInfo public rateLimitInfo

mintingKillswitch

Emergency killswitch to prevent all QEURO minting operations

When enabled (true), blocks both regular and batch minting functions

Can only be toggled by addresses with PAUSER_ROLE

Used as a crisis management tool when protocol lacks sufficient collateral

Independent of the general pause mechanism - provides granular control

bool public mintingKillswitch

isBlacklisted

Blacklist mapping for compliance and security

Blacklisted addresses cannot transfer or receive tokens

Can be managed by addresses with COMPLIANCE_ROLE

mapping(address => bool) public isBlacklisted

isWhitelisted

Whitelist mapping for compliance (if enabled)

When whitelistEnabled is true, only whitelisted addresses can transfer

Can be managed by addresses with COMPLIANCE_ROLE

mapping(address => bool) public isWhitelisted

whitelistEnabled

Whether whitelist mode is enabled

When true, only whitelisted addresses can transfer tokens

Can be toggled by addresses with COMPLIANCE_ROLE

bool public whitelistEnabled

minPricePrecision

Minimum precision for external price feeds

Used to validate price feed precision for accurate calculations

Can be updated by governance through updateMinPricePrecision()

uint256 public minPricePrecision

treasury

Treasury address for ETH recovery

SECURITY: Only this address can receive ETH from recoverETH function

address public treasury

Functions

flashLoanProtection

Modifier to protect against flash loan attacks

Uses the FlashLoanProtectionLibrary to check QEURO balance consistency

modifier flashLoanProtection() ;

constructor

Constructor for QEURO token contract

Disables initializers for security

Notes:

  • security: Disables initializers for security

  • validation: No validation needed

  • state-changes: Disables initializers

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

  • oz-upgrades-unsafe-allow: constructor

constructor() ;

initialize

Initializes the QEURO token (called only once at deployment)

This function replaces the constructor. It:

  1. Initializes the ERC20 token with name and symbol
  2. Configures the role system
  3. Assigns appropriate roles
  4. Configures pause and upgrade system
  5. Sets initial rate limits and precision settings

Security considerations:

  • Only callable once (initializer modifier)
  • Validates input parameters
  • Sets up proper role hierarchy
  • Initializes all state variables

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Initializes all contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to initializer modifier

  • oracle: No oracle dependencies

function initialize(address admin, address vault, address _timelock, address _treasury) public initializer;

Parameters

NameTypeDescription
adminaddressAddress that will have the DEFAULT_ADMIN_ROLE
vaultaddressAddress of the QuantillonVault (will get MINTER_ROLE and BURNER_ROLE)
_timelockaddressAddress of the timelock contract
_treasuryaddressTreasury address for protocol fees

mint

Mints QEURO tokens to a specified address

Implemented securities:

  • Only the vault can call this function (MINTER_ROLE)
  • The contract must not be paused
  • Respect for maximum supply cap
  • Input parameter validation
  • Rate limiting
  • Blacklist/whitelist checks Usage example: vault.mint(user, 1000 * 1e18) for 1000 QEURO

Security considerations:

  • Only MINTER_ROLE can mint
  • Pause check
  • Rate limiting
  • Blacklist/whitelist checks
  • Supply cap verification
  • Secure minting using OpenZeppelin

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to MINTER_ROLE

  • oracle: No oracle dependencies

function mint(address to, uint256 amount)
    external
    onlyRole(MINTER_ROLE) // Only the vault can mint
    whenNotPaused;

Parameters

NameTypeDescription
toaddressAddress that will receive the tokens
amountuint256Amount of tokens to mint (in wei, 18 decimals)

batchMint

Batch mint QEURO tokens to multiple addresses

Applies the same validations as single mint per item to avoid bypassing rate limits, blacklist/whitelist checks, and max supply constraints. Using external mint for each entry reuses all checks and events.

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to MINTER_ROLE

  • oracle: No oracle dependencies

function batchMint(address[] calldata recipients, uint256[] calldata amounts)
    external
    onlyRole(MINTER_ROLE)
    whenNotPaused
    flashLoanProtection;

Parameters

NameTypeDescription
recipientsaddress[]Array of recipient addresses
amountsuint256[]Array of amounts to mint (18 decimals)

burn

Burns QEURO tokens from a specified address

Implemented securities:

  • Only the vault can call this function (BURNER_ROLE)
  • The contract must not be paused
  • Sufficient balance verification
  • Parameter validation
  • Rate limiting Note: The vault must have an allowance or be authorized otherwise

Security considerations:

  • Only BURNER_ROLE can burn
  • Pause check
  • Rate limiting
  • Secure burning using OpenZeppelin

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to BURNER_ROLE

  • oracle: No oracle dependencies

  • security: No flash loan protection needed - only vault can burn

function burn(address from, uint256 amount)
    external
    onlyRole(BURNER_ROLE) // Only the vault can burn
    whenNotPaused;

Parameters

NameTypeDescription
fromaddressAddress from which to burn tokens
amountuint256Amount of tokens to burn

batchBurn

Batch burn QEURO tokens from multiple addresses

Applies the same validations as single burn per item to avoid bypassing rate limits and balance checks. Accumulates total for rate limiting.

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to BURNER_ROLE

  • oracle: No oracle dependencies

function batchBurn(address[] calldata froms, uint256[] calldata amounts)
    external
    onlyRole(BURNER_ROLE)
    whenNotPaused
    flashLoanProtection;

Parameters

NameTypeDescription
fromsaddress[]Array of addresses to burn from
amountsuint256[]Array of amounts to burn (18 decimals)

_checkAndUpdateMintRateLimit

Checks and updates the mint rate limit for the caller

Implements sliding window rate limiting using block numbers to prevent abuse

Notes:

  • security: Resets rate limit if reset period has passed (~300 blocks), prevents block manipulation

  • validation: Validates amount against current rate limit caps

  • state-changes: Updates rateLimitInfo.currentHourMinted and lastRateLimitReset

  • events: No events emitted

  • errors: Throws RateLimitExceeded if amount would exceed current rate limit

  • reentrancy: Not protected - internal function only

  • access: Internal function - no access restrictions

  • oracle: No oracle dependencies

function _checkAndUpdateMintRateLimit(uint256 amount) internal;

Parameters

NameTypeDescription
amountuint256The amount to be minted (18 decimals), used to check against rate limits

_checkAndUpdateBurnRateLimit

Checks and updates the burn rate limit for the caller

Implements sliding window rate limiting using block numbers to prevent abuse

Notes:

  • security: Resets rate limit if reset period has passed (~300 blocks), prevents block manipulation

  • validation: Validates amount against current rate limit caps

  • state-changes: Updates rateLimitInfo.currentHourBurned and lastRateLimitReset

  • events: No events emitted

  • errors: Throws RateLimitExceeded if amount would exceed current rate limit

  • reentrancy: Not protected - internal function only

  • access: Internal function - no access restrictions

  • oracle: No oracle dependencies

function _checkAndUpdateBurnRateLimit(uint256 amount) internal;

Parameters

NameTypeDescription
amountuint256The amount to be burned (18 decimals), used to check against rate limits

updateRateLimits

Updates rate limits for mint and burn operations

Only callable by admin

Security considerations:

  • Validates new limits
  • Ensures new limits are not zero
  • Ensures new limits are not too high
  • Updates rateLimitCaps (mint and burn) in a single storage slot
  • Emits RateLimitsUpdated event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to DEFAULT_ADMIN_ROLE

  • oracle: No oracle dependencies

function updateRateLimits(uint256 newMintLimit, uint256 newBurnLimit) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
newMintLimituint256New mint rate limit per reset period (~300 blocks)
newBurnLimituint256New burn rate limit per reset period (~300 blocks)

blacklistAddress

Blacklists an address

Only callable by compliance role

Security considerations:

  • Validates input parameters
  • Prevents blacklisting of zero address
  • Prevents blacklisting of already blacklisted addresses
  • Updates isBlacklisted mapping
  • Emits AddressBlacklisted event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function blacklistAddress(address account, string memory reason) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountaddressAddress to blacklist
reasonstringReason for blacklisting

unblacklistAddress

Removes an address from blacklist

Only callable by compliance role

Security considerations:

  • Validates input parameter
  • Prevents unblacklisting of non-blacklisted addresses
  • Updates isBlacklisted mapping
  • Emits AddressUnblacklisted event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function unblacklistAddress(address account) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountaddressAddress to remove from blacklist

whitelistAddress

Whitelists an address

Only callable by compliance role

Security considerations:

  • Validates input parameters
  • Prevents whitelisting of zero address
  • Prevents whitelisting of already whitelisted addresses
  • Updates isWhitelisted mapping
  • Emits AddressWhitelisted event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function whitelistAddress(address account) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountaddressAddress to whitelist

unwhitelistAddress

Removes an address from whitelist

Only callable by compliance role

Security considerations:

  • Validates input parameter
  • Prevents unwhitelisting of non-whitelisted addresses
  • Updates isWhitelisted mapping
  • Emits AddressUnwhitelisted event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function unwhitelistAddress(address account) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountaddressAddress to remove from whitelist

toggleWhitelistMode

Toggles whitelist mode

Only callable by compliance role

Security considerations:

  • Validates input parameter
  • Updates whitelistEnabled state
  • Emits WhitelistModeToggled event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function toggleWhitelistMode(bool enabled) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
enabledboolWhether to enable whitelist mode

batchBlacklistAddresses

Batch blacklist multiple addresses

Only callable by compliance role

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function batchBlacklistAddresses(address[] calldata accounts, string[] calldata reasons)
    external
    onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to blacklist
reasonsstring[]Array of reasons for blacklisting

batchUnblacklistAddresses

Batch unblacklist multiple addresses

Only callable by compliance role

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function batchUnblacklistAddresses(address[] calldata accounts) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to remove from blacklist

batchWhitelistAddresses

Batch whitelist multiple addresses

Only callable by compliance role

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function batchWhitelistAddresses(address[] calldata accounts) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to whitelist

batchUnwhitelistAddresses

Batch unwhitelist multiple addresses

Only callable by compliance role

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to COMPLIANCE_ROLE

  • oracle: No oracle dependencies

function batchUnwhitelistAddresses(address[] calldata accounts) external onlyRole(COMPLIANCE_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to remove from whitelist

updateMinPricePrecision

Updates minimum price precision for external feeds

Only callable by admin

Security considerations:

  • Validates input parameter
  • Prevents setting precision to zero
  • Prevents setting precision higher than PRECISION
  • Updates minPricePrecision
  • Emits MinPricePrecisionUpdated event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to DEFAULT_ADMIN_ROLE

  • oracle: No oracle dependencies

function updateMinPricePrecision(uint256 newPrecision) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
newPrecisionuint256New minimum precision (e.g., 1e6 for 6 decimals)

normalizePrice

Normalizes a price value to 18 decimals

Helper function for external integrations

Security considerations:

  • Validates input parameters
  • Prevents too many decimals
  • Prevents zero price
  • Handles normalization correctly

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: No state changes

  • events: No events emitted

  • errors: Throws custom errors for invalid conditions

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function normalizePrice(uint256 price, uint8 feedDecimals) external pure returns (uint256);

Parameters

NameTypeDescription
priceuint256Price value from external feed
feedDecimalsuint8Number of decimals in the price feed

Returns

NameTypeDescription
<none>uint256Normalized price with 18 decimals

validatePricePrecision

Validates price precision from external feed

Helper function for external integrations

Security considerations:

  • Validates input parameters
  • Handles normalization if feedDecimals is not 18
  • Returns true if price is above or equal to minPricePrecision

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function validatePricePrecision(uint256 price, uint8 feedDecimals) external view returns (bool);

Parameters

NameTypeDescription
priceuint256Price value from external feed
feedDecimalsuint8Number of decimals in the price feed

Returns

NameTypeDescription
<none>boolWhether the price meets minimum precision requirements

pause

Pauses all token operations (emergency only)

When paused:

  • No transfers possible
  • No mint/burn possible
  • Only read functions work Used in case of:
  • Critical bug discovered
  • Ongoing attack
  • Emergency protocol maintenance

Security considerations:

  • Only PAUSER_ROLE can pause
  • Pauses all token operations
  • Prevents any state changes

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to PAUSER_ROLE

  • oracle: No oracle dependencies

function pause() external onlyRole(PAUSER_ROLE);

unpause

Removes pause and restores normal operations

Can only be called by a PAUSER_ROLE Used after resolving the issue that caused the pause

Security considerations:

  • Only PAUSER_ROLE can unpause
  • Unpauses all token operations
  • Allows normal state changes

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to PAUSER_ROLE

  • oracle: No oracle dependencies

function unpause() external onlyRole(PAUSER_ROLE);

decimals

Returns the number of decimals for the token (always 18)

Always returns 18 for DeFi compatibility

Security considerations:

  • Always returns 18
  • No input validation
  • No state changes

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function decimals() public pure override returns (uint8);

Returns

NameTypeDescription
<none>uint8Number of decimals (18 for DeFi compatibility)

isMinter

Checks if an address has the minter role

Checks if account has MINTER_ROLE

Security considerations:

  • Checks if account has MINTER_ROLE
  • No input validation
  • No state changes

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function isMinter(address account) external view returns (bool);

Parameters

NameTypeDescription
accountaddressAddress to check

Returns

NameTypeDescription
<none>booltrue if the address can mint

isBurner

Checks if an address has the burner role

Checks if account has BURNER_ROLE

Security considerations:

  • Checks if account has BURNER_ROLE
  • No input validation
  • No state changes

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function isBurner(address account) external view returns (bool);

Parameters

NameTypeDescription
accountaddressAddress to check

Returns

NameTypeDescription
<none>booltrue if the address can burn

getSupplyUtilization

Calculates the percentage of maximum supply utilization

Useful for monitoring:

  • 0 = 0% used
  • 5000 = 50% used
  • 10000 = 100% used (maximum supply reached)

Security considerations:

  • Calculates percentage based on totalSupply and maxSupply
  • Handles division by zero
  • Returns 0 if totalSupply is 0

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function getSupplyUtilization() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Percentage in basis points (0-10000, where 10000 = 100%)

getRemainingMintCapacity

Calculates remaining space for minting new tokens

Calculates remaining capacity by subtracting currentSupply from maxSupply

Security considerations:

  • Calculates remaining capacity by subtracting currentSupply from maxSupply
  • Handles case where currentSupply >= maxSupply
  • Returns 0 if no more minting is possible

Notes:

  • security: No security checks needed

  • validation: No input validation required - view function

  • state-changes: No state changes - view function only

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: Not applicable - view function

  • access: Public - no access restrictions

  • oracle: No oracle dependencies

function getRemainingMintCapacity() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Number of tokens that can still be minted (18 decimals)

getRateLimitStatus

Gets current rate limit status

Returns current hour amounts if within the hour, zeros if an hour has passed

Security considerations:

  • Returns current hour amounts if within the hour
  • Returns zeros if an hour has passed
  • Returns current limits and next reset time
  • Includes bounds checking to prevent timestamp manipulation

Notes:

  • security: No security checks needed

  • validation: No input validation required - view function

  • state-changes: No state changes - view function only

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: Not applicable - view function

  • access: Public - no access restrictions

  • oracle: No oracle dependencies

function getRateLimitStatus()
    external
    view
    returns (
        uint256 mintedThisHour,
        uint256 burnedThisHour,
        uint256 mintLimit,
        uint256 burnLimit,
        uint256 nextResetTime
    );

Returns

NameTypeDescription
mintedThisHouruint256Amount minted in current hour (18 decimals)
burnedThisHouruint256Amount burned in current hour (18 decimals)
mintLimituint256Current mint rate limit (18 decimals)
burnLimituint256Current burn rate limit (18 decimals)
nextResetTimeuint256Block number when rate limits reset

batchTransfer

Batch transfer QEURO tokens to multiple addresses

Performs multiple transfers from msg.sender to recipients. Uses OpenZeppelin's transfer mechanism with compliance checks.

Notes:

  • security: Validates all recipients and amounts, enforces blacklist/whitelist checks

  • validation: Validates array lengths match, amounts > 0, recipients != address(0)

  • state-changes: Updates balances for all recipients and sender

  • events: Emits Transfer events for each successful transfer

  • errors: Throws ArrayLengthMismatch, BatchSizeTooLarge, InvalidAddress, InvalidAmount, BlacklistedAddress, NotWhitelisted

  • reentrancy: Protected by whenNotPaused modifier

  • access: Public - requires sufficient balance and compliance checks

  • oracle: No oracle dependencies

function batchTransfer(address[] calldata recipients, uint256[] calldata amounts)
    external
    whenNotPaused
    returns (bool);

Parameters

NameTypeDescription
recipientsaddress[]Array of recipient addresses
amountsuint256[]Array of amounts to transfer (18 decimals)

Returns

NameTypeDescription
<none>boolsuccess Always returns true if all transfers succeed

_update

Hook called before each token transfer

Adds pause verification and blacklist checks to standard OpenZeppelin transfers

Security considerations:

  • Checks if transfer is from a blacklisted address
  • Checks if transfer is to a blacklisted address
  • If whitelist is enabled, checks if recipient is whitelisted
  • Prevents transfers if any checks fail
  • Calls super._update for standard ERC20 logic

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by whenNotPaused modifier

  • access: Internal function

  • oracle: No oracle dependencies

function _update(address from, address to, uint256 amount) internal override whenNotPaused;

Parameters

NameTypeDescription
fromaddressSource address (address(0) for mint)
toaddressDestination address (address(0) for burn)
amountuint256Amount transferred

recoverToken

Recover tokens accidentally sent to the contract to treasury only

Only DEFAULT_ADMIN_ROLE can recover tokens to treasury

Security considerations:

  • Only DEFAULT_ADMIN_ROLE can recover
  • Prevents recovery of own QEURO tokens
  • Tokens are sent to treasury address only
  • Uses SafeERC20 for secure transfers

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to DEFAULT_ADMIN_ROLE

  • oracle: No oracle dependencies

function recoverToken(address token, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
tokenaddressToken address to recover
amountuint256Amount to recover

recoverETH

Recover ETH to treasury address only

SECURITY: Restricted to treasury to prevent arbitrary ETH transfers

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to DEFAULT_ADMIN_ROLE

  • oracle: No oracle dependencies

function recoverETH() external onlyRole(DEFAULT_ADMIN_ROLE);

updateMaxSupply

Updates the maximum supply limit (governance only)

Function to adjust supply cap if necessary Requires governance and must be used with caution

IMPROVEMENT: Now functional with dynamic supply cap

Security considerations:

  • Only DEFAULT_ADMIN_ROLE can update
  • Validates newMaxSupply
  • Prevents setting cap below current supply
  • Prevents setting cap to zero
  • Emits SupplyCapUpdated event

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to DEFAULT_ADMIN_ROLE

  • oracle: No oracle dependencies

function updateMaxSupply(uint256 newMaxSupply) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
newMaxSupplyuint256New supply limit

updateTreasury

Update treasury address

SECURITY: Only governance can update treasury address

Notes:

  • security: Validates input parameters and enforces security checks

  • validation: Validates input parameters and business logic constraints

  • state-changes: Updates contract state variables

  • events: Emits relevant events for state changes

  • errors: Throws custom errors for invalid conditions

  • reentrancy: Protected by reentrancy guard

  • access: Restricted to DEFAULT_ADMIN_ROLE

  • oracle: No oracle dependencies

function updateTreasury(address _treasury) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
_treasuryaddressNew treasury address

getTokenInfo

Complete token information (for monitoring)

Returns current state of the token for monitoring purposes

Security considerations:

  • Returns current state of the token
  • No input validation
  • No state changes

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function getTokenInfo()
    external
    view
    returns (
        string memory name_,
        string memory symbol_,
        uint8 decimals_,
        uint256 totalSupply_,
        uint256 maxSupply_,
        bool isPaused_,
        bool whitelistEnabled_,
        uint256 mintRateLimit_,
        uint256 burnRateLimit_
    );

Returns

NameTypeDescription
name_stringToken name
symbol_stringToken symbol
decimals_uint8Number of decimals
totalSupply_uint256Current total supply
maxSupply_uint256Maximum authorized supply
isPaused_boolPause state
whitelistEnabled_boolWhether whitelist mode is enabled
mintRateLimit_uint256Current mint rate limit
burnRateLimit_uint256Current burn rate limit

mintRateLimit

Get current mint rate limit (per hour)

Returns current mint rate limit

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function mintRateLimit() external view returns (uint256 limit);

Returns

NameTypeDescription
limituint256Mint rate limit in wei per hour (18 decimals)

setMintingKillswitch

Toggle the emergency minting killswitch to enable/disable all minting operations

Emergency function that provides granular control over minting without affecting other operations

Can only be called by addresses with PAUSER_ROLE for security

Used as a crisis management tool when protocol lacks sufficient collateral

Independent of the general pause mechanism - allows selective operation blocking

When enabled, both mint() and batchMint() functions will revert with MintingDisabled error

Burning operations remain unaffected by the killswitch

Notes:

  • security: Only callable by PAUSER_ROLE holders

  • validation: Validates caller has PAUSER_ROLE

  • events: Emits MintingKillswitchToggled event with new state and caller

  • errors: Throws AccessControlUnauthorizedAccount if caller lacks PAUSER_ROLE

  • state-changes: Updates mintingKillswitch state variable

  • access: Restricted to PAUSER_ROLE

  • reentrancy: Not protected - simple state change

  • oracle: No oracle dependencies

function setMintingKillswitch(bool enabled) external onlyRole(PAUSER_ROLE);

Parameters

NameTypeDescription
enabledboolTrue to enable killswitch (block all minting), false to disable (allow minting)

burnRateLimit

Get current burn rate limit (per hour)

Returns current burn rate limit

Notes:

  • security: No security checks needed

  • validation: No validation needed

  • state-changes: No state changes

  • events: No events emitted

  • errors: No errors thrown

  • reentrancy: No reentrancy protection needed

  • access: No access restrictions

  • oracle: No oracle dependencies

function burnRateLimit() external view returns (uint256 limit);

Returns

NameTypeDescription
limituint256Burn rate limit in wei per hour (18 decimals)

Events

TokensMinted

Emitted when tokens are minted

OPTIMIZED: Indexed amount for efficient filtering by mint size

event TokensMinted(address indexed to, uint256 indexed amount, address indexed minter);

Parameters

NameTypeDescription
toaddressRecipient of the tokens
amountuint256Amount minted in wei (18 decimals)
minteraddressAddress that performed the mint (vault)

MintingKillswitchToggled

Emitted when the minting killswitch is toggled on or off

Provides transparency for emergency actions taken by protocol administrators

event MintingKillswitchToggled(bool enabled, address indexed caller);

Parameters

NameTypeDescription
enabledboolTrue if killswitch is being enabled (minting blocked), false if disabled (minting allowed)
calleraddressAddress of the PAUSER_ROLE holder who toggled the killswitch

TokensBurned

Emitted when tokens are burned

OPTIMIZED: Indexed amount for efficient filtering by burn size

event TokensBurned(address indexed from, uint256 indexed amount, address indexed burner);

Parameters

NameTypeDescription
fromaddressAddress from which tokens are burned
amountuint256Amount burned in wei (18 decimals)
burneraddressAddress that performed the burn (vault)

SupplyCapUpdated

Emitted when the supply limit is modified

Emitted when governance updates the maximum supply

event SupplyCapUpdated(uint256 oldCap, uint256 newCap);

Parameters

NameTypeDescription
oldCapuint256Old supply limit in wei (18 decimals)
newCapuint256New supply limit in wei (18 decimals)

RateLimitsUpdated

Emitted when rate limits are updated

OPTIMIZED: Indexed parameter type for efficient filtering

event RateLimitsUpdated(string indexed limitType, uint256 mintLimit, uint256 burnLimit);

Parameters

NameTypeDescription
limitTypestring
mintLimituint256New mint rate limit in wei per hour (18 decimals)
burnLimituint256New burn rate limit in wei per hour (18 decimals)

TreasuryUpdated

Emitted when treasury address is updated

event TreasuryUpdated(address indexed treasury);

Parameters

NameTypeDescription
treasuryaddressNew treasury address

AddressBlacklisted

Emitted when an address is blacklisted

OPTIMIZED: Indexed reason for efficient filtering by blacklist type

event AddressBlacklisted(address indexed account, string indexed reason);

Parameters

NameTypeDescription
accountaddressAddress that was blacklisted
reasonstringReason for blacklisting (for compliance records)

AddressUnblacklisted

Emitted when an address is removed from blacklist

Emitted when COMPLIANCE_ROLE removes an address from blacklist

event AddressUnblacklisted(address indexed account);

Parameters

NameTypeDescription
accountaddressAddress that was removed from blacklist

AddressWhitelisted

Emitted when an address is whitelisted

Emitted when COMPLIANCE_ROLE whitelists an address

event AddressWhitelisted(address indexed account);

Parameters

NameTypeDescription
accountaddressAddress that was whitelisted

AddressUnwhitelisted

Emitted when an address is removed from whitelist

Emitted when COMPLIANCE_ROLE removes an address from whitelist

event AddressUnwhitelisted(address indexed account);

Parameters

NameTypeDescription
accountaddressAddress that was removed from whitelist

WhitelistModeToggled

Emitted when whitelist mode is toggled

Emitted when COMPLIANCE_ROLE toggles whitelist mode

event WhitelistModeToggled(bool enabled);

Parameters

NameTypeDescription
enabledboolWhether whitelist mode is enabled

MinPricePrecisionUpdated

Emitted when minimum price precision is updated

Emitted when governance updates minimum price precision

event MinPricePrecisionUpdated(uint256 oldPrecision, uint256 newPrecision);

Parameters

NameTypeDescription
oldPrecisionuint256Old minimum precision value
newPrecisionuint256New minimum precision value

RateLimitReset

Emitted when rate limit is reset

OPTIMIZED: Indexed block number for efficient block-based filtering

event RateLimitReset(uint256 indexed blockNumber);

Parameters

NameTypeDescription
blockNumberuint256Block number when reset occurred

ETHRecovered

Emitted when ETH is recovered to treasury

event ETHRecovered(address indexed to, uint256 indexed amount);

Parameters

NameTypeDescription
toaddressAddress to which ETH was recovered
amountuint256Amount of ETH recovered

Structs

RateLimitCaps

Packed rate limit caps for mint and burn (per hour)

Two uint128 packed into one slot for storage efficiency

struct RateLimitCaps {
    uint128 mint;
    uint128 burn;
}

RateLimitInfo

Rate limiting information - OPTIMIZED: Packed for storage efficiency

Resets every ~300 blocks (~1 hour assuming 12 second blocks) or when rate limits are updated

Used to enforce mintRateLimit and burnRateLimit

struct RateLimitInfo {
    uint96 currentHourMinted; // Current minted amount in the current hour (12 bytes)
    uint96 currentHourBurned; // Current burned amount in the current hour (12 bytes)
    uint64 lastRateLimitReset; // Block number of the last rate limit reset (8 bytes)
}