Skip to content

Interfaces

fact Copied from contracts/src/interfaces/ (Solidity 0.8.28). Comments abridged.

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

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_ORACLE
function setCalendar(address calendar_) external; // onlyOwner, KEY_CALENDAR
function setFeeSink(address feeSink_) external; // onlyOwner, KEY_FEE_SINK
function setKeeperReward(uint256 keeperRewardQuote_) external; // onlyOwner, KEY_KEEPER_REWARD (ParamUpdated)
// Recovery Unwind (Subscription | Live only)
function proposeUnwind(uint256 seriesId) external; // onlyOwner, whenPaused
function cancelUnwind(uint256 seriesId) external; // onlyOwnerOrGuardian
function unwind(uint256 seriesId) external; // onlyOwner, whenPaused; status -> Unwound
function withdrawUnwound(uint256 seriesId) external returns (uint256 quoteOut, uint256 stockOut); // holders, never pausable
function sweepExcess(address token, address to) external; // onlyOwner; reverts NoExcess(token), UnwindPending(count)
function recordedLiabilities(address token) external view returns (uint256); // quote: totalQuoteEscrow; underlying: totalStockEscrow

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

function mint(address to, uint256 id, uint256 amount) external; // onlyCore
function burn(address from, uint256 id, uint256 amount) external; // onlyCore
function seriesOf(uint256 id) external pure returns (uint256); // id >> 1
function legOf(uint256 id) external pure returns (uint8); // id & 1
// plus standard ERC-1155: balanceOf, balanceOfBatch, safeTransferFrom, safeBatchTransferFrom, setApprovalForAll, uri
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);
}
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.

interface IFeeSink { function notifyFee(address token, uint256 amount) external; } // push: transfer first, then notify
interface IRewardSink { function notifyReward(uint256 amount) external; } // push: transfer first, then notify
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.

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; // onlyOwner
function setMintCapPerEpoch(uint256 newCap) external; // onlyOwner
function mint(address to, uint256 amount) external; // minters only, whenNotPaused
function 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; // onlyOwner
function setCooldown(uint256 newCooldown) external; // onlyOwner
function notifyReward(uint256 amount) external; // rewardNotifier only
function unvestedRewards() external view returns (uint256);
function totalAssets() external view returns (uint256); // balance − unvestedRewards()
function requestWithdraw(uint256 shares) external; // escrows shares, unlockAt = now + cooldown
function cancelWithdrawRequest() external;
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256); // owner == msg.sender, matured request
function 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; // onlyOwner
function setAssetEnabled(address token, bool enabled) external; // onlyOwner
function registerLegSeries(uint256 seriesId) external; // owner or BondDepository
function setDesk(address desk_) external; // onlyOwner
function setBondDepository(address depository) external; // onlyOwner
function setMaxFeedStaleness(uint256 staleness) external; // onlyOwner
function setRedemptionParams(uint16 haircutBps, uint16 dailyCapBps) external; // onlyOwner
function mintNote(address to, uint256 amount) external; // onlyOwner
function withdrawERC20(address token, address to, uint256 amount) external; // onlyOwner
function withdrawLegs(uint256 seriesId, address to, uint256 units) external; // onlyOwner
function 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; // permissionless
function 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); // onlyOwner
function closeMarket(uint256 id) external; // onlyOwner
function setControlVariable(uint256 id, uint256 controlVariable) external; // onlyOwner
function setDiscountParams(uint16 k, uint16 maxDiscountBps_) external; // onlyOwner
function setDesk(IDeskUtilisation desk_) external; // onlyOwner
function 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 lastDecay
function debtRatio(uint256 id) external view returns (uint256); // WAD, debt / NOTE.totalSupply
function 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; // onlyOwner
function setAuctionParams(uint256 halfLifeSeconds_, uint16 bumpBps_, uint16 maxFillBps_) external; // onlyOwner
function resetAuction(uint256 newStartPriceWad) external; // onlyOwner
function sweep(address token, address to, uint256 amount) external; // onlyOwner, not the quote token
function notifyFee(address token, uint256 amount) external; // quote token only
function sync() external; // route any un-notified quote balance
function 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 / 1e4
function 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; // onlyOwner
function setMaxFeedStaleness(uint256 seconds_) external; // onlyOwner
function setQueueProcessLimit(uint256 limit) external; // onlyOwner, <= 50
function fillCoupon(uint256 seriesId, uint256 amount) external; // onlyOwner, Subscription only, S > D, caps
function liquidateToTreasury(address token, uint256 amount) external; // onlyOwner
function sweepToken(address token, address to, uint256 amount) external; // onlyOwner
function harvest(uint256 seriesId) external; // permissionless
function 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 + heldStockValue
function 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; // onlyOwner
function gaugeController() external view returns (address);
function setPerUnderlyingCapFromGauge(address underlying, uint16 bps) external; // gauge controller only; NotGaugeController, CapOutOfBounds
function 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 launch
function upgradeTimelock() external view returns (address);
function setUpgradeTimelock(address newTimelock) external; // current UpgradeTimelock only
function 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.

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&params=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, WeightTooHigh
function 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; // onlyOwner
function changeTypeWeight(int128 typeId, uint256 weight) external; // onlyOwner
function addGauge(address gauge, int128 gaugeType, uint256 weight, address underlying) external; // onlyOwner
function changeGaugeWeight(address gauge, uint256 weight) external; // onlyOwner; GaugeHasVotes
function 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
// Minter
function mintWeekly() external returns (uint256 minted); // anyone, once per week, whenNotPaused; AlreadyMinted, NothingToMint
function 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 only
function stake(uint256 amount) external; // whenNotPaused; DeskGauge: dNOTE, StakingGauge: sNOTE, SeriesGauge: COUPON units of LEG_ID = seriesId << 1
function withdraw(uint256 amount) external; // never pausable
function exit() external; // withdraw all + getReward
function 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