Skip to content

[Smart Contracts] Add Validation for Negative or Zero Price Values in Agent Registration #150

Description

@devJaja

🎯 Objective

Add validation to prevent registration or pricing updates with negative or zero price_stroops values in the agent_registry Soroban contract. Currently, any i128 value is accepted.


📁 Files to Modify

Action File Path Description
Modify smart-contracts/contracts/agent_registry/src/lib.rs Add price validation to register_agent, register_agents, and update_pricing

📁 Reference Files

File Path Purpose
smart-contracts/contracts/agent_registry/src/lib.rs (line ~335) register_agent validation section
smart-contracts/contracts/agent_registry/src/lib.rs (line ~395) register_agents batch validation
smart-contracts/contracts/agent_registry/src/lib.rs (line ~479) update_pricing validation
smart-contracts/contracts/agent_registry/src/lib.rs (Error enum) Existing error variants

🔍 Current Vulnerable Code

register_agent (lib.rs ~line 335)

// CURRENT — No price validation
pub fn register_agent(env: Env, record: AgentParams) -> Result<(), Error> {
    // Validates: not paused, not frozen, owner auth
    // MISSING: price_stroops > 0 check
    // ...
}

update_pricing (lib.rs ~line 479)

// CURRENT — No price validation
pub fn update_pricing(
    env: Env,
    agent_id: Symbol,
    new_price: i128,
) -> Result<(), Error> {
    // Validates: agent exists, not paused, not frozen, owner auth
    // MISSING: new_price > 0 check
    // ...
}

💥 Impact

  • An agent could register with price_stroops = -1000 (effectively paying users)
  • The coordinator's cheapest-agent selection could be gamed
  • Zero-price agents could flood the registry with free services
  • Negative prices break economic assumptions in the payment layer

✅ Expected Fix

Add Error Variant (if not already present)

#[contracterror]
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Error {
    NotFound = 1,
    Unauthorized = 2,
    AlreadyExists = 3,
    ContractPaused = 4,
    AgentFrozen = 5,
    NotAdmin = 6,
    AlreadyResolved = 7,
    DuplicateInBatch = 8,
    InvalidPrice = 9,        // ADD THIS
}

Add Validation in register_agent

if record.price_stroops <= 0 {
    return Err(Error::InvalidPrice);
}

Add Validation in update_pricing

if new_price <= 0 {
    return Err(Error::InvalidPrice);
}

🧪 Tests to Add

#[test]
fn register_rejects_zero_price() {
    // Register with price_stroops = 0 → should return Error::InvalidPrice
}

#[test]
fn register_rejects_negative_price() {
    // Register with price_stroops = -100 → should return Error::InvalidPrice
}

#[test]
fn update_pricing_rejects_zero_price() {
    // Update to price_stroops = 0 → should return Error::InvalidPrice
}

#[test]
fn update_pricing_rejects_negative_price() {
    // Update to price_stroops = -50 → should return Error::InvalidPrice
}

✅ Acceptance Criteria

  • Add InvalidPrice = 9 variant to the Error enum in lib.rs
  • Add price_stroops <= 0 check in register_agent → return Error::InvalidPrice
  • Add price_stroops <= 0 check in register_agents batch validation
  • Add new_price <= 0 check in update_pricing → return Error::InvalidPrice
  • Add 4 unit tests (zero/negative for register and update)
  • Run cargo test — all tests pass

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions