Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
687 changes: 67 additions & 620 deletions contracts/teachlink/src/bridge.rs

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions contracts/teachlink/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Compile-time configuration constants for the TeachLink contract.

/// Fee configuration
pub mod fees {
pub const DEFAULT_FEE_RATE: u32 = 100; // 1% in basis points
pub const MAX_FEE_RATE: u32 = 10000; // 100% in basis points
pub const FEE_CALCULATION_DIVISOR: u32 = 10000;
}

/// Amount validation
pub mod amounts {
pub const MIN_AMOUNT: i128 = 1;
pub const FALLBACK_PRICE: i128 = 1_000_000; // 1 USD in 6 decimals
}

/// Chain configuration
pub mod chains {
pub const MIN_CHAIN_ID: u32 = 1;
pub const DEFAULT_MIN_CONFIRMATIONS: u32 = 3;
pub const MAX_CHAIN_NAME_LENGTH: u32 = 32;
}

/// Oracle configuration
pub mod oracle {
pub const MAX_CONFIDENCE: u32 = 100;
pub const DEFAULT_CONFIDENCE_THRESHOLD: u32 = 80;
pub const PRICE_FRESHNESS_SECONDS: u64 = 3600;
}

/// Storage limits
pub mod storage {
pub const MAX_BRIDGE_TXS: u32 = 1000;
pub const MAX_CHAIN_CONFIGS: u32 = 50;
pub const MAX_ORACLE_PRICES: u32 = 100;
}
201 changes: 69 additions & 132 deletions contracts/teachlink/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,139 +1,76 @@
use soroban_sdk::contracterror;
//! Error types and panic helper for the TeachLink contract.

/// Bridge module errors
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum BridgeError {
AlreadyInitialized = 100,
AmountMustBePositive = 101,
DestinationChainNotSupported = 102,
InsufficientValidatorSignatures = 103,
InvalidValidatorSignature = 104,
NonceAlreadyProcessed = 105,
TokenMismatch = 106,
BridgeTransactionNotFound = 107,
TimeoutNotReached = 108,
FeeCannotBeNegative = 109,
MinimumValidatorsMustBeAtLeastOne = 110,
// BFT Consensus Errors
ProposalNotFound = 111,
ProposalAlreadyVoted = 112,
ProposalExpired = 113,
InsufficientStake = 114,
InsufficientBalance = 115,
ValidatorNotActive = 116,
ByzantineThresholdNotMet = 117,
// Slashing Errors
ValidatorAlreadySlashed = 118,
InvalidSlashingEvidence = 119,
CannotSlashSelf = 120,
// Multi-Chain Errors
ChainNotActive = 121,
AssetNotSupported = 122,
InvalidChainConfiguration = 123,
// Liquidity Errors
InsufficientLiquidity = 124,
SlippageExceeded = 125,
InvalidLPAmount = 126,
// Emergency Errors
BridgePaused = 127,
ChainPaused = 128,
UnauthorizedPause = 129,
CircuitBreakerTriggered = 130,
// Message Passing Errors
PacketNotFound = 131,
PacketTimeout = 132,
InvalidPayload = 133,
// Atomic Swap Errors
SwapNotFound = 134,
InvalidHashlock = 135,
TimelockExpired = 136,
SwapAlreadyCompleted = 137,
// General Errors
Unauthorized = 138,
InvalidInput = 139,
RetryLimitExceeded = 140,
RetryBackoffActive = 141,
BridgeTransactionFailed = 142,
}
use soroban_sdk::{symbol_short, Env};

/// Escrow module errors
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum EscrowError {
AmountMustBePositive = 200,
AtLeastOneSignerRequired = 201,
InvalidSignerThreshold = 202,
RefundTimeMustBeInFuture = 203,
RefundTimeMustBeAfterReleaseTime = 204,
DuplicateSigner = 205,
SignerNotAuthorized = 206,
SignerAlreadyApproved = 207,
CallerNotAuthorized = 208,
InsufficientApprovals = 209,
ReleaseTimeNotReached = 210,
OnlyDepositorCanRefund = 211,
RefundNotEnabled = 212,
RefundTimeNotReached = 213,
OnlyDepositorCanCancel = 214,
CannotCancelAfterApprovals = 215,
OnlyDepositorOrBeneficiaryCanDispute = 216,
EscrowNotInDispute = 217,
OnlyArbitratorCanResolve = 218,
EscrowNotPending = 219,
EscrowNotFound = 220,
ArbitratorNotAuthorized = 221,
/// All recoverable error conditions in the contract.
#[derive(Clone, Debug)]
pub enum TeachLinkError {
Unauthorized,
InvalidAmount,
InvalidAddress,
ChainNotSupported,
RateLimitExceeded,
InsufficientBalance,
BridgeFailed,
NotInitialized,
InvalidChainId,
FeeTooHigh,
ChainExists,
InvalidPrice,
InvalidConfidence,
UnauthorizedOracle,
}

/// Rewards module errors
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum RewardsError {
AlreadyInitialized = 300,
AmountMustBePositive = 301,
InsufficientRewardPoolBalance = 302,
NoRewardsAvailable = 303,
NoPendingRewards = 304,
RateCannotBeNegative = 305,
}
/// Increment the error counter and panic with a descriptive symbol.
pub fn handle_error(env: &Env, error: TeachLinkError) -> ! {
use crate::storage::ERROR_COUNT;

/// Mobile platform module errors
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum MobilePlatformError {
DeviceNotSupported = 400,
InsufficientStorage = 401,
NetworkUnavailable = 402,
AuthenticationFailed = 403,
SyncFailed = 404,
PaymentFailed = 405,
SecurityViolation = 406,
FeatureNotAvailable = 407,
}
let mut count: u64 = env.storage().instance().get(&ERROR_COUNT).unwrap_or(0);
count += 1;
env.storage().instance().set(&ERROR_COUNT, &count);

/// Common errors that can be used across modules
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum CommonError {
Unauthorized = 400,
InvalidInput = 401,
InsufficientBalance = 402,
TransferFailed = 403,
StorageError = 404,
match error {
TeachLinkError::Unauthorized => {
env.panic_with_error_data(&symbol_short!("unauth"), "Unauthorized access")
}
TeachLinkError::InvalidAmount => {
env.panic_with_error_data(&symbol_short!("inv_amt"), "Invalid amount")
}
TeachLinkError::InvalidAddress => {
env.panic_with_error_data(&symbol_short!("inv_addr"), "Invalid address")
}
TeachLinkError::ChainNotSupported => {
env.panic_with_error_data(&symbol_short!("no_chain"), "Chain not supported")
}
TeachLinkError::RateLimitExceeded => {
env.panic_with_error_data(&symbol_short!("rate_lim"), "Rate limit exceeded")
}
TeachLinkError::InsufficientBalance => {
env.panic_with_error_data(&symbol_short!("no_bal"), "Insufficient balance")
}
TeachLinkError::BridgeFailed => {
env.panic_with_error_data(&symbol_short!("br_fail"), "Bridge operation failed")
}
TeachLinkError::NotInitialized => {
env.panic_with_error_data(&symbol_short!("no_init"), "Contract not initialized")
}
TeachLinkError::InvalidChainId => {
env.panic_with_error_data(&symbol_short!("inv_chn"), "Invalid chain ID")
}
TeachLinkError::FeeTooHigh => {
env.panic_with_error_data(&symbol_short!("fee_hi"), "Fee rate too high")
}
TeachLinkError::ChainExists => {
env.panic_with_error_data(&symbol_short!("chn_ex"), "Chain already exists")
}
TeachLinkError::InvalidPrice => {
env.panic_with_error_data(&symbol_short!("inv_prc"), "Invalid price")
}
TeachLinkError::InvalidConfidence => {
env.panic_with_error_data(&symbol_short!("inv_conf"), "Invalid confidence")
}
TeachLinkError::UnauthorizedOracle => {
env.panic_with_error_data(&symbol_short!("unauth_or"), "Unauthorized oracle")
}
}
}

/// Result type alias for bridge operations
#[allow(dead_code)]
pub type BridgeResult<T> = core::result::Result<T, BridgeError>;

/// Result type alias for escrow operations
#[allow(dead_code)]
pub type EscrowResult<T> = core::result::Result<T, EscrowError>;

/// Result type alias for rewards operations
#[allow(dead_code)]
pub type RewardsResult<T> = core::result::Result<T, RewardsError>;

/// Result type alias for common operations
#[allow(dead_code)]
pub type CommonResult<T> = core::result::Result<T, CommonError>;
Loading
Loading