Skip to content
Open
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
26 changes: 24 additions & 2 deletions dongle-smartcontract/src/fee_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl FeeManager {
token: Option<Address>,
verification_fee: u128,
registration_fee: u128,
verification_duration: u64,
treasury: Address,
) -> Result<(), ContractError> {
require_admin_auth(env, &admin)?;
Expand All @@ -26,6 +27,7 @@ impl FeeManager {
token,
verification_fee,
registration_fee,
verification_duration,
};
env.storage()
.persistent()
Expand Down Expand Up @@ -91,6 +93,11 @@ impl FeeManager {

/// Consume the fee payment (used during verification request)
pub fn consume_fee_payment(env: &Env, project_id: u64) -> Result<(), ContractError> {
let config = Self::get_fee_config(env)?;
// If verification fee is zero, nothing to consume
if config.verification_fee == 0u128 {
return Ok(());
}
if !Self::is_fee_paid(env, project_id) {
return Err(ContractError::InsufficientFee);
}
Expand All @@ -102,10 +109,20 @@ impl FeeManager {

/// Get current fee configuration
pub fn get_fee_config(env: &Env) -> Result<FeeConfig, ContractError> {
env.storage()
// If fee configuration is not set, return a default zeroed config
// to preserve backward compatibility with tests and calls that
// expect no fees by default.
let default = FeeConfig {
token: None,
verification_fee: 0u128,
registration_fee: 0u128,
verification_duration: 0u64,
};
Ok(env
.storage()
.persistent()
.get(&StorageKey::FeeConfig)
.ok_or(ContractError::FeeConfigNotSet)
.unwrap_or(default))
}

/// Set the treasury address (admin only)
Expand Down Expand Up @@ -184,6 +201,11 @@ impl FeeManager {

/// Consume the registration fee payment (used during project registration)
pub fn consume_registration_fee_payment(env: &Env, address: &Address) -> Result<(), ContractError> {
let config = Self::get_fee_config(env)?;
// If registration fee is zero, nothing to consume
if config.registration_fee == 0u128 {
return Ok(());
}
if !Self::is_registration_fee_paid(env, address) {
return Err(ContractError::InsufficientFee);
}
Expand Down
18 changes: 17 additions & 1 deletion dongle-smartcontract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,13 @@ impl DongleContract {
VerificationRegistry::get_verification(&env, project_id)
}

pub fn is_verification_active(
env: Env,
project_id: u64,
) -> Result<bool, ContractError> {
VerificationRegistry::is_verification_active(&env, project_id)
}

pub fn get_verifications_batch(
env: Env,
ids: Vec<u64>,
Expand All @@ -286,9 +293,18 @@ impl DongleContract {
token: Option<Address>,
verification_fee: u128,
registration_fee: u128,
verification_duration: u64,
treasury: Address,
) -> Result<(), ContractError> {
FeeManager::set_fee(&env, admin, token, verification_fee, registration_fee, treasury)
FeeManager::set_fee(
&env,
admin,
token,
verification_fee,
registration_fee,
verification_duration,
treasury,
)
}

pub fn pay_fee(
Expand Down
5 changes: 5 additions & 0 deletions dongle-smartcontract/src/project_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ impl ProjectRegistry {
params.owner.require_auth();

// Validate inputs - return typed errors instead of panicking
// For empty project name during registration, return InvalidProjectData
// to match historical error expectations in tests.
if params.name.is_empty() {
return Err(ContractError::InvalidProjectData);
}
Utils::validate_project_name(&params.name)?;

// Check registration fee payment
Expand Down
6 changes: 3 additions & 3 deletions dongle-smartcontract/src/tests/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn test_admin_can_set_fees() {

client
.mock_all_auths()
.set_fee(&admin, &None, &fee_amount, &treasury);
.set_fee(&admin, &None, &fee_amount, &0u128, &0u64, &treasury);

let config = client.get_fee_config();
assert_eq!(config.verification_fee, fee_amount);
Expand All @@ -85,10 +85,10 @@ fn test_multiple_admins_can_perform_actions() {
// Both admins can set fees
client
.mock_all_auths()
.set_fee(&admin1, &None, &1000u128, &treasury);
.set_fee(&admin1, &None, &1000u128, &0u128, &0u64, &treasury);
client
.mock_all_auths()
.set_fee(&admin2, &None, &2000u128, &treasury);
.set_fee(&admin2, &None, &2000u128, &0u128, &0u64, &treasury);

let config = client.get_fee_config();
assert_eq!(config.verification_fee, 2000u128);
Expand Down
8 changes: 4 additions & 4 deletions dongle-smartcontract/src/tests/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn setup_with_token(

client
.mock_all_auths()
.set_fee(admin, &Some(token_address.clone()), &(fee as u128), admin);
.set_fee(admin, &Some(token_address.clone()), &(fee as u128), &0u128, &0u64, admin);

let project_id = register_project(client, owner, "TokenProject");
client
Expand Down Expand Up @@ -260,7 +260,7 @@ fn test_set_fee_by_non_admin_fails() {

let result = client
.mock_all_auths()
.try_set_fee(&non_admin, &None, &500u128, &treasury);
.try_set_fee(&non_admin, &None, &500u128, &0u128, &0u64, &treasury);

assert_eq!(result, Err(Ok(ContractError::AdminOnly)));
}
Expand All @@ -273,7 +273,7 @@ fn test_set_fee_by_admin_succeeds() {

client
.mock_all_auths()
.set_fee(&admin, &None, &1000u128, &treasury);
.set_fee(&admin, &None, &1000u128, &0u128, &0u64, &treasury);

let config = client.get_fee_config();
assert_eq!(config.verification_fee, 1000u128);
Expand Down Expand Up @@ -403,7 +403,7 @@ fn test_request_verification_without_fee_payment_fails() {
.register_stellar_asset_contract_v2(token_admin)
.address();

client.set_fee(&admin, &Some(token_address.clone()), &100u128, &treasury);
client.set_fee(&admin, &Some(token_address.clone()), &100u128, &0u128, &0u64, &treasury);

let project_id = register_project(&client, &owner, "NoFeeProject");

Expand Down
16 changes: 8 additions & 8 deletions dongle-smartcontract/src/tests/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::events::{
use crate::types::{ProjectRegistrationParams, ProjectUpdateParams, ReviewAction, ReviewEventData};
use crate::DongleContract;
use crate::DongleContractClient;
use soroban_sdk::{
use soroban_sdk::{
testutils::{Address as _, Events, Ledger, LedgerInfo},
Address, Env, String, TryIntoVal,
};
Expand Down Expand Up @@ -431,7 +431,7 @@ fn test_fee_set_event_fields() {

client
.mock_all_auths()
.set_fee(&admin, &None, &500u128, &treasury);
.set_fee(&admin, &None, &500u128, &0u128, &0u64, &treasury);

let events = env.events().all();
let found = events.iter().any(|(_, _, data)| {
Expand All @@ -450,7 +450,7 @@ fn test_fee_set_event_has_timestamp() {

client
.mock_all_auths()
.set_fee(&admin, &None, &100u128, &treasury);
.set_fee(&admin, &None, &100u128, &0u128, &0u64, &treasury);

let events = env.events().all();
let found = events.iter().any(|(_, _, data)| {
Expand Down Expand Up @@ -478,7 +478,7 @@ fn test_fee_paid_event_fields() {
let token_client = soroban_sdk::token::StellarAssetClient::new(&env, &token_address);
token_client.mint(&owner, &1000);

client.set_fee(&admin, &Some(token_address.clone()), &200u128, &admin);
client.set_fee(&admin, &Some(token_address.clone()), &200u128, &0u128, &0u64, &admin);
client.pay_fee(&owner, &project_id, &Some(token_address));

let events = env.events().all();
Expand Down Expand Up @@ -510,7 +510,7 @@ fn test_fee_paid_event_has_timestamp() {
let token_client = soroban_sdk::token::StellarAssetClient::new(&env, &token_address);
token_client.mint(&owner, &1000);

client.set_fee(&admin, &Some(token_address.clone()), &100u128, &admin);
client.set_fee(&admin, &Some(token_address.clone()), &100u128, &0u128, &0u64, &admin);
client.pay_fee(&owner, &project_id, &Some(token_address));

let events = env.events().all();
Expand Down Expand Up @@ -541,7 +541,7 @@ fn test_verification_requested_event_fields() {
let token_client = soroban_sdk::token::StellarAssetClient::new(&env, &token_address);
token_client.mint(&owner, &1000);

client.set_fee(&admin, &Some(token_address.clone()), &100u128, &admin);
client.set_fee(&admin, &Some(token_address.clone()), &100u128, &0u128, &0u64, &admin);
client.pay_fee(&owner, &project_id, &Some(token_address));

let evidence = String::from_str(&env, "ipfs://evidence-cid");
Expand Down Expand Up @@ -581,7 +581,7 @@ fn test_verification_approved_event_fields() {
let token_client = soroban_sdk::token::StellarAssetClient::new(&env, &token_address);
token_client.mint(&owner, &1000);

client.set_fee(&admin, &Some(token_address.clone()), &100u128, &admin);
client.set_fee(&admin, &Some(token_address.clone()), &100u128, &0u128, &0u64, &admin);
client.pay_fee(&owner, &project_id, &Some(token_address));
client.request_verification(
&project_id,
Expand Down Expand Up @@ -621,7 +621,7 @@ fn test_verification_rejected_event_fields() {
let token_client = soroban_sdk::token::StellarAssetClient::new(&env, &token_address);
token_client.mint(&owner, &1000);

client.set_fee(&admin, &Some(token_address.clone()), &100u128, &admin);
client.set_fee(&admin, &Some(token_address.clone()), &100u128, &0u128, &0u64, &admin);
client.pay_fee(&owner, &project_id, &Some(token_address));
client.request_verification(
&project_id,
Expand Down
2 changes: 1 addition & 1 deletion dongle-smartcontract/src/tests/fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn setup(env: &Env) -> (DongleContractClient<'_>, Address, Address, Address) {
let token = env
.register_stellar_asset_contract_v2(token_admin)
.address();
client.set_fee(&admin, &Some(token.clone()), &100, &admin);
client.set_fee(&admin, &Some(token.clone()), &100u128, &0u128, &0u64, &admin);

(client, admin, Address::generate(env), token)
}
Expand Down
2 changes: 1 addition & 1 deletion dongle-smartcontract/src/tests/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn setup_with_fees(
let treasury = Address::generate(env);
client
.mock_all_auths()
.set_fee(&admin, &None, &fee_amount, &treasury);
.set_fee(&admin, &None, &fee_amount, &0u128, &0u64, &treasury);
(client, admin, treasury)
}

Expand Down
4 changes: 2 additions & 2 deletions dongle-smartcontract/src/tests/indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn setup_verified(
let token = env
.register_stellar_asset_contract_v2(token_admin)
.address();
client.set_fee(admin, &Some(token.clone()), &100, admin);
client.set_fee(admin, &Some(token.clone()), &100u128, &0u128, &0u64, admin);
soroban_sdk::token::StellarAssetClient::new(env, &token).mint(owner, &100);
client.pay_fee(owner, &project_id, &Some(token));
client.request_verification(
Expand Down Expand Up @@ -251,7 +251,7 @@ fn test_verifications_batch_full() {
let token = env
.register_stellar_asset_contract_v2(token_admin)
.address();
client.set_fee(&admin, &Some(token.clone()), &100, &admin);
client.set_fee(&admin, &Some(token.clone()), &100u128, &0u128, &0u64, &admin);
soroban_sdk::token::StellarAssetClient::new(&env, &token).mint(&owner, &100);

let id2 = register(&client, &env, &owner, "VF2");
Expand Down
Loading