Interest Payment
Overview
The Interest Payment contract provides a comprehensive solution for both interest-based payment schedules for loans backed by RestrictedLockupTokens and dividend distribution functionality for equity-like payments.
Key Features
Interest Payment Features
- Configurable interest accrual start and end timestamps
- Ability to create multiple payment periods with different interest rates
- Admin can fund interest payments and force claim interest on behalf of token holders
- Token holders can claim interest based on their ownership during specific periods
- Support for principal amount funding and claiming at maturity
- Comprehensive admin controls for managing interest distributions
Dividend Distribution Features
- Snapshot-based distributions: Dividends are distributed based on token holdings at specific timestamps
- Multiple token support: Distribute any ERC-20 token (USDC, DAI, etc.) as dividends
- Proportional allocation: Dividends are allocated proportionally to token ownership at snapshot time
- Batch operations: Efficient batch claiming and funding operations for multiple snapshots
- Flexible funding: Multiple dividend rounds can be funded for the same snapshot timestamp
- Audit trail: Complete tracking of funded, claimed, and unclaimed dividend amounts per snapshot
- Integration with SnapshotPeriods: Leverages the same snapshot system used for interest calculations
Usage
How It Works
Interest payments are distributed to recipients based on their proportional ownership of the RestrictedLockupToken at specific time periods and the configured interest rates for each period. The contract keeps track of token ownership through the SnapshotPeriods contract, which records token balances at different timestamps. Interest rates can be set differently for each payment period, allowing for flexible interest payment schedules. Role checks (e.g., Transfer Admin, Contract Admin) are routed to the external AccessControl
contract.
- Anyone funds the interest payment contract with a payment token (e.g., USDC) by calling
fundInterest()
. - Transfer Admin creates payment periods using
createPaymentPeriod()
, defining the start and end timestamps, interest rate, and interest rate period duration for the period. - Token holders can claim their interest by calling
claimInterest(amount)
orclaimInterestForPeriod(periodIdx, amount)
with an optional amount cap. - The contract calculates the amount of interest due based on the token holder's time-weighted ownership and the configured interest rate for each period.
- Interest is transferred to the token holder from the contract.
Principal Amount Management
The contract also supports principal amount management with partial operations:
- Transfer Admin can fund principal amounts using
fundPrincipal()
. - Token holders can claim their principal at maturity by calling
claimPrincipal(amount)
:amount = 0
: Claims all available principal for the token holderamount > 0
: Claims exactly the specified amount (must be divisible byprincipalAmountPerToken
)
- Transfer Admin can reclaim unused principal using
reclaimPrincipal(amount)
:amount = 0
: Reclaims all unused principalamount > 0
: Reclaims exactly the specified amount
- The principal amount per token is set during contract deployment.
This diagram illustrates the principal funding and claiming process:
-
Approve Funding: The Transfer Admin first approves the Interest Payment contract to spend payment tokens (like USDC) from their account.
-
Fund Principal: The Transfer Admin calls
fundPrincipal()
with the amount to fund, which must be divisible by the circulating token supply. -
Wait for Maturity: Principal can only be claimed after reaching the maturity date (defined by
interestAccrualEndTimestamp
). -
Token Holder Approval: To claim principal, the token holder must first approve the Interest Payment contract to transfer their security tokens.
-
Claim Principal: The token holder calls
claimPrincipal(amount)
, where:amount = 0
: Claims all available principal for their tokensamount > 0
: Claims the specific amount (must be divisible byprincipalAmountPerToken
)
-
Token Burn: The corresponding security tokens are burned from the token holder, effectively redeeming them.
-
Principal Payment: The requested principal amount in payment tokens is transferred to the token holder.
This process allows token holders to redeem their security tokens for the principal amount at maturity, similar to how a bond works in traditional finance.
Dividend Distribution Functionality
The InterestPayment contract also provides comprehensive dividend distribution capabilities through the IDividends interface. This allows the same contract to handle both debt-like interest payments and equity-like dividend distributions.
How Dividend Distribution Works
Dividends are distributed based on historical token ownership at specific timestamps (snapshots). This approach ensures fair distribution regardless of when dividends are actually funded or claimed.
Key Dividend Operations
Funding Dividends
// Fund dividends for a specific snapshot timestamp
interestPayment.fundDividend(
dividendTokenAddress, // e.g., USDC contract address
dividendAmount, // Total amount to distribute (must be divisible by total supply)
snapshotTimestamp // Historical timestamp for ownership calculation
);
Requirements:
- Dividend amount must be evenly divisible by the total token supply at the snapshot
- Snapshot timestamp must be valid (within the contract's operational range)
- Caller must have Transfer Admin role
- Dividend token must be a valid ERC-20 contract
Claiming Dividends
// Individual claim
interestPayment.claimDividend(dividendTokenAddress, snapshotTimestamp);
// Batch claim across multiple snapshots
uint256[] memory timestamps = [timestamp1, timestamp2, timestamp3];
interestPayment.batchClaimDividend(dividendTokenAddress, timestamps);
Querying Dividend Information
// Check unclaimed dividend amount for an address
uint256 unclaimed = interestPayment.unclaimedBalanceAt(
dividendTokenAddress,
holderAddress,
snapshotTimestamp
);
// Check total dividend amount available to claim (claimed + unclaimed)
uint256 totalAwarded = interestPayment.totalAwardedBalanceAt(
dividendTokenAddress,
holderAddress,
snapshotTimestamp
);
// Check how much dividend funding is available for a snapshot
uint256 totalFunds = interestPayment.tokensAt(dividendTokenAddress, snapshotTimestamp);
Dividend Allocation Logic
Dividends are allocated proportionally based on token ownership at the snapshot timestamp:
Holder's Dividend = (Holder's Token Balance at Snapshot / Total Supply at Snapshot) × Total Dividend Amount
Example:
- Total supply at snapshot: 1,000,000 tokens
- Holder owns: 50,000 tokens (5%)
- Total dividend funded: 100,000 USDC
- Holder's share: 5,000 USDC
Multiple Dividend Rounds
The system supports multiple dividend distributions for the same snapshot:
// Initial dividend funding
interestPayment.fundDividend(usdcAddress, 100000e6, snapshotTimestamp);
// Additional dividend funding for same snapshot
interestPayment.fundDividend(usdcAddress, 50000e6, snapshotTimestamp);
// Total available dividends: 150,000 USDC
Integration with Interest Payments
The unified contract design allows for the following scenarios:
- Quarterly Dividends: Regular dividend distributions based on quarterly snapshots
- Interest + Dividends: Simultaneous debt service payments and equity distributions
- Special Distributions: One-time dividend payments for specific events
- Multi-Token Distributions: Different dividend tokens (USDC, DAI, etc.) for different purposes
Example: Complete Dividend Cycle
// 1. End of quarter - snapshot timestamp is recorded automatically
uint256 quarterEndTimestamp = block.timestamp;
// 2. Company profits are calculated off-chain
uint256 quarterlyProfits = 500000e6; // 500,000 USDC
// 3. Admin funds dividend distribution
usdcToken.approve(interestPaymentAddress, quarterlyProfits);
interestPayment.fundDividend(usdcAddress, quarterlyProfits, quarterEndTimestamp);
// 4. Token holders claim their dividends
interestPayment.claimDividend(usdcAddress, quarterEndTimestamp);
This dividend functionality transforms the InterestPayment contract into a comprehensive tool for both debt and equity token management.
Administrative Functions
The Interest Payment contract provides several advanced administrative functions to adjust the terms of the interest and principal payments after deployment:
Extending Maturity (shiftInterestAccrualEnd)
The shiftInterestAccrualEnd(timestamp)
function allows the Contract Admin or Transfer Admin to extend the maturity date by updating the interestAccrualEndTimestamp
. This is particularly useful when:
- The original maturity date needs to be extended due to business requirements
- The loan or bond term is being renegotiated
- Regulatory requirements necessitate a modification to the maturity date
The new timestamp must be greater than the current interestAccrualEndTimestamp
, ensuring that maturity can only be extended, not reduced.
Managing Interest for Payment Periods
Creating Payment Periods
When creating payment periods with createPaymentPeriod(startTimestamp, endTimestamp, interestRate, interestRatePeriodDuration)
, the following requirements must be met:
- Periods must be created sequentially, with no gaps between them
- The end timestamp of one period must be the start timestamp of the next period
- The first period must start at
interestAccrualStartTimestamp
- Each period's end timestamp must be a multiple of
interestRatePeriodSeconds
from the start timestamp, except for the final period which may end atinterestAccrualEndTimestamp
- Periods cannot be created for timestamps before
interestAccrualStartTimestamp
or afterinterestAccrualEndTimestamp
- Interest rates cannot exceed
maxInterestRate
if set (0 means no limit)
This sequential creation ensures continuous tracking of token ownership across the entire interest accrual timeframe. Interest is calculated dynamically based on the rate and time-weighted token ownership rather than fixed amounts.
Updating Interest Rate for a Period
The updateInterestRateForPeriod(periodIdx, interestRate, interestRatePeriodDuration)
function allows the Transfer Admin to modify the interest rate for a specific payment period before it starts. This enables:
- Correcting interest rate configurations
- Adjusting rates due to changing market conditions
- Setting interest rate to zero for periods where no interest should accrue
Important: Interest rates can only be updated before the period starts (i.e., before block.timestamp > period.startTimestamp
). The new rate cannot exceed maxInterestRate
if set.
Setting a period's interest rate to zero effectively means that no token holder will accrue interest during that period, regardless of their token ownership. This can be useful for:
- Implementing grace periods
- Reflecting periods of non-performance
- Handling special situations where interest payments should be suspended
Managing Maximum Interest Rate
The setMaxInterestRate(maxInterestRate)
function allows the Contract Admin to set a maximum interest rate cap. When set to 0, there is no limit on interest rates. This provides:
- Protection against accidentally setting excessively high interest rates
- Governance control over maximum borrowing costs
- Flexibility to adjust rate caps as market conditions change
These administrative functions provide considerable flexibility in managing the lifecycle of interest-bearing security tokens, allowing adjustments to both principal and interest terms while maintaining the integrity of the payment system.
Reclaiming Interest and Principal
In cases where interest or principal funds need to be reclaimed, administrators can use several functions to reclaim unused funds. This is often necessary in scenarios such as contract migration, correction of funding errors, or legal compliance requirements.
Reclaiming Interest
The Interest Payment contract provides multiple ways to reclaim interest:
- Setup: Contract Admin sets the reclaimer address that will receive all reclaimed funds
- Pause: Transfer Admin pauses payment for the specific period being reclaimed
- Reclaim Options:
reclaimInterest(wallet, paymentPeriodIdx)
: Reclaims unclaimed interest from a specific wallet for a periodreclaimInterestForAllRecipients(paymentPeriodIdx)
: Reclaims all unclaimed interest for an entire periodreclaimTotalInterest(amount)
: Reclaims a specific amount of unused interest
- Unpause: Transfer Admin unpauses payment for the period after reclaiming is complete
Reclaiming Principal
The principal amount can also be reclaimed if needed:
- Setup: Contract Admin sets the reclaimer address that will receive reclaimed funds
- Pause: Transfer Admin pauses the entire contract
- Reclaim: Transfer Admin reclaims all unused principal funds
- Unpause: Transfer Admin unpauses the contract after reclaiming is complete
Important Considerations
- A valid reclaimer address must be set before any reclaiming can occur
- Pausing before reclaiming prevents users from claiming during the reclaim process
- Unpausing after reclaiming allows normal operations to resume
- Only Transfer Admin can reclaim funds, while Contract Admin can set the reclaimer address
- Reclaimed funds are transferred directly to the reclaimer address
Early Repayment
The Interest Payment contract supports early repayment functionality, allowing Contract Admin or Transfer Admin to trigger an early maturity event. This feature is useful in scenarios such as:
- Refinancing debt at a lower interest rate
- Restructuring financial obligations
- Implementing callable bonds that can be paid off before maturity
- Responding to changes in market conditions
The earlyRepayment(timestamp)
function performs two key actions:
- Sets the interest accrual end timestamp to the specified timestamp, effectively stopping any further interest accrual
- Pauses payment after the specified timestamp to provide administrative control over final payments
When early repayment is triggered:
- Interest stops accruing at the specified timestamp, freezing the total interest amount
- Token holders can still claim their accrued interest up to the repayment timestamp
- Principal becomes available for claiming immediately (assuming it has been funded)
- The EarlyRepayment event is emitted, recording the admin address and timestamp
This feature provides important flexibility in managing debt instruments represented by the token, allowing administrators to respond to changing financial conditions while preserving token holders' rights to receive their accrued interest and principal.
Force Claiming Interest
The Interest Payment contract provides administrative functions to force claim interest on behalf of wallet addresses. This is particularly useful in scenarios such as:
- Processing interest distributions for wallets that may not have the means to claim independently
- Managing automated distributions for institutional or managed accounts
- Handling special settlement cases requiring administrative intervention
- Distributing interest from paused payment periods for specific wallets
Two administrative force claim functions are available:
Force Claim for Specific Period (forceClaimForPeriod)
The forceClaimForPeriod(wallet, periodIdx, amount)
function allows the Transfer Admin to force claim interest for a specific wallet from a specific payment period:
- If the amount parameter is set to 0, all available interest for that wallet and period will be claimed
- If the amount parameter is greater than 0, only that amount will be claimed (up to the available claimable amount)
- This function works even for paused payment periods, providing administrative override capability
- The
ForceClaimed
event is emitted with details of the transfer admin, recipient wallet, amount, and period index
Force Claim Across All Periods (forceClaim)
The forceClaim(wallet, amount)
function allows the Transfer Admin to force claim interest for a specific wallet across all eligible payment periods:
- Similar to
forceClaimForPeriod
, if amount is 0, all available interest is claimed - If amount is greater than 0, the function will claim up to that amount, potentially across multiple periods
- The function processes periods sequentially, and will stop once the specified amount is reached
- This function also works for paused payment periods
- The
ForceClaimed
event is emitted for each period from which interest is claimed
Admin Functions
The Interest Payment contract has several admin functions for managing interest payments:
createPaymentPeriod(startTimestamp, endTimestamp, interestRate, interestRatePeriodDuration)
: Creates a new payment period with specified interest rate.updateInterestRateForPeriod(periodIdx, interestRate, interestRatePeriodDuration)
: Updates the interest rate for a specific period before it starts.setMaxInterestRate(maxInterestRate)
: Sets the maximum allowed interest rate (Contract Admin only).fundInterest(amount)
: Funds the contract with interest payment tokens.claimInterest(amount)
: Allows token holders to claim interest across all payment periods, with optional amount cap (0 for all available).claimInterestForPeriod(periodIdx, amount)
: Enables token holders to claim interest for a specific payment period, with optional amount cap.batchClaimInterestForPeriods(periodIdxs[], amount)
: Allows token holders to claim interest for multiple payment periods in a single transaction, with optional amount cap.reclaimInterest(wallet, amount)
: Reclaims unclaimed interest from a wallet across all periods, with optional amount cap.reclaimInterestForPeriod(wallet, paymentPeriodIdx, amount)
: Reclaims unclaimed interest from a wallet for a specific period, with optional amount cap.batchReclaimInterest(wallet, periodIdxs[], amount)
: Reclaims unclaimed interest from a wallet for multiple periods, with optional amount cap.reclaimInterestForAllRecipients(paymentPeriodIdx)
: Reclaims all unclaimed interest for a period.reclaimTotalInterest(amount)
: Reclaims a specific amount of unused interest.pausePaymentPeriod(periodIdx)
andunpausePaymentPeriod(periodIdx)
: Pauses or unpauses claiming for a specific period.pausePaymentAfter(timestamp)
: Pauses claiming after the given timestamp.unpausePaymentAfter()
: Unpause claiming.pause(isPaused)
: Pauses or unpauses the entire contract.shiftInterestAccrualEnd(timestamp)
: Updates the end timestamp for interest accrual for all payment periods. This allows the Transfer Admin to extend the maturity day.setReclaimerAddress(reclaimerAddress)
: Sets the address that is authorized to receive reclaimed interest. This address must be set before any reclaim operations can be performed.fundPrincipal(amount)
: Transfers principal payment tokens to the contract for distribution to token holders at maturity.claimPrincipal(amount)
: Allows token holders to claim their principal amount at maturity based on their token holdings. Amount parameter: 0 = claim all available, >0 = claim specific amount.reclaimPrincipal(amount)
: Enables the Transfer Admin to reclaim unclaimed principal amounts from the contract. Amount parameter: 0 = reclaim all available, >0 = reclaim specific amount.earlyRepayment(timestamp)
: Allows the Contract Admin or Transfer Admin to trigger early repayment of the loan at a specific timestamp. If timestamp is 0, uses current block timestamp.forceClaim(wallet, amount)
: Allows Transfer Admin to force claim interest for a specific wallet across all payment periods, with optional amount cap (0 for all available).forceClaimForPeriod(wallet, periodIdx, amount)
: Enables Transfer Admin to force claim interest for a specific wallet and payment period, with optional amount cap (0 for all available).
Interest Accrual and Calculation
The contract provides several view functions to check accrued interest:
totalAccruedInterest()
: Returns the total accrued interest at the current time.totalAccruedInterestAt(timestamp)
: Returns the total accrued interest at a specific timestamp.accruedInterest(account)
: Returns the accrued interest for a specific account.accruedInterestAt(account, timestamp)
: Returns the accrued interest for a specific account at a specific timestamp.accruedInterestForPeriod(account, periodIdx)
: Returns the accrued interest for a specific account in a specific payment period.paymentPeriodsCount()
: Returns the total number of payment periods that have been created.periodTotalInterest(periodIdx)
: Returns the total interest amount that was accrued during a specific payment period.periodTotalClaimedInterest(periodIdx)
: Returns the total amount of interest that has been claimed by token holders for a specific payment period.periodTotalReclaimedInterest(periodIdx)
: Returns the total amount of interest that has been reclaimed by the admin for a specific payment period.periodAvailableInterest(periodIdx)
: Returns the amount of interest that is still available to be claimed for a specific payment period.periodDuration(periodIdx)
: Returns the duration (in seconds) of a specific payment period.periodStartTimestamp(periodIdx)
: Returns the start timestamp of a specific payment period.periodEndTimestamp(periodIdx)
: Returns the end timestamp of a specific payment period.unclaimedAmountAt(receiver, timestamp)
: Returns the amount of unclaimed interest for a specific receiver at a given timestamp.unclaimedAmountForPeriod(receiver, periodIdx)
: Returns the amount of unclaimed interest for a specific receiver in a specific payment period.claimedAmountForPeriod(receiver, periodIdx)
: Returns the amount of interest that has been claimed by a specific receiver in a specific payment period.reclaimedAmountForPeriod(receiver, periodIdx)
: Returns the amount of interest that has been reclaimed from a specific receiver in a specific payment period.usedAmountForPeriod(receiver, periodIdx)
: Returns the total amount of interest that has been either claimed or reclaimed for a specific receiver in a specific payment period.accountTotalClaimedAmount(receiver)
: Returns the total amount of interest that has been claimed by a specific receiver across all payment periods.accountTotalReclaimedAmount(receiver)
: Returns the total amount of interest that has been reclaimed from a specific receiver across all payment periods.totalInterestAmountFunded()
: Returns the total amount of interest that has been funded to the contract.totalInterestAmountClaimed()
: Returns the total amount of interest that has been claimed by all token holders.totalInterestAmountReclaimed()
: Returns the total amount of interest that has been reclaimed by admins.totalInterestAmountUnused()
: Returns the total amount of interest that remains unused in the contract.nearestInterestPaymentTimestampAt(timestamp)
: Returns the nearest interest payment timestamp at a given timestamp (rounded to period boundaries).findPaymentPeriodIndex(startTimestamp, endTimestamp)
: Finds the index of a payment period that covers the specified time range.paymentPeriodPaused(periodIdx)
: Returns whether a specific payment period is paused.fundedPrincipalAmount()
: Returns the total amount of principal that has been funded to the contract.reclaimPrincipalAmount()
: Returns the total amount of principal that has been reclaimed by the admin.claimedPrincipalAmount()
: Returns the total amount of principal that has been claimed by token holders.totalAvailablePrincipalAmount()
: Returns the total amount of principal that is still available to be claimed.availablePrincipalAmount(account)
: Returns the amount of principal that is available to be claimed by a specific account.
Interest is accrued based on configurable interest rates and calculated using the formula:
interest = (time-weighted ownership * interestRatePerSecond * principalAmountPerToken) / PRECISION_FACTORS
Where:
time-weighted ownership
= token balance × time period durationinterestRatePerSecond
=(interestRate × INTEREST_RATE_PRECISION_FACTOR) / interestRatePeriodDuration
INTEREST_RATE_PRECISION_FACTOR = 1,000,000,000
for precision in interest rate calculationsBIPS_PRECISION = 10,000
for basis points calculations
The interest rate is specified in basis points (bips) where 10,000 bips = 100%. For example, a 5% annual interest rate would be specified as 500 bips.
Amount Parameter Behavior
All claiming and reclaiming functions support an amount
parameter that allows users to specify how much they want to claim or reclaim:
- amount = 0: Claims/reclaims all available funds
- amount > 0: Claims/reclaims up to the specified amount, capped at available funds
- If the specified amount exceeds available funds, the transaction will revert with
InterestPayment_NotEnoughFundsToClaim
This provides fine-grained control over fund movements and enables partial claiming/reclaiming scenarios.
Principal Amount Parameter Behavior
Principal claiming and reclaiming functions also support an amount
parameter for precise control:
For claimPrincipal(amount)
:
- amount = 0: Claims all available principal for the token holder's current balance
- amount > 0: Claims exactly the specified amount, with requirements:
- Amount must not exceed the holder's available principal (
tokenBalance × principalAmountPerToken
) - Amount must be divisible by
principalAmountPerToken
to ensure exact token-to-principal conversion - Corresponding tokens are transferred:
tokensToTransfer = amount / principalAmountPerToken
- Amount must not exceed the holder's available principal (
For reclaimPrincipal(amount)
:
- amount = 0: Reclaims all unused principal from the contract
- amount > 0: Reclaims exactly the specified amount, capped at available unused principal
This enables use cases such as:
- Partial redemption of token positions
- Staged principal withdrawals
- Precise fund management for complex financial instruments
Error Handling
Administrative Errors
InterestPayment_InvalidRestrictedLockupTokenAddress
: Thrown when attempting to deploy with an invalid token addressInterestPayment_InvalidDividendTokenAddress
: Thrown when an invalid dividend token address is providedInterestPayment_InvalidPaymentPeriodSeconds
: Thrown when payment period is set to zeroInterestPayment_InvalidReclaimerAddress
: Thrown when attempting to set a zero address as reclaimerInterestPayment_InvalidTimestamp
: Thrown when providing an invalid timestamp for payment pausingInterestPayment_InvalidPaymentToken
: Thrown when payment token address is invalidInterestPayment_InterestRateGreaterThanMaxInterestRate
: Thrown when trying to set interest rate above max rateInterestPayment_PeriodAlreadyStarted
: Thrown when trying to update interest rate after period has startedInterestPayment_InterestRateNotChanged
: Thrown when trying to update interest rate to the same valueInterestPayment_MaxInterestRateNotChanged
: Thrown when trying to set max interest rate to the same value
Configuration Errors
InterestPayment_InvalidInterestAccrualStartTimestamp
: Thrown when start timestamp is set to zeroInterestPayment_InvalidInterestAccrualEndTimestamp
: Thrown when end timestamp is set to zeroInterestPayment_InvalidInterestAccrualPeriod
: Thrown when start timestamp is greater than or equal to end timestampInterestPayment_CannotUnpauseAfterMaturity
: Thrown when attempting to unpause payments after maturityInterestPayment_PaymentNotPausedAfter
: Thrown when trying to unpause when not paused
Period Management Errors
InterestPayment_InvalidPeriod
: Thrown when referencing a non-existent periodInterestPayment_StartTimestampGreaterThanEndTimestamp
: Thrown when creating a period with start after endInterestPayment_StartTimestampBeforeAccrualStartTimestamp
: Thrown when period starts before overall interest accrual startInterestPayment_EndTimestampGreaterThanAccrualEndTimestamp
: Thrown when period ends after overall interest accrual endInterestPayment_NoPaymentPeriods
: Thrown when attempting to claim interest when no payment periods have been createdInterestPayment_PeriodDurationNotMultipleOfInterestRatePeriod
: Thrown when a payment period's duration does not align with the configured interest rate period. For example, if the interest rate period is set to 1 day (86400 seconds), then all payment periods must start and end at the same time of day. If interest accrual begins at2025-01-01 12:00:00
, then valid period boundaries would be2025-01-01 12:00:00
to2025-01-02 12:00:00
,2025-01-02 12:00:00
to2025-01-03 12:00:00
, etc. This ensures consistent interest accrual calculations across all periods.InterestPayment_PeriodAlreadyExists
: Thrown when attempting to create a duplicate periodInterestPayment_PeriodNotNext
: Thrown when attempting to create a payment period that does not immediately follow the previous period. For example, if the last payment period ends at2025-02-14 12:00:00
, the next period must start at exactly that timestamp. Creating a period starting at2025-02-24 12:00:00
would fail because it creates a gap in the payment schedule. This ensures continuous, sequential payment periods without any gaps in the interest accrual timeline.InterestPayment_InvalidTotalAccruedInterest
: Thrown when setting accrued interest below already claimed/reclaimed amountInterestPayment_PaymentPeriodPaused
: Thrown when attempting to claim from a paused period
Funding and Claiming Errors
InterestPayment_InvalidAmount
: Thrown when attempting to fund with zero amountInterestPayment_TokenSupplyIsZero
: Thrown when token supply is zero during principal fundingInterestPayment_PrincipalAmountNotDivisibleByTokenSupply
: Thrown when principal amount isn't divisible by token supplyInterestPayment_InvalidToken
: Thrown when using an invalid token for paymentInterestPayment_InvalidFeeApplied
: Thrown when token transfer results in unexpected balanceInterestPayment_NoFundsToClaim
: Thrown when attempting to claim with no available fundsInterestPayment_NotEnoughFundsToClaim
: Thrown when attempting to force claim more than availableInterestPayment_InvalidUnclaimedAmount
: Thrown when unclaimed calculation produces invalid resultInterestPayment_NotEnoughFundedPrincipal
: Thrown when attempting to claim more principal than availableInterestPayment_MaturityNotReached
: Thrown when attempting to claim principal before maturity
API Reference
Constructor
constructor(ConstructorParams params)
Initializes the InterestPayment contract with configuration parameters.
Parameters:
params
(ConstructorParams): Struct containing initialization parameters
ConstructorParams Structure:
struct ConstructorParams {
address accessControl; // External access control contract address
address restrictedLockupTokenAddress; // RestrictedLockupToken contract address
address trustedForwarder; // ERC-2771 trusted forwarder address
address paymentToken; // ERC-20 token used for payments
uint256 paymentPeriodSeconds; // Interest rate period duration in seconds
uint256 principalAmountPerToken; // Principal amount per token for maturity claims
uint256 interestAccrualStartTimestamp; // When interest accrual begins
uint256 interestAccrualEndTimestamp; // When interest accrual ends (maturity)
uint256 maxInterestRate; // Maximum allowed interest rate in basis points
}
Requirements:
- All addresses must be non-zero
- Payment period seconds must be greater than zero
- Interest accrual start must be before end timestamp
- Principal amount per token must be greater than zero
Constants
CONTRACT_ADMIN_ROLE() → uint8
Returns the contract admin role constant (1).
Returns:
uint8
: The contract admin role value
RESERVE_ADMIN_ROLE() → uint8
Returns the reserve admin role constant (2).
Returns:
uint8
: The reserve admin role value
WALLETS_ADMIN_ROLE() → uint8
Returns the wallets admin role constant (4).
Returns:
uint8
: The wallets admin role value
TRANSFER_ADMIN_ROLE() → uint8
Returns the transfer admin role constant (8).
Returns:
uint8
: The transfer admin role value
INTEREST_RATE_PRECISION_FACTOR() → uint256
Returns the precision factor used for interest rate calculations (1,000,000,000).
Returns:
uint256
: The precision factor for interest calculations
Administrative Functions (API)
pause(bool isPaused_)
Pauses or unpauses the contract.
Parameters:
isPaused_
(bool): True to pause, false to unpause
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
Emits: Paused
or Unpaused
events
pausePaymentPeriod(uint256 periodIdx)
Pauses a specific payment period.
Parameters:
periodIdx
(uint256): Index of the payment period to pause
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
- Period index must be valid
Emits: PeriodPaused(authority, periodIdx)
unpausePaymentPeriod(uint256 periodIdx)
Unpauses a specific payment period.
Parameters:
periodIdx
(uint256): Index of the payment period to unpause
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
- Period index must be valid
Emits: PeriodUnpaused(authority, periodIdx)
pausePaymentAfter(uint256 timestamp)
Pauses all payments after a specific timestamp.
Parameters:
timestamp
(uint256): Timestamp after which payments are paused
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
- Timestamp must be in the future
Emits: PaymentPausedAfter(timestamp)
unpausePaymentAfter()
Removes the payment pause timestamp.
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
- Payments must currently be paused after a timestamp
- Current time must be before maturity
Emits: PaymentUnpausedAfter()
setReclaimerAddress(address newReclaimerAddress)
Sets the address that receives reclaimed funds.
Parameters:
newReclaimerAddress
(address): New reclaimer address
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE
Emits: ReclaimerAddressChanged(authority, newReclaimerAddress)
shiftInterestAccrualEnd(uint256 newInterestAccrualEndTimestamp)
Extends the interest accrual end timestamp (maturity date).
Parameters:
newInterestAccrualEndTimestamp
(uint256): New end timestamp
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
- New timestamp must be after current end timestamp
Emits: InterestAccrualEndShifted(authority, newInterestAccrualEndTimestamp)
setMaxInterestRate(uint256 maxInterestRate_)
Sets the maximum allowed interest rate.
Parameters:
maxInterestRate_
(uint256): New maximum interest rate in basis points
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE
- Rate must be different from current rate
Emits: SetMaxInterestRate(authority, maxInterestRate_)
earlyRepayment(uint256 timestamp)
Triggers early repayment by pausing payments and updating maturity.
Parameters:
timestamp
(uint256): New maturity timestamp
Requirements:
- Caller must have CONTRACT_ADMIN_ROLE or TRANSFER_ADMIN_ROLE
- Timestamp must be in the future
Emits: EarlyRepayment(authority, timestamp)
Payment Period Management
createPaymentPeriod(uint256 startTimestamp, uint256 endTimestamp, uint256 interestRate_, uint256 interestRatePeriodDuration)
Creates a new payment period with specified interest rate.
Parameters:
startTimestamp
(uint256): Period start timestampendTimestamp
(uint256): Period end timestampinterestRate_
(uint256): Interest rate in basis pointsinterestRatePeriodDuration
(uint256): Duration for interest rate calculation
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Start must be before end timestamp
- Period must be sequential (no gaps)
- Interest rate must not exceed maximum
Emits: PaymentPeriodCreated(authority, periodIdx, startTimestamp, endTimestamp, interestRate_)
updateInterestRateForPeriod(uint256 periodIdx, uint256 interestRate_, uint256 interestRatePeriodDuration)
Updates the interest rate for an existing period before it starts.
Parameters:
periodIdx
(uint256): Index of the period to updateinterestRate_
(uint256): New interest rate in basis pointsinterestRatePeriodDuration
(uint256): Duration for interest rate calculation
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Period must not have started yet
- Interest rate must be different from current rate
- Rate must not exceed maximum
Emits: InterestRateUpdated(authority, periodIdx, interestRate_)
Interest Funding and Management
fundInterest(uint256 amount)
Funds the contract with payment tokens for interest distributions.
Parameters:
amount
(uint256): Amount of payment tokens to fund
Requirements:
- Contract must not be paused
- Amount must be greater than zero
- Caller must have approved tokens to contract
Emits: Funded(funder, amount)
claimInterest(uint256 amount)
Claims available interest for the caller across all periods.
Parameters:
amount
(uint256): Maximum amount to claim (0 = claim all available)
Requirements:
- Contract must not be paused
- Must have available interest to claim
- Periods must not be paused
Emits: Claimed(claimer, amount, periodIdx)
for each period
claimInterestForPeriod(uint256 paymentPeriodIdx, uint256 amount)
Claims interest for a specific payment period.
Parameters:
paymentPeriodIdx
(uint256): Index of the payment periodamount
(uint256): Amount to claim (0 = claim all available for period)
Requirements:
- Contract must not be paused
- Period must exist and not be paused
- Must have available interest for the period
Emits: Claimed(claimer, amount, paymentPeriodIdx)
batchClaimInterestForPeriods(uint256[] paymentPeriodIdxs, uint256 amount)
Claims interest across multiple specified periods.
Parameters:
paymentPeriodIdxs
(uint256[]): Array of payment period indicesamount
(uint256): Maximum total amount to claim across periods
Requirements:
- Contract must not be paused
- All periods must exist and not be paused
- Must have available interest in the periods
Emits: Claimed(claimer, amount, periodIdx)
for each period
forceClaim(address wallet, uint256 amount)
Force claims interest on behalf of a wallet (admin function).
Parameters:
wallet
(address): Address to claim interest foramount
(uint256): Maximum amount to claim (0 = claim all available)
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
Emits: ForceClaimed(authority, wallet, amount, periodIdx)
for each period
forceClaimForPeriod(address wallet, uint256 paymentPeriodIdx, uint256 amount)
Force claims interest for a specific period on behalf of a wallet.
Parameters:
wallet
(address): Address to claim interest forpaymentPeriodIdx
(uint256): Index of the payment periodamount
(uint256): Amount to claim
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Period must exist
Emits: ForceClaimed(authority, wallet, amount, paymentPeriodIdx)
batchForceClaimInterest(address wallet, uint256[] paymentPeriodIdxs, uint256 amount)
Force claims interest across multiple periods on behalf of a wallet.
Parameters:
wallet
(address): Address to claim interest forpaymentPeriodIdxs
(uint256[]): Array of payment period indicesamount
(uint256): Maximum total amount to claim
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
Emits: ForceClaimed(authority, wallet, amount, periodIdx)
for each period
Interest Reclaiming Functions
reclaimInterest(address wallet, uint256 amount)
Reclaims unclaimed interest from a wallet to the reclaimer address.
Parameters:
wallet
(address): Address to reclaim interest fromamount
(uint256): Maximum amount to reclaim (0 = reclaim all available)
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Reclaimer address must be set
Emits: Reclaimed(reclaimerAddress, wallet, amount, periodIdx)
for each period
reclaimInterestForPeriod(address wallet, uint256 paymentPeriodIdx, uint256 amount)
Reclaims interest from a specific period.
Parameters:
wallet
(address): Address to reclaim interest frompaymentPeriodIdx
(uint256): Index of the payment periodamount
(uint256): Amount to reclaim
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Period must exist
- Reclaimer address must be set
Emits: Reclaimed(reclaimerAddress, wallet, amount, paymentPeriodIdx)
batchReclaimInterest(address wallet, uint256[] paymentPeriodIdxs, uint256 amount)
Reclaims interest across multiple periods.
Parameters:
wallet
(address): Address to reclaim interest frompaymentPeriodIdxs
(uint256[]): Array of payment period indicesamount
(uint256): Maximum total amount to reclaim
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Reclaimer address must be set
Emits: Reclaimed(reclaimerAddress, wallet, amount, periodIdx)
for each period
reclaimInterestForAllRecipients(uint256 paymentPeriodIdx)
Reclaims all remaining interest from a completed period.
Parameters:
paymentPeriodIdx
(uint256): Index of the payment period
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Period must be completed (past end timestamp)
- Reclaimer address must be set
Emits: ReclaimedAll(reclaimerAddress, amount, paymentPeriodIdx)
reclaimTotalInterest(uint256 amount)
Reclaims a specified amount from total unused interest funds.
Parameters:
amount
(uint256): Amount to reclaim
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Amount must be available in unused funds
Emits: ReclaimedAll(reclaimerAddress, amount, type(uint256).max)
Principal Management Functions
fundPrincipal(uint256 amount)
Funds principal amount for maturity claims.
Parameters:
amount
(uint256): Amount of payment tokens to fund as principal
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Amount must be divisible by circulating token supply
Emits: PrincipalFunded(funder, amount)
claimPrincipal(uint256 amount)
Claims principal at maturity by burning tokens.
Parameters:
amount
(uint256): Amount to claim (0 = claim all available)
Requirements:
- Contract must not be paused
- Maturity must be reached
- Caller must have tokens to burn
- Sufficient principal must be funded
Emits: PrincipalClaimed(claimer, amount)
forceClaimPrincipal(address wallet, uint256 amount)
Force claims principal on behalf of a wallet.
Parameters:
wallet
(address): Address to claim principal foramount
(uint256): Amount to claim (0 = claim all available)
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Maturity must be reached
Emits: PrincipalClaimed(wallet, amount)
reclaimPrincipal(uint256 amount)
Reclaims unused principal funds.
Parameters:
amount
(uint256): Amount to reclaim (0 = reclaim all available)
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Reclaimer address must be set
Emits: PrincipalReclaimed(authority, amount)
Dividend Functions (IDividends Interface)
fundDividend(address token_, uint256 amount_, uint256 timestamp_)
Funds dividend distribution for a specific snapshot timestamp.
Parameters:
token_
(address): ERC-20 token address for dividend paymentsamount_
(uint256): Amount of tokens to distributetimestamp_
(uint256): Snapshot timestamp for token holder eligibility
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- Contract must not be paused
- Timestamp must be in the past
- Amount must be divisible by total supply at timestamp
Emits: DividendFunded(funder, token_, amount_, timestamp_)
claimDividend(address token_, uint256 timestamp_)
Claims dividend for a specific token and timestamp.
Parameters:
token_
(address): ERC-20 token addresstimestamp_
(uint256): Snapshot timestamp
Requirements:
- Contract must not be paused
- Timestamp must be valid (past timestamp)
- Must have unclaimed dividend balance
Emits: DividendClaimed(claimer, token_, amount, timestamp_)
batchClaimDividend(address token_, uint256[] timestamps_)
Claims dividends across multiple timestamps for a token.
Parameters:
token_
(address): ERC-20 token addresstimestamps_
(uint256[]): Array of snapshot timestamps
Requirements:
- Contract must not be paused
- All timestamps must be valid
Emits: DividendClaimed(claimer, token_, amount, timestamp_)
for each timestamp
Query Functions
Interest Calculation Functions
accruedInterest(address account) → uint256
Returns total accrued interest for an account up to current time.
Parameters:
account
(address): Address to query interest for
Returns:
uint256
: Total accrued interest amount
accruedInterestAt(address account, uint256 timestamp) → uint256
Returns accrued interest for an account up to a specific timestamp.
Parameters:
account
(address): Address to query interest fortimestamp
(uint256): Timestamp to calculate interest up to
Returns:
uint256
: Accrued interest amount at timestamp
accruedInterestForPeriod(address account, uint256 periodIdx) → uint256
Returns accrued interest for a specific period.
Parameters:
account
(address): Address to query interest forperiodIdx
(uint256): Payment period index
Returns:
uint256
: Accrued interest for the period
totalAccruedInterest() → uint256
Returns total accrued interest across all accounts and periods.
Returns:
uint256
: Total accrued interest amount
totalAccruedInterestAt(uint256 timestamp) → uint256
Returns total accrued interest up to a specific timestamp.
Parameters:
timestamp
(uint256): Timestamp to calculate interest up to
Returns:
uint256
: Total accrued interest at timestamp
Period Information Functions
paymentPeriodsCount() → uint256
Returns the number of created payment periods.
Returns:
uint256
: Count of payment periods
paymentPeriodPaused(uint256 periodIdx) → bool
Checks if a payment period is paused.
Parameters:
periodIdx
(uint256): Payment period index
Returns:
bool
: True if period is paused
periodTotalInterest(uint256 periodIdx) → uint256
Returns total interest for a period based on current accrual.
Parameters:
periodIdx
(uint256): Payment period index
Returns:
uint256
: Total interest amount for the period
periodAvailableInterest(uint256 periodIdx) → uint256
Returns available (unclaimed/unreclaimed) interest for a period.
Parameters:
periodIdx
(uint256): Payment period index
Returns:
uint256
: Available interest amount
periodStartTimestamp(uint256 periodIdx) → uint256
Returns the start timestamp of a payment period.
Parameters:
periodIdx
(uint256): Payment period index
Returns:
uint256
: Period start timestamp
periodEndTimestamp(uint256 periodIdx) → uint256
Returns the end timestamp of a payment period.
Parameters:
periodIdx
(uint256): Payment period index
Returns:
uint256
: Period end timestamp
periodDuration(uint256 periodIdx) → uint256
Returns the duration of a payment period in seconds.
Parameters:
periodIdx
(uint256): Payment period index
Returns:
uint256
: Period duration in seconds
Account Balance Functions
unclaimedAmountForPeriod(address receiver_, uint256 paymentPeriodIdx_) → uint256
Returns unclaimed interest amount for an account in a specific period.
Parameters:
receiver_
(address): Address to querypaymentPeriodIdx_
(uint256): Payment period index
Returns:
uint256
: Unclaimed interest amount
claimedAmountForPeriod(address receiver_, uint256 periodIdx_) → uint256
Returns claimed interest amount for an account in a specific period.
Parameters:
receiver_
(address): Address to queryperiodIdx_
(uint256): Payment period index
Returns:
uint256
: Claimed interest amount
reclaimedAmountForPeriod(address receiver_, uint256 periodIdx_) → uint256
Returns reclaimed interest amount for an account in a specific period.
Parameters:
receiver_
(address): Address to queryperiodIdx_
(uint256): Payment period index
Returns:
uint256
: Reclaimed interest amount
accountTotalClaimedAmount(address receiver_) → uint256
Returns total claimed interest across all periods for an account.
Parameters:
receiver_
(address): Address to query
Returns:
uint256
: Total claimed amount
accountTotalReclaimedAmount(address receiver_) → uint256
Returns total reclaimed interest across all periods for an account.
Parameters:
receiver_
(address): Address to query
Returns:
uint256
: Total reclaimed amount
Contract State Functions
totalInterestAmountFunded() → uint256
Returns total amount of interest funds deposited.
Returns:
uint256
: Total funded interest amount
totalInterestAmountUnused() → uint256
Returns total unused (available for claims) interest amount.
Returns:
uint256
: Total unused interest amount
totalInterestAmountClaimed() → uint256
Returns total amount of interest claimed by users.
Returns:
uint256
: Total claimed interest amount
totalInterestAmountReclaimed() → uint256
Returns total amount of interest reclaimed by admin.
Returns:
uint256
: Total reclaimed interest amount
Principal Functions
fundedPrincipalAmount() → uint256
Returns total principal amount funded.
Returns:
uint256
: Total funded principal amount
claimedPrincipalAmount() → uint256
Returns total principal amount claimed.
Returns:
uint256
: Total claimed principal amount
reclaimedPrincipalAmount() → uint256
Returns total principal amount reclaimed.
Returns:
uint256
: Total reclaimed principal amount
totalAvailablePrincipalAmount() → uint256
Returns total available principal amount for claims.
Returns:
uint256
: Total available principal amount
availablePrincipalAmount(address account) → uint256
Returns available principal amount for a specific account.
Parameters:
account
(address): Address to query
Returns:
uint256
: Available principal amount for the account
Contract Configuration Functions
restrictedLockupToken() → address
Returns the RestrictedLockupToken contract address.
Returns:
address
: Token contract address
paymentToken() → address
Returns the payment token contract address.
Returns:
address
: Payment token contract address
principalAmountPerToken() → uint256
Returns the principal amount per token for maturity claims.
Returns:
uint256
: Principal amount per token
Utility Functions
nearestInterestPaymentTimestampAt(uint256 timestamp) → uint256
Returns the nearest valid interest payment timestamp.
Parameters:
timestamp
(uint256): Input timestamp
Returns:
uint256
: Nearest payment timestamp
findPaymentPeriodIndex(uint256 startTimestamp, uint256 endTimestamp) → uint256
Finds the index of a payment period with specific start/end timestamps.
Parameters:
startTimestamp
(uint256): Period start timestampendTimestamp
(uint256): Period end timestamp
Returns:
uint256
: Period index or type(uint256).max if not found
Dividend Query Functions
totalAwardedBalanceAt(address token_, address receiver_, uint256 timestamp_) → uint256
Returns total awarded dividend balance (claimed + unclaimed) for an account.
Parameters:
token_
(address): Dividend token addressreceiver_
(address): Address to querytimestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Total awarded balance
unclaimedBalanceAt(address token_, address receiver_, uint256 timestamp_) → uint256
Returns unclaimed dividend balance for an account at a timestamp.
Parameters:
token_
(address): Dividend token addressreceiver_
(address): Address to querytimestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Unclaimed dividend balance
claimedBalanceAt(address token_, address receiver_, uint256 timestamp_) → uint256
Returns claimed dividend balance for an account at a timestamp.
Parameters:
token_
(address): Dividend token addressreceiver_
(address): Address to querytimestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Claimed dividend balance
tokensAt(address token_, uint256 timestamp_) → uint256
Returns unused dividend tokens available for claims at a timestamp.
Parameters:
token_
(address): Dividend token addresstimestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Unused dividend token amount
fundsAt(address token_, uint256 timestamp_) → uint256
Returns total funded dividend amount for a token at a timestamp.
Parameters:
token_
(address): Dividend token addresstimestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Total funded dividend amount
totalSupplyAt(uint256 timestamp_) → uint256
Returns total token supply at a specific timestamp.
Parameters:
timestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Total supply at timestamp
balanceOfAt(address sender_, uint256 timestamp_) → uint256
Returns token balance of an address at a specific timestamp.
Parameters:
sender_
(address): Address to querytimestamp_
(uint256): Snapshot timestamp
Returns:
uint256
: Balance at timestamp
isAmountDivisible(uint256 amount_, uint256 timestamp_) → bool
Checks if an amount is divisible by total supply at a timestamp.
Parameters:
amount_
(uint256): Amount to checktimestamp_
(uint256): Snapshot timestamp
Returns:
bool
: True if amount is divisible by total supply
Events
Interest Payment Events
Funded(address indexed funder, uint256 amount)
Emitted when interest funds are deposited.
Parameters:
funder
(address, indexed): Address that funded the contractamount
(uint256): Amount of tokens funded
Claimed(address indexed claimer, uint256 amount, uint256 indexed periodIdx)
Emitted when interest is claimed by a user.
Parameters:
claimer
(address, indexed): Address that claimed interestamount
(uint256): Amount of interest claimedperiodIdx
(uint256, indexed): Payment period index
ForceClaimed(address indexed authority, address indexed wallet, uint256 amount, uint256 indexed periodIdx)
Emitted when interest is force claimed by admin.
Parameters:
authority
(address, indexed): Admin address that performed force claimwallet
(address, indexed): Wallet address that received the claimamount
(uint256): Amount of interest claimedperiodIdx
(uint256, indexed): Payment period index
Reclaimed(address indexed reclaimerAddress, address indexed wallet, uint256 amount, uint256 indexed periodIdx)
Emitted when interest is reclaimed from a wallet.
Parameters:
reclaimerAddress
(address, indexed): Address that received reclaimed fundswallet
(address, indexed): Wallet address funds were reclaimed fromamount
(uint256): Amount of interest reclaimedperiodIdx
(uint256, indexed): Payment period index
ReclaimedAll(address indexed reclaimerAddress, uint256 amount, uint256 indexed periodIdx)
Emitted when all remaining interest is reclaimed from a period.
Parameters:
reclaimerAddress
(address, indexed): Address that received reclaimed fundsamount
(uint256): Amount of interest reclaimedperiodIdx
(uint256, indexed): Payment period index (type(uint256).max for total reclaim)
Payment Period Events
PaymentPeriodCreated(address indexed authority, uint256 indexed periodIdx, uint256 startTimestamp, uint256 endTimestamp, uint256 interestRate)
Emitted when a new payment period is created.
Parameters:
authority
(address, indexed): Address that created the periodperiodIdx
(uint256, indexed): Index of the created periodstartTimestamp
(uint256): Period start timestampendTimestamp
(uint256): Period end timestampinterestRate
(uint256): Interest rate in basis points
InterestRateUpdated(address indexed authority, uint256 indexed periodIdx, uint256 interestRate)
Emitted when interest rate is updated for a period.
Parameters:
authority
(address, indexed): Address that updated the rateperiodIdx
(uint256, indexed): Payment period indexinterestRate
(uint256): New interest rate in basis points
PeriodPaused(address indexed authority, uint256 indexed periodIdx)
Emitted when a payment period is paused.
Parameters:
authority
(address, indexed): Address that paused the periodperiodIdx
(uint256, indexed): Payment period index
PeriodUnpaused(address indexed authority, uint256 indexed periodIdx)
Emitted when a payment period is unpaused.
Parameters:
authority
(address, indexed): Address that unpaused the periodperiodIdx
(uint256, indexed): Payment period index
Administrative Events
PaymentPausedAfter(uint256 timestamp)
Emitted when payments are paused after a timestamp.
Parameters:
timestamp
(uint256): Timestamp after which payments are paused
PaymentUnpausedAfter()
Emitted when payment pause timestamp is removed.
ReclaimerAddressChanged(address indexed authority, address indexed newReclaimerAddress)
Emitted when reclaimer address is changed.
Parameters:
authority
(address, indexed): Address that changed the reclaimernewReclaimerAddress
(address, indexed): New reclaimer address
InterestAccrualEndShifted(address indexed authority, uint256 newInterestAccrualEndTimestamp)
Emitted when interest accrual end timestamp is extended.
Parameters:
authority
(address, indexed): Address that shifted the end timestampnewInterestAccrualEndTimestamp
(uint256): New end timestamp
SetMaxInterestRate(address indexed authority, uint256 maxInterestRate)
Emitted when maximum interest rate is changed.
Parameters:
authority
(address, indexed): Address that set the max ratemaxInterestRate
(uint256): New maximum interest rate
EarlyRepayment(address indexed authority, uint256 timestamp)
Emitted when early repayment is triggered.
Parameters:
authority
(address, indexed): Address that triggered early repaymenttimestamp
(uint256): New maturity timestamp
Principal Events
PrincipalFunded(address indexed funder, uint256 amount)
Emitted when principal is funded.
Parameters:
funder
(address, indexed): Address that funded principalamount
(uint256): Amount of principal funded
PrincipalClaimed(address indexed claimer, uint256 amount)
Emitted when principal is claimed.
Parameters:
claimer
(address, indexed): Address that claimed principalamount
(uint256): Amount of principal claimed
PrincipalReclaimed(address indexed authority, uint256 amount)
Emitted when principal is reclaimed.
Parameters:
authority
(address, indexed): Address that reclaimed principalamount
(uint256): Amount of principal reclaimed
Dividend Events
DividendFunded(address indexed funder, address indexed token, uint256 amount, uint256 indexed timestamp)
Emitted when dividend is funded.
Parameters:
funder
(address, indexed): Address that funded the dividendtoken
(address, indexed): Dividend token addressamount
(uint256): Amount of dividend fundedtimestamp
(uint256, indexed): Snapshot timestamp
DividendClaimed(address indexed claimer, address indexed token, uint256 amount, uint256 indexed timestamp)
Emitted when dividend is claimed.
Parameters:
claimer
(address, indexed): Address that claimed dividendtoken
(address, indexed): Dividend token addressamount
(uint256): Amount of dividend claimedtimestamp
(uint256, indexed): Snapshot timestamp
Pausable Events
Paused(address account)
Emitted when contract is paused.
Parameters:
account
(address): Address that paused the contract
Unpaused(address account)
Emitted when contract is unpaused.
Parameters:
account
(address): Address that unpaused the contract
Custom Errors
Access Control Errors
EasyAccessControl_DoesNotHaveContractAdminRole(address addr)
Thrown when address lacks CONTRACT_ADMIN_ROLE.
Parameters:
addr
(address): Address that lacks the role
EasyAccessControl_DoesNotHaveTransferAdminRole(address addr)
Thrown when address lacks TRANSFER_ADMIN_ROLE.
Parameters:
addr
(address): Address that lacks the role
EasyAccessControl_DoesNotHaveContractOrTransferAdminRole(address addr)
Thrown when address lacks both CONTRACT_ADMIN_ROLE and TRANSFER_ADMIN_ROLE.
Parameters:
addr
(address): Address that lacks the roles
EasyAccessControl_InvalidZeroAddress()
Thrown when zero address is provided where valid address required.
Configuration Errors (API)
InterestPayment_InvalidRestrictedLockupTokenAddress()
Thrown when invalid token address provided in constructor.
InterestPayment_InvalidPaymentPeriodSeconds()
Thrown when payment period seconds is zero.
InterestPayment_InvalidInterestAccrualStartTimestamp()
Thrown when interest accrual start timestamp is zero.
InterestPayment_InvalidInterestAccrualEndTimestamp()
Thrown when interest accrual end timestamp is zero or invalid.
InterestPayment_InvalidInterestAccrualPeriod()
Thrown when start timestamp >= end timestamp.
InterestPayment_InvalidPrincipalAmountPerToken()
Thrown when principal amount per token is zero.
InterestPayment_InvalidPaymentToken()
Thrown when payment token address is zero.
InterestPayment_InvalidReclaimerAddress()
Thrown when reclaimer address is zero.
InterestPayment_InvalidTimestamp()
Thrown when invalid timestamp provided.
Payment Period Errors
InterestPayment_InvalidPeriod()
Thrown when referencing invalid period.
InterestPayment_InvalidPeriodIndex()
Thrown when period index is out of bounds.
InterestPayment_StartTimestampGreaterThanEndTimestamp()
Thrown when period start > end timestamp.
InterestPayment_StartTimestampBeforeAccrualStartTimestamp()
Thrown when period starts before overall accrual start.
InterestPayment_EndTimestampGreaterThanAccrualEndTimestamp()
Thrown when period ends after overall accrual end.
InterestPayment_PeriodDurationNotMultipleOfInterestRatePeriod()
Thrown when period duration doesn't align with interest rate period.
InterestPayment_PeriodAlreadyExists()
Thrown when attempting to create duplicate period.
InterestPayment_PeriodNotNext()
Thrown when period doesn't follow sequentially.
InterestPayment_NoPaymentPeriods()
Thrown when no payment periods exist.
InterestPayment_PaymentPeriodPaused(uint256 periodIdx)
Thrown when attempting operation on paused period.
Parameters:
periodIdx
(uint256): Index of paused period
InterestPayment_PeriodAlreadyStarted()
Thrown when trying to modify started period.
Interest Rate Errors
InterestPayment_InterestRateGreaterThanMaxInterestRate()
Thrown when interest rate exceeds maximum.
InterestPayment_InterestRateNotChanged()
Thrown when trying to set same interest rate.
InterestPayment_MaxInterestRateNotChanged()
Thrown when trying to set same max interest rate.
Funding and Claiming Errors (API)
InterestPayment_InvalidAmount()
Thrown when amount is zero or invalid.
InterestPayment_TokenSupplyIsZero()
Thrown when token supply is zero during operations.
InterestPayment_PrincipalAmountNotDivisibleByTokenSupply()
Thrown when principal amount not divisible by token supply.
InterestPayment_InvalidFeeApplied()
Thrown when unexpected fee applied during transfer.
InterestPayment_NoFundsToClaim()
Thrown when no funds available for claiming.
InterestPayment_NotEnoughFundsToClaim()
Thrown when insufficient funds for requested claim.
InterestPayment_InvalidUnclaimedAmount(uint256 claimableFunds, uint256 claimedFunds)
Thrown when unclaimed calculation is invalid.
Parameters:
claimableFunds
(uint256): Expected claimable amountclaimedFunds
(uint256): Actual claimed amount
InterestPayment_NotEnoughFundedPrincipal()
Thrown when insufficient principal funded.
InterestPayment_MaturityNotReached()
Thrown when trying to claim principal before maturity.
Pause/Unpause Errors
InterestPayment_PaymentNotPausedAfter()
Thrown when trying to unpause when not paused.
InterestPayment_CannotUnpauseAfterMaturity()
Thrown when trying to unpause after maturity.
InterestPayment_CannotReclaimAllForOngoingPeriod()
Thrown when trying to reclaim all from active period.
Dividend Errors
InterestPayment_InvalidDividendSnapshotId()
Thrown when dividend snapshot timestamp is invalid.
InterestPayment_NoRemainingUnclaimedDividendBalance()
Thrown when no unclaimed dividend balance exists.
InterestPayment_InvalidDividendTokenAddress()
Thrown when dividend token address is zero.
InterestPayment_InvalidTokenDecimals(uint8 restrictedLockupTokenDecimals)
Thrown when token decimals are incompatible.
Parameters:
restrictedLockupTokenDecimals
(uint8): RestrictedLockupToken decimals
InterestPayment_IndivisibleAmount(uint256 paymentTokenAmount, uint256 totalSupplyAt)
Thrown when dividend amount not divisible by total supply.
Parameters:
paymentTokenAmount
(uint256): Dividend amounttotalSupplyAt
(uint256): Total supply at timestamp
InterestPayment_InvalidUnclaimedDividendBalance(uint256 claimableFunds, uint256 claimedFunds)
Thrown when unclaimed dividend calculation is invalid.
Parameters:
claimableFunds
(uint256): Expected claimable dividend amountclaimedFunds
(uint256): Actual claimed dividend amount
InterestPayment_ZeroTotalSupply()
Thrown when total supply is zero at snapshot timestamp.
Pausable Errors
EnforcedPause()
Thrown when operation attempted while contract paused.
ExpectedPause()
Thrown when pause expected but contract not paused.