Replaced string panics with typed VaultError enum across the Callora Vault contract to enable machine-readable error handling for integrators using @stellar/stellar-sdk.
- Defined
#[contracterror]enum with 27 error codes (1-27) - Each error has a stable u32 code and descriptive name
- Covers all validation and authorization scenarios
- NotInitialized - Vault not initialized
- AlreadyInitialized - Vault already initialized
- Unauthorized - Caller not authorized
- Paused - Vault is paused
- InsufficientBalance - Insufficient balance
- AmountNotPositive - Amount must be positive
- ExceedsMaxDeduct - Exceeds max deduct limit
- BelowMinDeposit - Below minimum deposit
- Overflow - Arithmetic overflow
- InitialBalanceNegative - Initial balance negative
- MinDepositNotPositive - Min deposit not positive
- MaxDeductNotPositive - Max deduct not positive
- MinDepositExceedsMaxDeduct - Min deposit > max deduct
- UsdcTokenCannotBeVault - USDC token = vault address
- RevenuePoolCannotBeVault - Revenue pool = vault address
- AuthorizedCallerCannotBeVault - Authorized caller = vault address
- InitialBalanceExceedsOnLedger - Initial balance > on-ledger balance
- AlreadyPaused - Vault already paused
- NotPaused - Vault not paused
- SettlementNotSet - Settlement address not configured
- BatchEmpty - Batch deduct requires items
- BatchTooLarge - Batch exceeds max size
- NewOwnerSameAsCurrent - New owner same as current
- NoOwnershipTransferPending - No ownership transfer pending
- NoAdminTransferPending - No admin transfer pending
- OfferingIdTooLong - Offering ID too long
- MetadataTooLong - Metadata too long
All public entrypoints now return Result instead of panicking:
init()→Result<VaultMeta, VaultError>deposit()→Result<i128, VaultError>deduct()→Result<i128, VaultError>batch_deduct()→Result<i128, VaultError>withdraw()→Result<i128, VaultError>withdraw_to()→Result<i128, VaultError>distribute()→Result<(), VaultError>pause()→Result<(), VaultError>unpause()→Result<(), VaultError>set_admin()→Result<(), VaultError>accept_admin()→Result<(), VaultError>transfer_ownership()→Result<(), VaultError>accept_ownership()→Result<(), VaultError>set_authorized_caller()→Result<(), VaultError>set_max_deduct()→Result<(), VaultError>set_allowed_depositor()→Result<(), VaultError>clear_allowed_depositors()→Result<(), VaultError>set_revenue_pool()→Result<(), VaultError>set_settlement()→Result<(), VaultError>set_metadata()→Result<String, VaultError>update_metadata()→Result<String, VaultError>add_address()→Result<(), VaultError>clear_all()→Result<(), VaultError>
View functions:
get_meta()→Result<VaultMeta, VaultError>balance()→Result<i128, VaultError>get_admin()→Result<Address, VaultError>get_usdc_token()→Result<Address, VaultError>get_settlement()→Result<Address, VaultError>is_authorized_depositor()→Result<bool, VaultError>
Private helper functions now return Result:
require_owner()→Result<(), VaultError>require_authorized_deduct_caller()→Result<(), VaultError>require_settlement()→Result<Address, VaultError>require_not_paused()→Result<(), VaultError>require_admin_or_owner()→Result<(), VaultError>
Added comprehensive error codes section with:
- Error code number
- Error name
- Description
- Machine-Readable Errors: Integrators can branch on error codes instead of parsing strings
- Reduced WASM Size: Typed errors are more compact than string panics
- Better Developer Experience: Clear error codes with stable u32 values
- SDK Compatibility: Works seamlessly with @stellar/stellar-sdk error handling
The contract compiles successfully with cargo check. Pre-existing test issues are unrelated to this implementation:
- Tests reference non-existent methods (
remove_allowed_depositor,cancel_ownership_transfer,cancel_admin_transfer) - These are pre-existing issues in the test suite
The implementation uses typed errors which are more compact than string panics, contributing to reduced WASM size. The contract should still pass check-wasm-size.sh.
- All error paths maintain the same security guarantees as before
- No authorization bypasses introduced
- Arithmetic overflow still properly detected and returned as errors
- CEI (Checks-Effects-Interactions) pattern preserved
This is a breaking change for integrators:
- All functions now return
Resulttypes - Callers must handle errors explicitly
- Error codes are stable and documented
- Update test suite to handle
Resulttypes - Update integration tests to assert on specific error codes
- Verify WASM size with
check-wasm-size.sh - Update client SDK documentation with error code handling examples