Quantillon Protocol API Documentation
Overview
The Quantillon Protocol is a comprehensive DeFi ecosystem built on Base, featuring a euro-pegged stablecoin (QEURO), governance token (QTI), and advanced yield management system. This document provides detailed API documentation for all public interfaces.
Table of Contents
- Core Contracts
- Vault Contracts
- Yield Management
- Oracle System
- Utilities
- Error Codes
- Events
- Integration Examples
Core Contracts
QuantillonVault
The main vault contract that manages QEURO minting and redemption against USDC.
Functions
initialize(address admin, address _qeuro, address _usdc, address _oracle, address _hedgerPool, address _userPool, address _timelock, address _feeCollector)
Initializes the vault with initial configuration.
Parameters:
admin(address): Admin address receiving roles_qeuro(address): QEURO token address_usdc(address): USDC token address_oracle(address): Oracle contract address_hedgerPool(address): HedgerPool address (can be set later)_userPool(address): UserPool address (can be set later)_timelock(address): Timelock/treasury address_feeCollector(address): FeeCollector address
Access: Public (only callable once)
mintQEURO(uint256 usdcAmount, uint256 minQeuroOut)
Mints QEURO by swapping USDC.
Parameters:
usdcAmount(uint256): Amount of USDC to swap (6 decimals)minQeuroOut(uint256): Minimum QEURO expected (18 decimals, slippage protection)
Access: Public
Requirements:
- Contract not paused
- Valid oracle price and initialized price cache (
initializePriceCache) - Active hedger (
hedgerPool.hasActiveHedger()) - Sufficient USDC balance and allowance
redeemQEURO(uint256 qeuroAmount, uint256 minUsdcOut)
Redeems QEURO for USDC.
Parameters:
qeuroAmount(uint256): Amount of QEURO to swap (18 decimals)minUsdcOut(uint256): Minimum USDC expected (6 decimals, slippage protection)
Access: Public
Requirements:
- Contract not paused
- Valid oracle price (normal mode)
- Sufficient QEURO balance and allowance
- Automatically routes to liquidation redemption when protocol CR is at or below critical threshold
calculateMintAmount(uint256 usdcAmount) → (uint256, uint256)
Calculates quoted mint output using cached price.
Parameters:
usdcAmount(uint256): Amount of USDC (6 decimals)
Returns:
uint256: Amount of QEURO that would be minted (18 decimals)uint256: Mint fee (USDC, 6 decimals)
Access: Public view
calculateRedeemAmount(uint256 qeuroAmount) → (uint256, uint256)
Calculates quoted redeem output using cached price.
Parameters:
qeuroAmount(uint256): Amount of QEURO (18 decimals)
Returns:
uint256: Amount of USDC that would be received (6 decimals)uint256: Redemption fee (USDC, 6 decimals)
Access: Public view
getVaultMetrics() → (uint256, uint256, uint256, uint256, uint256)
Retrieves comprehensive vault metrics.
Returns:
uint256:totalUsdcHeld(USDC in vault, 6 decimals)uint256:totalMinted(QEURO tracked by vault, 18 decimals)uint256:totalDebtValue(USD value from live supply and cached EUR/USD)uint256:totalUsdcInExternalVaults(tracked principal across external adapters)uint256:totalUsdcAvailable(vault + external vault balances including accrued yield)
Access: Public view
getProtocolCollateralizationRatio() → (uint256)
Returns collateralization ratio in 18-decimal percentage format (100% = 1e20).
canMint() → (bool)
Returns whether minting is currently allowed.
getProtocolCollateralizationRatioView() → (uint256) / canMintView() → (bool)
View-safe aliases that use cached price path (no state refresh side effects).
initializePriceCache()
Seeds the cached EUR/USD price after deployment (required before first mint).
updateHedgerRewardFeeSplit(uint256 newSplit)
Updates the fee share routed to HedgerPool reserve (1e18 = 100%).
mintQEUROToVault(uint256 usdcAmount, uint256 minQeuroOut, uint256 vaultId)
Mints QEURO and routes collateral to a specific external vault adapter.
mintAndStakeQEURO(uint256 usdcAmount, uint256 minQeuroOut, uint256 vaultId, uint256 minStQEUROOut) → (uint256, uint256)
One-step flow: mint QEURO and immediately stake into stQEURO{vaultName} for the selected vaultId.
harvestVaultYield(uint256 vaultId) → (uint256)
Triggers yield harvest for a specific external vault adapter.
deployUsdcToVault(uint256 vaultId, uint256 usdcAmount)
Operator function to manually deploy vault-held USDC into a selected external vault adapter.
Events
event QEUROminted(address indexed user, uint256 usdcAmount, uint256 qeuroAmount);
event QEURORedeemed(address indexed user, uint256 qeuroAmount, uint256 usdcAmount);
event LiquidationRedeemed(address indexed user, uint256 qeuroAmount, uint256 usdcPayout, uint256 collateralizationRatioBps, bool isPremium);
event ProtocolFeeRouted(string sourceType, uint256 totalFee, uint256 hedgerReserveShare, uint256 collectorShare);
event StakingVaultConfigured(uint256 indexed vaultId, address indexed adapter, bool active);
event UsdcDeployedToExternalVault(uint256 indexed vaultId, uint256 indexed usdcAmount, uint256 principalInVault);
event UsdcWithdrawnFromExternalVault(uint256 indexed vaultId, uint256 indexed usdcAmount, uint256 principalInVault);
event ExternalVaultYieldHarvested(uint256 indexed vaultId, uint256 harvestedYield);
QEUROToken
The euro-pegged stablecoin token with compliance features.
Functions
mint(address to, uint256 amount)
Mints QEURO tokens to a specified address.
Parameters:
to(address): Recipient addressamount(uint256): Amount to mint (18 decimals)
Access: Vault role only
burn(uint256 amount)
Burns QEURO tokens from the caller's balance.
Parameters:
amount(uint256): Amount to burn (18 decimals)
Access: Vault role only
whitelistAddress(address account)
Adds an address to the whitelist.
Parameters:
account(address): Address to whitelist
Access: Compliance role only
blacklistAddress(address account)
Adds an address to the blacklist.
Parameters:
account(address): Address to blacklist
Access: Compliance role only
updateMaxSupply(uint256 newMaxSupply)
Updates the maximum supply cap.
Parameters:
newMaxSupply(uint256): New maximum supply (18 decimals)
Access: Admin role only
getTokenInfo() → (uint256, uint256, uint256, bool, bool)
Retrieves comprehensive token information.
Returns:
uint256: Total supplyuint256: Maximum supplyuint256: Supply utilization percentagebool: Whitelist mode enabledbool: Contract paused
Access: Public view
Events
event TokensMinted(address indexed to, uint256 amount);
event TokensBurned(address indexed from, uint256 amount);
event AddressWhitelisted(address indexed account);
event AddressBlacklisted(address indexed account);
event MaxSupplyUpdated(uint256 oldMaxSupply, uint256 newMaxSupply);
QTIToken
The governance token with vote-escrow mechanics.
Functions
lock(uint256 amount, uint256 lockTime) → (uint256)
Locks QTI tokens for voting power.
Parameters:
amount(uint256): Amount of QTI to lock (18 decimals)lockTime(uint256): Duration to lock (seconds)
Returns:
uint256: Voting power received (18 decimals)
Access: Public
Requirements:
- Sufficient QTI balance
- Lock time between minimum and maximum duration
unlock() → (uint256)
Unlocks QTI tokens after lock period expires.
Returns:
uint256: Amount of QTI unlocked
Access: Public
Requirements:
- Lock period has expired
getVotingPower(address user) → (uint256)
Gets current voting power for an address.
Parameters:
user(address): User address
Returns:
uint256: Current voting power (18 decimals)
Access: Public view
getLockInfo(address user) → (uint256, uint256, uint256, uint256)
Gets lock information for an address.
Parameters:
user(address): User address
Returns:
uint256: Locked amountuint256: Lock timeuint256: Unlock timeuint256: Current voting power
Access: Public view
createProposal(string memory description, uint256 startTime, uint256 endTime) → (uint256)
Creates a new governance proposal.
Parameters:
description(string): Proposal descriptionstartTime(uint256): Voting start timeendTime(uint256): Voting end time
Returns:
uint256: Proposal ID
Access: Public
Requirements:
- Sufficient voting power
- Valid time parameters
vote(uint256 proposalId, bool support)
Votes on a governance proposal.
Parameters:
proposalId(uint256): Proposal IDsupport(bool): True for yes, false for no
Access: Public
Requirements:
- Voting period active
- Sufficient voting power
- Not already voted
Events
event TokensLocked(address indexed user, uint256 amount, uint256 lockTime, uint256 votingPower);
event TokensUnlocked(address indexed user, uint256 amount);
event ProposalCreated(uint256 indexed proposalId, string description, uint256 startTime, uint256 endTime);
event VoteCast(address indexed voter, uint256 indexed proposalId, bool support, uint256 votingPower);
UserPool
Manages user deposits, staking, and yield distribution.
Functions
deposit(uint256 usdcAmount)
Deposits USDC into the user pool.
Parameters:
usdcAmount(uint256): Amount of USDC to deposit (6 decimals)
Access: Public
Requirements:
- Contract not paused
- Sufficient USDC balance and allowance
withdraw(uint256 usdcAmount)
Withdraws USDC from the user pool.
Parameters:
usdcAmount(uint256): Amount of USDC to withdraw (6 decimals)
Access: Public
Requirements:
- Sufficient balance
- Contract not paused
stake(uint256 qeuroAmount)
Stakes QEURO tokens for rewards.
Parameters:
qeuroAmount(uint256): Amount of QEURO to stake (18 decimals)
Access: Public
Requirements:
- Sufficient QEURO balance and allowance
- Above minimum stake amount
unstake(uint256 qeuroAmount)
Unstakes QEURO tokens.
Parameters:
qeuroAmount(uint256): Amount of QEURO to unstake (18 decimals)
Access: Public
Requirements:
- Sufficient staked balance
- Cooldown period completed
claimStakingRewards() → (uint256)
Claims accumulated staking rewards.
Returns:
uint256: Amount of rewards claimed
Access: Public
getUserInfo(address user) → (uint256, uint256, uint256, uint256, uint256)
Gets comprehensive user information.
Parameters:
user(address): User address
Returns:
uint256: Deposited USDC amountuint256: Staked QEURO amountuint256: Last stake timeuint256: Pending rewardsuint256: Total rewards claimed
Access: Public view
getPoolMetrics() → (uint256, uint256, uint256, uint256)
Gets pool metrics.
Returns:
uint256: Total usersuint256: Total stakesuint256: Total depositsuint256: Total rewards distributed
Access: Public view
Events
event USDCDeposited(address indexed user, uint256 amount);
event USDCWithdrawn(address indexed user, uint256 amount);
event QEUROStaked(address indexed user, uint256 amount);
event QEUROUnstaked(address indexed user, uint256 amount);
event RewardsClaimed(address indexed user, uint256 amount);
HedgerPool
Manages the protocol’s single-hedger leveraged position and hedger reward settlement.
Functions
enterHedgePosition(uint256 usdcAmount, uint256 leverage) → (uint256)
Opens a new hedge position.
Parameters:
usdcAmount(uint256): USDC margin amount (6 decimals)leverage(uint256): Leverage multiplier (1-10x)
Returns:
uint256: Position ID
Access: Public
Requirements:
- Caller must be the configured
singleHedger - Valid leverage amount
- Sufficient USDC balance and allowance
- Fresh oracle price
exitHedgePosition(uint256 positionId) → (int256)
Closes the active hedge position.
Parameters:
positionId(uint256): Position ID to close
Returns:
int256: Profit or loss (positive = profit, negative = loss)
Access: Public
Requirements:
- Position exists and is active
- Caller owns the position
addMargin(uint256 positionId, uint256 usdcAmount)
Adds margin to an existing position.
Parameters:
positionId(uint256): Position IDusdcAmount(uint256): Additional USDC margin (6 decimals)
Access: Public
Requirements:
- Position exists and is active
- Caller owns the position
removeMargin(uint256 positionId, uint256 usdcAmount)
Removes margin from a position.
Parameters:
positionId(uint256): Position IDusdcAmount(uint256): USDC amount to remove (6 decimals)
Access: Public
Requirements:
- Position exists and is active
- Caller owns the position
- Maintains minimum margin ratio
claimHedgingRewards() → (uint256, uint256, uint256)
Claims hedger rewards.
Returns:
uint256: Interest differential paid/escrowed by HedgerPool reserveuint256: YieldShift rewards claimed via YieldShiftuint256: Total rewards for reporting (interest + yieldShift)
Access: Restricted to configured singleHedger
withdrawPendingRewards(address recipient)
Withdraws reward amounts escrowed after failed push-transfer in claimHedgingRewards.
hasActiveHedger() → (bool)
Returns whether a configured single hedger currently has an active position.
setSingleHedger(address hedger)
Bootstrap/rotation entrypoint for single hedger configuration (governance-only).
If no hedger is configured yet, assignment is immediate. Otherwise it creates a delayed pending rotation.
applySingleHedgerRotation()
Applies a previously proposed single-hedger rotation after delay (governance-only).
fundRewardReserve(uint256 amount)
Permissionless reserve top-up path for hedger rewards.
configureRiskAndFees((...))
Batch governance update for:
- margin ratio / leverage limits
- hold blocks / minimum margin
- EUR/USD interest rates
- entry / exit / margin fees
rewardFeeSplit(1e18 = 100%)
configureDependencies((...))
Batch governance update for:
treasuryvaultoracleyieldShiftfeeCollector
Events
event HedgePositionOpened(address indexed hedger, uint256 indexed positionId, bytes32 positionData);
event HedgePositionClosed(address indexed hedger, uint256 indexed positionId, bytes32 packedData);
event MarginUpdated(address indexed hedger, uint256 indexed positionId, bytes32 packedData);
event HedgingRewardsClaimed(address indexed hedger, bytes32 packedData);
event HedgerFillUpdated(uint256 indexed positionId, uint256 previousFilled, uint256 newFilled);
event RewardReserveFunded(address indexed funder, uint256 amount);
event SingleHedgerRotationProposed(address indexed currentHedger, address indexed pendingHedger, uint256 activatesAt);
event SingleHedgerRotationApplied(address indexed previousHedger, address indexed newHedger);
stQEUROFactory
Factory contract for vault-scoped staking tokens.
Functions
registerVault(uint256 vaultId, string vaultName) -> (address)
Registers the calling vault and deploys a dedicated stQEURO token proxy.
Parameters:
vaultId(uint256): Non-zero vault idvaultName(string): Uppercase alphanumeric vault suffix (length1..12)
Returns:
address: Newly deployed stQEURO token for the vault
Access: VAULT_FACTORY_ROLE only, strict self-registration semantics (msg.sender is the vault)
getStQEUROByVaultId(uint256 vaultId) -> (address)
Resolves stQEURO token address for a given vault id.
getStQEUROByVault(address vault) -> (address)
Resolves stQEURO token address for a given vault address.
getVaultById(uint256 vaultId) -> (address)
Returns vault address for a registered vault id.
getVaultIdByStQEURO(address stQEUROToken) -> (uint256)
Returns vault id mapped to an stQEURO token address.
getVaultName(uint256 vaultId) -> (string)
Returns vault name suffix stored at registration.
updateYieldShift(address newYieldShift)
Governance setter for YieldShift dependency used for newly deployed stQEURO tokens.
updateTokenImplementation(address newImplementation)
Governance setter for stQEURO token implementation address used by future proxies.
updateTreasury(address newTreasury) / updateTokenAdmin(address newAdmin) / updateOracle(address newOracle)
Governance setters for factory-level defaults used during vault token deployment.
Events
event VaultRegistered(uint256 indexed vaultId, address indexed vault, address indexed stQEUROToken, string vaultName);
event FactoryConfigUpdated(string indexed key, address oldValue, address newValue);
stQEUROToken
Staked QEURO token with yield distribution.
Functions
stake(uint256 qeuroAmount)
Stakes QEURO tokens to receive stQEURO.
Parameters:
qeuroAmount(uint256): Amount of QEURO to stake (18 decimals)
Access: Public
Requirements:
- Sufficient QEURO balance and allowance
unstake(uint256 stQeuroAmount)
Unstakes stQEURO tokens to receive QEURO.
Parameters:
stQeuroAmount(uint256): Amount of stQEURO to unstake (18 decimals)
Access: Public
Requirements:
- Sufficient stQEURO balance
claimYield() → (uint256)
Claims accumulated yield.
Returns:
uint256: Amount of yield claimed
Access: Public
getExchangeRate() → (uint256)
Gets current exchange rate between stQEURO and QEURO.
Returns:
uint256: Exchange rate (18 decimals)
Access: Public view
getQEUROEquivalent(uint256 stQeuroAmount) → (uint256)
Calculates QEURO equivalent for stQEURO amount.
Parameters:
stQeuroAmount(uint256): Amount of stQEURO (18 decimals)
Returns:
uint256: Equivalent QEURO amount (18 decimals)
Access: Public view
distributeYield(uint256 qeuroAmount)
Distributes yield to stakers.
Parameters:
qeuroAmount(uint256): Amount of QEURO to distribute (18 decimals)
Access: Yield manager role only
initialize(...) (dynamic metadata overload)
Supports per-vault metadata (tokenName, tokenSymbol, vaultName) when deployed through stQEUROFactory.
Events
event QEUROStaked(address indexed user, uint256 qeuroAmount, uint256 stQeuroAmount);
event QEUROUnstaked(address indexed user, uint256 stQeuroAmount, uint256 qeuroAmount);
event YieldClaimed(address indexed user, uint256 amount);
event YieldDistributed(uint256 totalAmount, uint256 timestamp);
Fee Management
FeeCollector
Centralized protocol fee collection and distribution.
Functions
collectFee(address token, uint256 amount)
Records a collected fee from a protocol contract.
Parameters:
token(address): Token address (e.g. USDC)amount(uint256): Fee amount collected
Access: Authorized protocol contracts only
distributeFees(address token)
Distributes collected fees to treasury, dev fund, and community fund according to configured ratios.
Parameters:
token(address): Token to distribute
Access: GOVERNANCE_ROLE
updateFeeRatios(uint256 treasury, uint256 dev, uint256 community)
Updates fee distribution ratios.
Parameters:
treasury(uint256): Treasury ratio (basis points, default 6000 = 60%)dev(uint256): Dev fund ratio (basis points, default 2500 = 25%)community(uint256): Community fund ratio (basis points, default 1500 = 15%)
Access: GOVERNANCE_ROLE
Requirements:
treasury + dev + community == 10000
withdrawFees(address token)
Withdraws collected fees to the caller's role-permitted address.
Access: TREASURY_ROLE
Events
event FeeCollected(address indexed token, uint256 amount);
event FeesDistributed(address indexed token, uint256 treasury, uint256 dev, uint256 community);
event FeeRatiosUpdated(uint256 treasury, uint256 dev, uint256 community);
Vault Contracts
AaveVault
Manages yield generation through Aave v3 protocol integration.
Functions
deployToAave(uint256 usdcAmount)
Deploys USDC to Aave for yield generation.
Parameters:
usdcAmount(uint256): Amount of USDC to deploy (6 decimals)
Access: Yield manager role only
Requirements:
- Sufficient USDC balance
- Within exposure limits
withdrawFromAave(uint256 usdcAmount)
Withdraws USDC from Aave.
Parameters:
usdcAmount(uint256): Amount of USDC to withdraw (6 decimals)
Access: Yield manager role only
harvestAaveYield() → (uint256)
Harvests accumulated yield from Aave.
Returns:
uint256: Amount of yield harvested
Access: Yield manager role only
Notes:
- Reverts if
yieldVaultIdis not configured (yieldVaultId == 0) - Routes harvested yield to
YieldShift.addYield(yieldVaultId, ...)
setYieldVaultId(uint256 newYieldVaultId)
Sets the destination vault id used when routing harvested Aave yield to YieldShift.
Access: Governance role only
updateYieldShift(address newYieldShift)
Updates the YieldShift dependency used by AaveVault for yield routing.
Access: Governance role only
getAaveBalance() → (uint256)
Gets current USDC balance in Aave.
Returns:
uint256: USDC balance in Aave (6 decimals)
Access: Public view
getAaveAPY() → (uint256)
Gets current Aave APY.
Returns:
uint256: APY in basis points
Access: Public view
autoRebalance() → (bool, uint256, uint256)
Automatically rebalances Aave position.
Returns:
bool: Whether rebalancing occurreduint256: New allocation percentageuint256: Expected yield
Access: Public
Events
event USDCDepositedToAave(uint256 amount);
event USDCWithdrawnFromAave(uint256 amount);
event AaveYieldHarvested(uint256 amount);
event AavePositionRebalanced(uint256 newAllocation, uint256 expectedYield);
Yield Management
YieldShift
Manages yield distribution between user and hedger pools.
Functions
addYield(uint256 vaultId, uint256 yieldAmount, bytes32 source)
Adds yield to the distribution system.
Parameters:
vaultId(uint256): Registered staking vault id receiving user-allocation yieldyieldAmount(uint256): Amount of USDC yield to add (6 decimals)source(bytes32): Source key ("aave","fees","interest_differential", etc.)
Access: Authorized yield sources only
updateYieldDistribution()
Refreshes and applies current distribution between user and hedger pools.
Access: Public (whenNotPaused)
claimUserYield(address user) → (uint256)
Claims yield for user pool.
Returns:
uint256: Amount of yield claimed
Access: YIELD_MANAGER_ROLE
claimHedgerYield(address hedger) → (uint256)
Claims yield for hedger pool.
Returns:
uint256: Amount of yield claimed
Access: YIELD_MANAGER_ROLE
configureYieldModel((...))
Batch governance update for:
baseYieldShiftmaxYieldShiftadjustmentSpeedtargetPoolRatio
configureDependencies((...))
Batch governance update for:
userPoolhedgerPoolaaveVaultstQEUROFactorytreasury
setYieldSourceAuthorization(address source, bytes32 yieldType, bool authorized)
Adds/removes an authorized yield source with explicit yield type mapping.
currentYieldShift() → (uint256)
Direct state getter for current shift (1e4 precision).
userPendingYield(address user) → (uint256) / hedgerPendingYield(address hedger) → (uint256)
Direct state getters for pending yield balances.
paused() → (bool)
Pausable state getter. Yield distribution is active when paused() == false.
getPoolMetrics() → (uint256, uint256, uint256, uint256)
Gets pool metrics for yield calculation.
Returns:
uint256: User pool sizeuint256: Hedger pool sizeuint256: Pool ratiouint256: Target ratio
Access: Public view
calculateOptimalYieldShift() → (uint256, uint256)
Calculates optimal yield distribution.
Returns:
uint256: Optimal shiftuint256: Current deviation from optimal
Access: Public view
Events
event YieldDistributionUpdated(uint256 userPoolYield, uint256 hedgerPoolYield, uint256 currentShift);
event YieldAdded(uint256 yieldAmount, string indexed source, uint256 indexed timestamp);
event UserYieldClaimed(address indexed user, uint256 yieldAmount, uint256 timestamp);
event HedgerYieldClaimed(address indexed hedger, uint256 yieldAmount, uint256 timestamp);
Oracle System
The oracle system consists of three contracts. All protocol contracts interact only with OracleRouter via the IOracle interface — the underlying oracle source can be switched by governance without any changes to the protocol.
OracleRouter
Routes price requests to the currently active oracle (ChainlinkOracle or StorkOracle).
Functions
getLatestPrice() → (uint256, bool)
Gets the current EUR/USD price from the active oracle.
Returns:
uint256: EUR/USD price (18 decimals)bool: Whether price is valid and fresh
Access: Public view
switchOracle(uint8 newOracleType)
Switches the active oracle between Chainlink (0) and Stork (1).
Parameters:
newOracleType(uint8):0= Chainlink,1= Stork
Access: ORACLE_MANAGER_ROLE
setOracleAddresses(address chainlink, address stork)
Updates the underlying oracle contract addresses.
Parameters:
chainlink(address): ChainlinkOracle proxy addressstork(address): StorkOracle proxy address
Access: ORACLE_MANAGER_ROLE
Events
event OracleSwitched(uint8 oldOracle, uint8 newOracle, address caller);
event OracleAddressesUpdated(address newChainlink, address newStork);
ChainlinkOracle
EUR/USD and USDC/USD price feeds via Chainlink AggregatorV3.
Validation rules:
- Max staleness: 3600 seconds (1 hour)
- Max deviation: 500 basis points (5%)
- Timestamp drift detection: 900 seconds (15 minutes)
Functions
getLatestPrice() → (uint256, bool)
Gets current EUR/USD price from Chainlink.
Returns:
uint256: EUR/USD price (18 decimals)bool: Whether price is valid and fresh
Access: Public view
updatePriceFeeds(address eurUsdFeed, address usdcUsdFeed)
Updates Chainlink price feed addresses.
Parameters:
eurUsdFeed(address): EUR/USD Chainlink aggregator addressusdcUsdFeed(address): USDC/USD Chainlink aggregator address
Access: ORACLE_MANAGER_ROLE
Events
event PriceFeedsUpdated(address eurUsdFeed, address usdcUsdFeed);
event CircuitBreakerTriggered(uint256 timestamp);
event CircuitBreakerReset(uint256 timestamp);
StorkOracle
EUR/USD and USDC/USD price feeds via Stork Network. Same IOracle interface as ChainlinkOracle.
Validation rules: identical to ChainlinkOracle (staleness, deviation, timestamp drift).
Functions
getLatestPrice() → (uint256, bool)
Gets current EUR/USD price from Stork Network.
Returns:
uint256: EUR/USD price (18 decimals)bool: Whether price is valid and fresh
Access: Public view
updateFeedIds(bytes32 eurUsdId, bytes32 usdcUsdId)
Updates Stork feed IDs.
Parameters:
eurUsdId(bytes32): EUR/USD Stork feed ID (default:keccak256("EURUSD"))usdcUsdId(bytes32): USDC/USD Stork feed ID (default:keccak256("USDCUSD"))
Access: ORACLE_MANAGER_ROLE
Events
event FeedIdsUpdated(bytes32 eurUsdId, bytes32 usdcUsdId);
Utilities
TimeProvider
Provides time utilities with offset capabilities.
Functions
currentTime() → (uint256)
Gets current time with offset.
Returns:
uint256: Current timestamp
Access: Public view
setTimeOffset(int256 offset)
Sets time offset.
Parameters:
offset(int256): Time offset in seconds
Access: Time manager role only
advanceTime(uint256 amount)
Advances time by specified amount.
Parameters:
amount(uint256): Time to advance in seconds
Access: Time manager role only
isFuture(uint256 timestamp) → (bool)
Checks if timestamp is in the future.
Parameters:
timestamp(uint256): Timestamp to check
Returns:
bool: True if timestamp is in the future
Access: Public view
Events
event TimeOffsetSet(int256 oldOffset, int256 newOffset);
event TimeAdvanced(uint256 amount);
Error Codes
The protocol uses custom errors for gas efficiency. Common error codes include:
// Access Control
error UnauthorizedAccess();
error InsufficientRole();
// Validation
error InvalidAmount();
error InvalidAddress();
error InvalidParameter();
error InvalidTime();
// Business Logic
error InsufficientBalance();
error InsufficientAllowance();
error ExceedsLimit();
error BelowMinimum();
// Oracle
error StalePrice();
error InvalidPrice();
error CircuitBreakerActive();
// Emergency
error ContractPaused();
error EmergencyMode();
// Liquidation
error PositionHealthy();
error InsufficientMargin();
Events
All contracts emit comprehensive events for state changes. Key event categories:
Core Events
- Token transfers and approvals
- Deposits and withdrawals
- Staking and unstaking
- Yield distribution
Governance Events
- Proposal creation and execution
- Voting and delegation
- Parameter updates
Risk Management Events
- Position opening and closing
- Liquidations
- Circuit breaker activations
Emergency Events
- Pause and unpause
- Emergency withdrawals
- Recovery operations
Integration Examples
Basic QEURO Minting
// 1. Approve USDC spending
usdc.approve(vaultAddress, usdcAmount);
// 2. Mint QEURO with slippage protection
uint256 minQeuroOut = (usdcAmount * 95) / 100; // 5% slippage tolerance
vault.mintQEURO(usdcAmount, minQeuroOut);
Staking QEURO for Rewards
// 1. Approve QEURO spending
qeuro.approve(userPoolAddress, qeuroAmount);
// 2. Stake QEURO
userPool.stake(qeuroAmount);
// 3. Claim rewards later
uint256 rewards = userPool.claimStakingRewards();
Opening a Hedge Position
// 1. Approve USDC spending
usdc.approve(hedgerPoolAddress, marginAmount);
// 2. Open position with 5x leverage
uint256 positionId = hedgerPool.enterHedgePosition(marginAmount, 5);
// 3. Monitor hedger activity / claim rewards
bool hedgerActive = hedgerPool.hasActiveHedger();
(uint256 interestDiff, uint256 ysRewards, uint256 total) = hedgerPool.claimHedgingRewards();
Governance Participation
// 1. Lock QTI for voting power
qti.lock(lockAmount, lockDuration);
// 2. Create proposal
uint256 proposalId = qti.createProposal(
"Update protocol parameters",
block.timestamp + 1 days,
block.timestamp + 7 days
);
// 3. Vote on proposal
qti.vote(proposalId, true); // Vote yes
Security Considerations
- Always validate return values from view functions
- Check contract state before making transactions
- Use slippage protection for all swaps
- Monitor oracle prices for freshness
- Implement proper error handling for all interactions
- Use events for transaction monitoring
- Follow access control patterns for role-based operations
Support
For technical support and questions:
- Email: team@quantillon.money
- Documentation: Quantillon Protocol Docs
- GitHub: Quantillon Labs
This documentation is maintained by Quantillon Labs and updated regularly. Last updated: March 2026