Skip to content

Latest commit

 

History

History
272 lines (222 loc) · 13.4 KB

File metadata and controls

272 lines (222 loc) · 13.4 KB

ContractError Taxonomy — Recovery Actions by Category

Grouped reference for SDK clients, indexers, and front-end integrators. Each category names its variants, explains when the contract raises them, and prescribes an SDK-side recovery action the caller can take.

Categories are also available as a stable #[repr(u32)] enum — ContractErrorCategory — with ContractError::category() to map any error to its category at runtime.

Source of truth: contracts/credit/src/types.rs. Cross-reference: docs/ERROR_CODES.md (categorized reference with recovery actions).


Auth (codes 1, 2, 32)

Code Variant When raised
1 Unauthorized Caller is not the expected Address for the operation.
2 NotAdmin Caller invoked an admin-only entrypoint without admin privileges.
32 AdminNotInitialized Admin address has not been set in contract storage.

Recovery action: Prompt the caller to re-connect a wallet with the correct role. For AdminNotInitialized, advise the deployer to call init() with a valid admin address before any admin-gated operation.


Lifecycle (codes 4, 14, 20, 21, 51)

Code Variant When raised
4 CreditLineClosed Action attempted on a permanently closed credit line.
14 AlreadyInitialized init() called more than once.
20 CreditLineSuspended Draw or admin action on a suspended credit line.
21 CreditLineDefaulted Draw or admin action on a defaulted credit line.
51 AlreadySettled The liquidation for this (borrower, settlement_id) pair has already been processed.

Recovery action:

  • CreditLineClosed: No recovery — the line is terminal. Create a new credit line.
  • AlreadyInitialized: No action needed (contract is already live).
  • AlreadySettled: No action needed — the settlement has already been processed.
  • CreditLineSuspended: Wait for admin reinstatement or self-reinstatement (see lifecycle.rs); repayments are still allowed.
  • CreditLineDefaulted: The line is in default; the borrower must either cure via repayment or the position must be liquidated through the auction contract.

Numeric (codes 5, 7, 12, 33, 34, 52)

Code Variant When raised
5 InvalidAmount Amount is zero, negative, or malformed where a positive value was required.
7 NegativeLimit Attempt to set a credit limit below zero.
12 Overflow Arithmetic overflow during checked math (e.g., interest proration, limit
calculation).
33 TimestampRegression Provided or ledger timestamp is not strictly greater than the stored value.
34 LimitOutOfBounds Credit limit falls outside the configured [min_limit, max_limit] range.
52 InvalidRiskWeight Collateral risk weight exceeds 10 000 bps (100 %).

Recovery action:

  • InvalidAmount: Re-validate inputs client-side — ensure draw/repay amounts are positive integers within bounds.
  • NegativeLimit: Clamp or reject the limit value before sending.
  • Overflow: This indicates an arithmetic failure at the protocol level. Retry with a smaller amount or under different rate/accrual conditions; if persistent, file a bug report.
  • TimestampRegression: Likely a client clock issue. Re-sync the caller's ledger view and retry.
  • LimitOutOfBounds: Adjust the proposed limit to [min_limit, max_limit] using get_protocol_config().
  • InvalidRiskWeight: Ensure risk weight is in 0..=10_000 bps.

Limit (codes 6, 10, 13, 17, 28, 45, 47)

Code Variant When raised
6 OverLimit Draw would exceed the borrower's credit limit minus utilized amount.
10 UtilizationNotZero Operation (e.g., limit decrease, closure) requires zero outstanding debt.
13 LimitDecreaseRequiresRepayment Credit limit decrease below the currently utilized amount.
17 DrawExceedsMaxAmount Draw amount exceeds the per-transaction max_draw_amount.
28 RepayExceedsMaxAmount Repay amount exceeds the per-transaction max_repay_amount.
45 CloseFactorAboveMax Supplied close_factor_bps exceeds the protocol-configured maximum.
47 DrawReversalWindowExpired Draw reversal attempted after the allowed reversal window elapsed.

Recovery action:

  • OverLimit: Reduce the draw amount to ≤ credit_limit - utilized. Query get_credit_line(borrower) to compute the available headroom.
  • UtilizationNotZero: Repay the outstanding balance first, then retry the operation.
  • LimitDecreaseRequiresRepayment: Repay the excess above the new limit before decreasing.
  • DrawExceedsMaxAmount / RepayExceedsMaxAmount: Split the transaction into smaller chunks or query max_draw_amount / max_repay_amount from protocol config and adjust the input.
  • CloseFactorAboveMax: Reduce close_factor_bps to ≤ the protocol max.
  • DrawReversalWindowExpired: Reversal no longer possible; the window has passed.

Liquidity (codes 22, 23, 24, 25, 26, 27, 30, 31, 41)

Code Variant When raised
22 MissingLiquidityToken Liquidity token address is not configured.
23 MissingLiquiditySource Liquidity source contract is not configured.
24 InsufficientLiquidityReserve The reserve pool cannot cover the requested draw.
25 LiquidityTokenCallFailed An external call to the liquidity token reverted or returned an error
where the contract can observe it.
26 InsufficientRepaymentAllowance Borrower's token allowance is below the effective repayment amount.
27 InsufficientRepaymentBalance Borrower's token balance is below the effective repayment amount.
30 TreasuryNotSet Treasury address is not configured when attempting a treasury withdrawal.
31 ExposureCapExceeded Draw would push global TotalUtilized above MaxTotalExposure.
41 BountyNotSet Bounty pool address is not configured.

Recovery action:

  • MissingLiquidityToken / MissingLiquiditySource: Inform the admin to complete liquidity configuration; the protocol is not yet operational.
  • InsufficientLiquidityReserve: Wait for the reserve to be replenished, or request admin to add liquidity.
  • LiquidityTokenCallFailed: Retry the transaction. If the token contract is genuinely faulty, the admin must replace it.
  • InsufficientRepaymentAllowance: Guide the borrower to increase the allowance for the contract address.
  • InsufficientRepaymentBalance: Guide the borrower to deposit more tokens into their wallet.
  • TreasuryNotSet: Admin must call set_treasury before withdrawing.
  • ExposureCapExceeded: Reduce the draw amount or wait for other borrowers to repay so the global cap frees headroom.
  • BountyNotSet: Admin must call set_bounty before withdrawing.

Risk (codes 8, 9, 18, 29)

Code Variant When raised
8 RateTooHigh Interest rate change exceeds max_rate_change_bps or the absolute ceiling.
9 ScoreTooHigh Risk score exceeds the maximum allowed (100).
18 Paused Protocol is paused by the emergency circuit breaker.
29 DrawCooldownActive Borrower attempted to draw before draw_min_interval_seconds elapsed.

Recovery action:

  • RateTooHigh: Clamp the rate change within RateChangeConfig bounds. Query get_rate_change_config() for max_rate_change_bps.
  • ScoreTooHigh: Normalize the risk score to [0, 100] before submitting.
  • Paused: Inform the user that the protocol is paused. Repayments are still accepted. Retry when the admin unpauses.
  • DrawCooldownActive: Wait draw_min_interval_seconds from the last draw timestamp (available via get_credit_line(borrower).last_accrual_ts) before retrying.

Oracle (codes 36, 37, 38, 50)

Code Variant When raised
36 OraclePriceInvalid Oracle price is zero, negative, or malformed.
37 OraclePriceStale Oracle price exceeds max_age_seconds since last update.
38 OraclePriceDeviation Oracle price deviation exceeds max_deviation_bps relative to prior.
50 OracleQuorumNotMet Fewer than min_quorum_k prices agree within the deviation bound.

Recovery action:

  • OraclePriceInvalid: Ensure the oracle is returning a valid positive price.
  • OraclePriceStale: Wait for an oracle price update, or trigger one via the oracle's push mechanism.
  • OraclePriceDeviation: Circuit-breaker tripped; await a new price within the deviation bound. Do not retry with the same price.
  • OracleQuorumNotMet: Submit prices from more independent oracle feeds.

Collateral (codes 35, 39, 50)

Code Variant When raised
35 CollateralRatioBelowMinimum Collateral withdraw would leave the ratio below MinCollateralRatioBps.
39 InsufficientCollateralBalance Withdrawal amount exceeds the borrower's deposited collateral balance.
50 CollateralInsufficient Collateral is insufficient for the requested operation (general semantic).

Recovery action: For code 35, reduce the withdrawal amount so that (post_collateral * MinCollateralRatioBps) / 10_000 >= utilized. Query the minimum collateral ratio via get_protocol_config() and compute the maximum safe withdrawal client-side. For code 39, query get_collateral_balance and ensure the requested amount does not exceed it. For code 50, deposit additional collateral or reduce the requested operation size until collateral coverage is adequate.


Block (codes 16, 19, 40, 46)

Code Variant When raised
16 BorrowerBlocked Borrower is on the admin-managed block list.
19 DrawsFrozen Global draw freeze is active (admin action for liquidity reserve ops).
40 BorrowerFrozen Borrower's draws are temporarily frozen until the specified expiry timestamp.
46 CreditLineFrozen Credit line draws are frozen by admin (compliance or investigation hold).

Recovery action:

  • BorrowerBlocked: The borrower is permanently blocked. No recovery from the SDK side; the borrower must contact the protocol admin.
  • DrawsFrozen: Inform the user that draws are temporarily frozen. Repayments remain open. Retry when the admin unfreezes.
  • BorrowerFrozen: Wait for the freeze to expire (or contact the admin to unfreeze early). The freeze is time-bounded and auto-expires.
  • CreditLineFrozen: Admin-compliance hold; wait for unfreeze_credit_line.

Reentrancy (code 11)

Code Variant When raised
11 Reentrancy Reentrant call detected during a cross-contract transfer.

Recovery action: Do not retry the same transaction — the reentrancy guard prevents the contract from being called again during an ongoing operation. Wait for the current transaction to resolve and inspect the on-chain state before submitting a new call.


Misc (codes 3, 15, 42, 43, 44, 48, 49)

Code Variant When raised
3 CreditLineNotFound The specified borrower has no credit line.
15 AdminAcceptTooEarly Admin acceptance attempted before the propose_admin delay elapsed.
42 NoPendingTreasuryWithdrawal No pending treasury withdrawal proposal exists.
43 TreasuryTimelockActive The 24-hour treasury timelock has not elapsed.
44 TreasuryProposalExists A treasury withdrawal proposal already exists.
48 OriginalDrawNotFound Original draw audit record not found for reversal.
49 AttestationBatchNotFound No attestation batch has been committed for this borrower.
53 InvalidAttestation Attestation proof is invalid or no batch committed.

Recovery action:

  • CreditLineNotFound: Create a credit line first via open_credit_line.
  • AdminAcceptTooEarly: Wait for the full delay window to elapse.
  • NoPendingTreasuryWithdrawal: Create a proposal via propose_treasury_withdrawal.
  • TreasuryTimelockActive: Wait for the 24-hour timelock.
  • TreasuryProposalExists: Execute or cancel the existing proposal first.
  • OriginalDrawNotFound: No reversal possible — no matching draw record.
  • AttestationBatchNotFound: Admin must commit a batch first.

Quick reference: category summary

Category Codes Count Dominant SDK recovery
Auth 1, 2, 32 3 Reconnect wallet / re-deploy with admin init
Lifecycle 4, 14, 20, 21, 51 5 Await admin action or create new line
Numeric 5, 7, 12, 33, 34, 52 6 Validate inputs / re-sync ledger view
Limit 6, 10, 13, 17, 28, 45, 47 7 Reduce amount or repay first
Liquidity 22, 23, 24, 25, 26, 27, 30, 31, 41 9 Replenish allowance / wait for reserve
Risk 8, 9, 18, 29 4 Clamp inputs / wait for cooldown or unpause
Oracle 36, 37, 38, 50 4 Await valid price feed
Collateral 35, 39 2 Reduce withdrawal amount
Block 16, 19, 40, 46 4 Contact admin or wait for unfreeze / expiry
Reentrancy 11 1 Do not retry; inspect on-chain state
Misc 3, 15, 42, 43, 44, 48, 49 7 Create line first / wait for delay
Total 1–52 52