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
124 changes: 114 additions & 10 deletions contracts/predictify-hybrid/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,25 @@ impl InputValidator {
Ok(())
}

/// Validate string length with both min and max limits
pub fn validate_string_length_range(
input: &String,
min_length: u32,
max_length: u32,
) -> Result<(), ValidationError> {
let length = input.len() as u32;

if length < min_length {
return Err(ValidationError::StringTooShort);
}

if length > max_length {
return Err(ValidationError::StringTooLong);
}

Ok(())
}

/// Validate numeric range for all parameters
pub fn validate_numeric_range(
value: i128,
Expand All @@ -1028,16 +1047,16 @@ impl InputValidator {

/// Validate address format and validity
pub fn validate_address_format(address: &Address) -> Result<(), ValidationError> {
//this is called, Soroban host performs the necessary
// authentication, manages replay prevention and enforces the user's
// authorization policies.
address.require_auth();

// Basic address validation - Soroban SDK handles the actual format validation
// We just need to ensure the address is not null/empty
// The address format is validated by the Soroban SDK when created
Ok(())
}

pub fn validate_address(address: &Address, env: &Env) -> Result<(), ValidationError> {
address.require_auth_for_args(vec![env, address.into_val(env)]);
/// Validate address with environment context
pub fn validate_address(env: &Env, address: &Address) -> Result<(), ValidationError> {
// Soroban SDK validates address format during creation
// Additional validation can be added here if needed
Ok(())
}

Expand Down Expand Up @@ -1185,6 +1204,91 @@ impl InputValidator {

Ok(())
}

/// Comprehensive input validation struct with all validation methods
pub fn validate_all_inputs(
env: &Env,
admin: &Address,
question: &String,
outcomes: &Vec<String>,
duration_days: u32,
stake_amount: i128,
) -> Result<(), ValidationError> {
// Validate admin address
Self::validate_address(env, admin)?;

// Validate question format
Self::validate_question_format(question)?;

// Validate outcomes array
Self::validate_array_size(outcomes, config::MAX_MARKET_OUTCOMES)?;

// Validate each outcome format
for outcome in outcomes.iter() {
Self::validate_outcome_format(&outcome)?;
}

// Validate duration
Self::validate_duration(&duration_days)?;

// Validate stake amount
Self::validate_positive_number(&stake_amount)?;
Self::validate_numeric_range(stake_amount, config::MIN_VOTE_STAKE, i128::MAX)?;

Ok(())
}

/// Validate comprehensive market creation parameters
pub fn validate_market_creation_comprehensive(
env: &Env,
admin: &Address,
question: &String,
outcomes: &Vec<String>,
duration_days: u32,
oracle_threshold: Option<i128>,
) -> ValidationResult {
let mut result = ValidationResult::valid();

// Validate admin address
if Self::validate_address(env, admin).is_err() {
result.add_error();
}

// Validate question
if Self::validate_question_format(question).is_err() {
result.add_error();
} else if question.len() < 20 {
result.add_warning(); // Question is quite short
}

// Validate outcomes
if Self::validate_array_size(outcomes, config::MAX_MARKET_OUTCOMES).is_err() {
result.add_error();
} else {
for outcome in outcomes.iter() {
if Self::validate_outcome_format(&outcome).is_err() {
result.add_error();
break;
}
}
}

// Validate duration
if Self::validate_duration(&duration_days).is_err() {
result.add_error();
} else if duration_days < 7 {
result.add_recommendation(); // Consider longer duration
}

// Validate oracle threshold if provided
if let Some(threshold) = oracle_threshold {
if Self::validate_positive_number(&threshold).is_err() {
result.add_error();
}
}

result
}
}

// ===== MARKET VALIDATION =====
Expand Down Expand Up @@ -2410,12 +2514,12 @@ impl ConfigValidator {
token_id: &Address,
) -> Result<(), ValidationError> {
// Validate admin address
if let Err(_) = InputValidator::validate_address(admin, env) {
if let Err(_) = InputValidator::validate_address(env, admin) {
return Err(ValidationError::InvalidConfig);
}

// Validate token address
if let Err(_) = InputValidator::validate_address(token_id, env) {
if let Err(_) = InputValidator::validate_address(env, token_id) {
return Err(ValidationError::InvalidConfig);
}

Expand Down Expand Up @@ -2606,7 +2710,7 @@ impl ComprehensiveValidator {
let mut result = ValidationResult::valid();

// Validate admin
if let Err(_) = InputValidator::validate_address(admin, env) {
if let Err(_) = InputValidator::validate_address(env, admin) {
result.add_error();
}

Expand Down
Loading
Loading