Interfaces
fact Copied from contracts/src/interfaces/ (Solidity 0.8.28). Comments abridged.
INoteCore
Section titled “INoteCore”interface INoteCore { enum Status { None, Subscription, Live, Autocalled, Matured, Cancelled, Unwound }
struct SeriesParams { address underlying; // Stock Token address feed; // AggregatorV3 for the underlying uint16 autocallBps; // e.g. 10_000 uint16 barrierBps; // e.g. 6_500 uint16 couponFloorBps; uint16 couponCapBps; // <= maxCouponCapBps (400) uint16 refBps; // reference coupon for discovery uint40[] observations; // [strike, obs1, ..., maturity], official closes uint128 notionalCap; // quote units uint128 minTicket; // quote units uint40 subscriptionEnd; // <= observations[0] }
function createSeries(SeriesParams calldata p) external returns (uint256 seriesId); function depositCoupon(uint256 seriesId, uint256 quoteAmount) external; function depositShield(uint256 seriesId, uint256 stockAmount, uint256 prefundQuote) external; function finalizeStrike(uint256 seriesId) external; // permissionless after observations[0] function observe(uint256 seriesId) external; // permissionless, next pending observation function claim(uint256 seriesId) external returns (uint256 quoteOut); function redeem(uint256 seriesId, uint256 units) external returns (uint256 quoteOut, uint256 stockOut); function refund(uint256 seriesId) external returns (uint256 quoteOut, uint256 stockOut); function sweepFees(uint256 seriesId) external; function onLegTransfer(uint256 seriesId, uint8 leg, address from, address to, uint256 amount) external; // only NoteLegs function seriesStatus(uint256 seriesId) external view returns (Status); function seriesCount() external view returns (uint256);}NoteCore recovery and module surface
Section titled “NoteCore recovery and module surface”fact Added by the Upgradeability and recovery addendum (contracts/src/core/NoteCore.sol). Owner is the 48-hour Timelock. createSeries reverts CoreDeprecated() when SeriesRegistry.isActive(address(this)) is false.
// Module swaps with MODULE_GRACE = 24 h; one pending change per slot (ModuleChangePending)function setOracle(address oracle_) external; // onlyOwner, KEY_ORACLEfunction setCalendar(address calendar_) external; // onlyOwner, KEY_CALENDARfunction setFeeSink(address feeSink_) external; // onlyOwner, KEY_FEE_SINKfunction setKeeperReward(uint256 keeperRewardQuote_) external; // onlyOwner, KEY_KEEPER_REWARD (ParamUpdated)
// Recovery Unwind (Subscription | Live only)function proposeUnwind(uint256 seriesId) external; // onlyOwner, whenPausedfunction cancelUnwind(uint256 seriesId) external; // onlyOwnerOrGuardianfunction unwind(uint256 seriesId) external; // onlyOwner, whenPaused; status -> Unwoundfunction withdrawUnwound(uint256 seriesId) external returns (uint256 quoteOut, uint256 stockOut); // holders, never pausablefunction sweepExcess(address token, address to) external; // onlyOwner; reverts NoExcess(token), UnwindPending(count)function recordedLiabilities(address token) external view returns (uint256); // quote: totalQuoteEscrow; underlying: totalStockEscrowISeriesRegistry
Section titled “ISeriesRegistry”fact contracts/src/core/SeriesRegistry.sol, immutable, Ownable (owner = Timelock).
interface ISeriesRegistry { function register(address core) external returns (uint256 version); // onlyOwner function deprecate(uint256 version) external; // onlyOwner, irreversible function coreOf(uint256 version) external view returns (address); // UnknownVersion function versionOf(address core) external view returns (uint256); // 0 = not registered function isDeprecated(uint256 version) external view returns (bool); function isActive(address core) external view returns (bool); function latestVersion() external view returns (uint256); function activeVersion() external view returns (uint256); // 0 if none function activeCore() external view returns (address);}INoteCoreViews
Section titled “INoteCoreViews”interface INoteCoreViews { struct SeriesView { address underlying; address feed; uint16 autocallBps; uint16 barrierBps; uint16 couponFloorBps; uint16 couponCapBps; uint16 refBps; uint16 couponFeeBps; // snapshotted at creation uint16 notionalFeeBps; // snapshotted at creation uint40 subscriptionEnd; uint128 notionalCap; uint128 minTicket; uint40[] observations; INoteCore.Status status; uint16 couponBps; // discovered at strike uint32 nextObs; // next observation index bool breached; // physical settlement uint256 s0; // 1e8 uint256 lastPrice; // 1e8 uint256 totalCouponDeposits; // D uint256 totalShieldStock; // 18 dec uint256 totalShieldPrefund; // quote uint256 matchedNotional; // N uint256 couponIndex; // WAD uint256 quoteEscrow; uint256 stockEscrow; }
function legs() external view returns (address); function quote() external view returns (address); function getSeries(uint256 seriesId) external view returns (SeriesView memory); function legId(uint256 seriesId, uint8 leg) external pure returns (uint256); function barrierHolding(uint256 seriesId) external view returns (bool); function accruedCoupon(uint256 seriesId, address account) external view returns (uint256); function settle(uint256 seriesId, address account) external; // permissionless lazy match function redeemShield(uint256 seriesId, uint256 units) external returns (uint256 quoteOut, uint256 stockOut); function previewRedeem(uint256 seriesId, uint8 leg, uint256 units) external view returns (uint256 quoteOut, uint256 stockOut); function requiredPrefund(uint256 seriesId, uint256 stockAmount) external view returns (uint256);}NoteCore also exposes public state: couponFeeBps, notionalFeeBps, maxCouponCapBps, maxObservations, keeperRewardQuote, feeSink, oracle, calendar, immutables quoteToken, quoteDecimals, legsToken, STOCK_SCALE, and constants LEG_COUPON = 0, LEG_SHIELD = 1, MAX_FEE_BPS = 5000, MAX_NOTIONAL_FEE_BPS = 500, STOCK_DECIMALS = 18. Three further views are implemented on the contract rather than the interface:
struct Accounting { uint256 couponSideQuote; uint256 prefundRemaining; uint256 prefundRefundable; uint256 couponPool; uint256 accruedFees; uint256 stockMatched; uint256 stockRefundable; uint256 stockUnmatched; uint256 prefundUnmatched; uint256 shieldUnusedPerUnit; }struct Position { uint256 couponDeposit; uint256 shieldStock; uint256 shieldPrefund; uint256 refundCouponQuote; uint256 refundPrefundQuote; uint256 refundStock; uint256 claimable; uint256 couponIndexPaid; bool settled; }function getAccounting(uint256 seriesId) external view returns (Accounting memory);function getPosition(uint256 seriesId, address account) external view returns (Position memory);function previewSettle(uint256 seriesId, address account) external view returns (uint256 couponUnits, uint256 shieldUnits, uint256 refundQuote, uint256 refundStock);Governance setters on NoteCore (all onlyOwner): setFeeSink(address), setOracle(address), setCalendar(address), setFees(uint16 couponFeeBps, uint16 notionalFeeBps), setKeeperReward(uint256), setLimits(uint16 maxCouponCapBps, uint16 maxObservations). createSeries is restricted to the owner or the configured seriesCreator (RollPolicy; setSeriesCreator(address), SeriesCreatorSet, error NotSeriesCreator). Two automation views live on NoteCore: dueWork(uint256 seriesId) -> (bool strikeDue, bool observationDue, bool settleable) and the constant MAX_LAZY_OBSERVATIONS = 4 (see Automation and cranks).
NoteLegs (ERC-1155)
Section titled “NoteLegs (ERC-1155)”function mint(address to, uint256 id, uint256 amount) external; // onlyCorefunction burn(address from, uint256 id, uint256 amount) external; // onlyCorefunction seriesOf(uint256 id) external pure returns (uint256); // id >> 1function legOf(uint256 id) external pure returns (uint8); // id & 1// plus standard ERC-1155: balanceOf, balanceOfBatch, safeTransferFrom, safeBatchTransferFrom, setApprovalForAll, uriIOracleAdapter
Section titled “IOracleAdapter”interface IOracleAdapter { function observe(address feed, uint40 closeTs) external returns (uint256 price, bool ok); function peek(address feed, uint40 closeTs) external view returns (uint256 price, bool ok); function latestPrice(address feed) external view returns (uint256 price); function isCancelled(address feed, uint40 closeTs) external view returns (bool); function deferredSince(address feed, uint40 closeTs) external view returns (uint40);}IMarketCalendar
Section titled “IMarketCalendar”interface IMarketCalendar { function isOfficialClose(uint40 ts) external view returns (bool); function officialCloseOf(uint32 dayIndex) external view returns (uint40); // 0 if not a trading day function isDST(uint32 dayIndex) external pure returns (bool); function isHoliday(uint32 dayIndex) external view returns (bool); function earlyClose(uint32 dayIndex) external view returns (uint40); // 0 if none}dayIndex = timestamp / 86400.
IFeeSink and IRewardSink
Section titled “IFeeSink and IRewardSink”interface IFeeSink { function notifyFee(address token, uint256 amount) external; } // push: transfer first, then notifyinterface IRewardSink { function notifyReward(uint256 amount) external; } // push: transfer first, then notifyIStockToken
Section titled “IStockToken”interface IStockToken is IERC20Metadata { function uiMultiplier() external view returns (uint256); function balanceOfUI(address account) external view returns (uint256);}The protocol reads only raw balanceOf and transfer paths; uiMultiplier is exposed for tests and front-ends.
Token engine
Section titled “Token engine”fact External signatures copied from contracts/src/token/. Governance-only functions are marked onlyOwner; Governed adds setGuardian, pause (owner or guardian) and unpause (owner) to every module.
// NOTE (ERC-20 + Permit + Votes; CAP = 100_000_000e18; EPOCH = 7 days)function setMinter(address account, bool allowed) external; // onlyOwnerfunction setMintCapPerEpoch(uint256 newCap) external; // onlyOwnerfunction mint(address to, uint256 amount) external; // minters only, whenNotPausedfunction burn(uint256 amount) external;function burnFrom(address account, uint256 amount) external;function currentEpoch() external view returns (uint256);function epochMintRemaining() external view returns (uint256);
// sNOTE (ERC-4626 over NOTE; STREAM_DURATION = 7 days; MAX_COOLDOWN = 30 days)function setRewardNotifier(address notifier) external; // onlyOwnerfunction setCooldown(uint256 newCooldown) external; // onlyOwnerfunction notifyReward(uint256 amount) external; // rewardNotifier onlyfunction unvestedRewards() external view returns (uint256);function totalAssets() external view returns (uint256); // balance − unvestedRewards()function requestWithdraw(uint256 shares) external; // escrows shares, unlockAt = now + cooldownfunction cancelWithdrawRequest() external;function withdraw(uint256 assets, address receiver, address owner) external returns (uint256); // owner == msg.sender, matured requestfunction redeem(uint256 shares, address receiver, address owner) external returns (uint256); // owner == msg.sender, matured request
// Treasury (REDEMPTION_WINDOW = 1 day; MAX_HAIRCUT_BPS = 5_000)function addStockAsset(address token, AggregatorV3Interface feed) external; // onlyOwnerfunction setAssetEnabled(address token, bool enabled) external; // onlyOwnerfunction registerLegSeries(uint256 seriesId) external; // owner or BondDepositoryfunction setDesk(address desk_) external; // onlyOwnerfunction setBondDepository(address depository) external; // onlyOwnerfunction setMaxFeedStaleness(uint256 staleness) external; // onlyOwnerfunction setRedemptionParams(uint16 haircutBps, uint16 dailyCapBps) external; // onlyOwnerfunction mintNote(address to, uint256 amount) external; // onlyOwnerfunction withdrawERC20(address token, address to, uint256 amount) external; // onlyOwnerfunction withdrawLegs(uint256 seriesId, address to, uint256 units) external; // onlyOwnerfunction valueOf(address token, uint256 amount) external view returns (uint256);function legValueFactorWad(uint256 seriesId) external view returns (uint256);function legValueQuote(uint256 seriesId, uint256 units) external view returns (uint256);function reserveValueQuote() external view returns (uint256);function circulatingSupply() external view returns (uint256);function previewRedeem(uint256 noteAmount) external view returns (uint256);function dailyRedemptionRemaining() external view returns (uint256);function redeem(uint256 noteAmount, uint256 minQuoteOut) external returns (uint256 quoteOut);function harvestSeries(uint256 seriesId) external; // permissionlessfunction purchaseStock(address token, uint256 amount) external returns (uint256 quotePaid); // Desk only
// BondDepository (MAX_DISCOUNT_CAP_BPS = 5_000)enum QuoteKind { ERC20, CouponLeg }struct MarketParams { QuoteKind kind; address quoteToken; uint256 legSeriesId; uint256 capacity; uint256 controlVariable; uint256 minPriceWad; uint256 maxDebt; uint48 vestingSeconds; uint48 conclusion; }struct Bond { uint256 marketId; uint256 payout; uint256 claimed; uint48 vestStart; uint48 vestEnd; }function createMarket(MarketParams calldata p) external returns (uint256 id); // onlyOwnerfunction closeMarket(uint256 id) external; // onlyOwnerfunction setControlVariable(uint256 id, uint256 controlVariable) external; // onlyOwnerfunction setDiscountParams(uint16 k, uint16 maxDiscountBps_) external; // onlyOwnerfunction setDesk(IDeskUtilisation desk_) external; // onlyOwnerfunction marketCount() external view returns (uint256);function market(uint256 id) external view returns (Market memory);function bond(address user, uint256 index) external view returns (Bond memory);function bondCount(address user) external view returns (uint256);function currentDebt(uint256 id) external view returns (uint256); // linear decay since lastDecayfunction debtRatio(uint256 id) external view returns (uint256); // WAD, debt / NOTE.totalSupplyfunction basePrice(uint256 id) external view returns (uint256); // max(cv × debtRatio, minPriceWad)function utilisationDiscountBps() external view returns (uint256); // min(desk utilisation × k / 1e4, maxDiscountBps)function marketPrice(uint256 id) external view returns (uint256); // max(basePrice × (1e4 − disc) / 1e4, minPriceWad)function quoteValueWad(uint256 id, uint256 amount) external view returns (uint256);function payoutFor(uint256 id, uint256 amount) external view returns (uint256);function pendingPayout(address user, uint256 index) external view returns (uint256);function deposit(uint256 id, uint256 amount, uint256 maxPriceWad, address recipient) external returns (uint256 payout, uint256 bondIndex);function redeem(uint256[] calldata indexes) external returns (uint256 total);
// RevenueRouter (IFeeSink; MIN_HALF_LIFE = 5 minutes; MAX_HALF_LIFE = 30 days; MAX_BUMP_BPS = 10_000)function setSplit(uint16 buybackBps_) external; // onlyOwnerfunction setAuctionParams(uint256 halfLifeSeconds_, uint16 bumpBps_, uint16 maxFillBps_) external; // onlyOwnerfunction resetAuction(uint256 newStartPriceWad) external; // onlyOwnerfunction sweep(address token, address to, uint256 amount) external; // onlyOwner, not the quote tokenfunction notifyFee(address token, uint256 amount) external; // quote token onlyfunction sync() external; // route any un-notified quote balancefunction floorPriceWad() external view returns (uint256);function currentPriceWad() external view returns (uint256);function previewSell(uint256 noteAmount) external view returns (uint256);function maxFillQuote() external view returns (uint256); // buybackReserve × maxFillBps / 1e4function sellNoteForQuote(uint256 noteAmount, uint256 minQuoteOut) external returns (uint256 quoteOut);
// Desk (ERC-4626 over USDG, ERC1155Holder; MAX_QUEUE_PROCESS = 50)struct Caps { uint16 perSeriesCapBps; uint16 perUnderlyingCapBps; uint16 totalDeployedCapBps; }struct WithdrawRequest { address owner; address receiver; uint256 shares; }function setCaps(Caps calldata caps_) external; // onlyOwnerfunction setMaxFeedStaleness(uint256 seconds_) external; // onlyOwnerfunction setQueueProcessLimit(uint256 limit) external; // onlyOwner, <= 50function fillCoupon(uint256 seriesId, uint256 amount) external; // onlyOwner, Subscription only, S > D, capsfunction liquidateToTreasury(address token, uint256 amount) external; // onlyOwnerfunction sweepToken(address token, address to, uint256 amount) external; // onlyOwnerfunction harvest(uint256 seriesId) external; // permissionlessfunction requestWithdraw(uint256 shares, address receiver) external returns (uint256 id);function cancelWithdrawRequest(uint256 id) external;function processQueue(uint256 n) external returns (uint256 filled);function queueLength() external view returns (uint256);function withdrawRequest(uint256 id) external view returns (WithdrawRequest memory);function idleAssets() external view returns (uint256);function heldStockValue() external view returns (uint256 total);function heldStocks() external view returns (address[] memory);function totalAssets() external view returns (uint256); // idle + deployed + heldStockValuefunction utilisationBps() external view returns (uint256); // deployed × 1e4 / totalAssets// Gauge-steered caps (MIN_UNDERLYING_CAP_BPS = 100, MAX_UNDERLYING_CAP_BPS = 4_000)function setGaugeController(address controller) external; // onlyOwnerfunction gaugeController() external view returns (address);function setPerUnderlyingCapFromGauge(address underlying, uint16 bps) external; // gauge controller only; NotGaugeController, CapOutOfBoundsfunction effectivePerUnderlyingCapBps(address underlying) external view returns (uint16); // min(caps.perUnderlyingCapBps, gauge value)function caps() external view returns (uint16 perSeries, uint16 perUnderlying, uint16 totalDeployed);
// UUPSModule (Treasury, BondDepository, RevenueRouter, Desk)function version() external pure returns (string memory); // "1.0.0" at launchfunction upgradeTimelock() external view returns (address);function setUpgradeTimelock(address newTimelock) external; // current UpgradeTimelock onlyfunction upgradeToAndCall(address newImplementation, bytes calldata data) external payable; // UpgradeTimelock only (NotUpgradeTimelock)The Market struct returned by market(id) adds bool active, uint256 totalDebt, uint48 lastDecay, uint256 sold and uint256 purchased to the MarketParams fields; capacity there is the remaining NOTE payout capacity.
Governance
Section titled “Governance”fact Copied from contracts/src/governance/interfaces/ and the contract sources. Owner of every governance contract is the 48-hour Timelock. See Governance for behaviour.
// veNOTE (IERC5805: getVotes, getPastVotes, getPastTotalSupply, clock, CLOCK_MODE; delegation reverts DelegationNotSupported)interface IVeNOTE is IERC5805 { struct Point { int128 bias; int128 slope; uint256 ts; } struct LockedBalance { int128 amount; uint256 end; uint256 stakedShares; uint256 stakedNoteEq; } // MAXTIME = 4 * 365 days; WEEK = 7 days; unlock times floor to a week boundary function createLock(uint256 amount, uint256 unlockTime) external; // whenNotPaused function increaseAmount(uint256 amount) external; function increaseUnlockTime(uint256 unlockTime) external; function depositFor(address account, uint256 amount) external; function lockFromStaked(uint256 shares, uint256 unlockTime) external; // sNOTE shares; unlockTime 0 for top-up function withdraw() external; // never pausable function checkpoint() external; function balanceOf(address account) external view returns (uint256); function balanceOfAt(address account, uint256 timestamp) external view returns (uint256); function totalSupply() external view returns (uint256); function totalSupplyAt(uint256 timestamp) external view returns (uint256); function locked(address account) external view returns (LockedBalance memory); function lockedEnd(address account) external view returns (uint256); function getLastUserSlope(address account) external view returns (int128); function userPointEpoch(address account) external view returns (uint256); function userPointHistory(address account, uint256 index) external view returns (Point memory); function pointHistory(uint256 index) external view returns (Point memory); function epoch() external view returns (uint256); function slopeChanges(uint256 timestamp) external view returns (int128);}
// NoteGovernor / UpgradeGovernor (OpenZeppelin v5.1 Governor; standard IGovernor surface plus:)function COUNTING_MODE() external pure returns (string memory); // "support=bravo,fractional&quorum=for,abstain¶ms=fractional"function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) external returns (uint256); // support 255 + abi.encodePacked(uint128 against, uint128 for, uint128 abstain)function proposalThreshold() external view returns (uint256); // max(absolute, pastTotalSupply(clock() - 1) * bps / 10_000)function setProposalThresholdBps(uint256 bps) external; // onlyGovernance; InvalidBps// UpgradeGovernor constants: MIN_QUORUM_NUMERATOR = 8; MIN_VOTING_PERIOD = 7 days; MIN_TIMELOCK_DELAY = 7 days
// GaugeController (types: 0 SeriesGauge, 1 DeskGauge, 2 StakingGauge; WEIGHT_VOTE_DELAY = 10 days;// CAP_FLOOR_BPS = 100; CAP_CEILING_BPS = 4_000)interface IGaugeController { function nGauges() external view returns (uint256); function gauges(uint256 index) external view returns (address); function gaugeTypes(address gauge) external view returns (int128); // UnknownGauge function gaugeRelativeWeight(address gauge, uint256 timestamp) external view returns (uint256); // WAD function gaugeRelativeWeightWrite(address gauge, uint256 timestamp) external returns (uint256);}function allGauges() external view returns (address[] memory);function gaugeUnderlying(address gauge) external view returns (address);function underlyings() external view returns (address[] memory);function voteForGaugeWeights(address gauge, uint256 userWeightBps) external; // whenNotPaused; sum <= 10_000; VoteCooldown, PowerExceeded, LockExpiresTooSoon, WeightTooHighfunction voteUserSlopes(address user, address gauge) external view returns (uint256 slope, uint256 power, uint256 end);function voteUserPower(address user) external view returns (uint256);function lastUserVote(address user, address gauge) external view returns (uint256);function checkpoint() external;function checkpointGauge(address gauge) external;function syncCaps() external; // once per week; DeskNotSet, AlreadySynced(week)function addType(string memory name, uint256 weight) external; // onlyOwnerfunction changeTypeWeight(int128 typeId, uint256 weight) external; // onlyOwnerfunction addGauge(address gauge, int128 gaugeType, uint256 weight, address underlying) external; // onlyOwnerfunction changeGaugeWeight(address gauge, uint256 weight) external; // onlyOwner; GaugeHasVotesfunction setDesk(IDeskGaugeCaps desk_) external; // onlyOwner
// IDeskGaugeCaps (implemented by Desk)interface IDeskGaugeCaps { function caps() external view returns (uint16 perSeriesCapBps, uint16 perUnderlyingCapBps, uint16 totalDeployedCapBps); function setPerUnderlyingCapFromGauge(address underlying, uint16 bps) external;}
// EmissionSchedule (defaults 300_000e18 / 200 bps / 4 weeks / 25_000e18)interface IEmissionSchedule { function weeklyEmission(uint256 timestamp) external view returns (uint256);}function periodsElapsed(uint256 timestamp) external view returns (uint256);function setSchedule(uint256 initialWeekly, uint256 decayBps, uint256 decayPeriodWeeks, uint256 floorWeekly) external; // onlyOwner; InvalidSchedule
// Minterfunction mintWeekly() external returns (uint256 minted); // anyone, once per week, whenNotPaused; AlreadyMinted, NothingToMintfunction currentWeek() external view returns (uint256);function mintedWeek(uint256 week) external view returns (bool);function mintedForWeek(uint256 week) external view returns (uint256);function mintedToGauge(address gauge) external view returns (uint256);function totalMinted() external view returns (uint256);function setSchedule(IEmissionSchedule schedule) external; // onlyOwner
// INOTEMintable (what Minter needs from NOTE)interface INOTEMintable is IERC20 { function mint(address to, uint256 amount) external; function epochMintRemaining() external view returns (uint256); function mintCapPerEpoch() external view returns (uint256); function currentEpoch() external view returns (uint256);}
// Gauges (RewardGauge base; DURATION = 7 days)interface IGauge { function notifyRewardAmount(uint256 amount) external; } // minter onlyfunction stake(uint256 amount) external; // whenNotPaused; DeskGauge: dNOTE, StakingGauge: sNOTE, SeriesGauge: COUPON units of LEG_ID = seriesId << 1function withdraw(uint256 amount) external; // never pausablefunction exit() external; // withdraw all + getRewardfunction getReward() external returns (uint256 amount);function earned(address account) external view returns (uint256);function rewardPerToken() external view returns (uint256);function lastTimeRewardApplicable() external view returns (uint256);function remainingRewards() external view returns (uint256);function setMinter(address minter_) external; // onlyOwner