-
Notifications
You must be signed in to change notification settings - Fork 1
Develop #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Develop #147
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
fix: replace hard codded project name
Feat/landing page redesign
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (9)
stellar/contract/round/src/test.rs (2)
2166-2283
: Test for referrer fee calculations has commented assertions.The test verifies referrer deposits work correctly, but contains commented-out assertions that should be either fixed and uncommented, or removed entirely.
let deposit_without_referrer = round.get_deposits_for_round(&1, &None, &None); let deposit_without_referrer = deposit_without_referrer.first().unwrap(); assert_eq!(deposit_without_referrer.referrer_fee, 0); - // assert_eq!( - // deposit_without_referrer.net_amount as u128, - // amount.saturating_sub(calculate_protocol_fee(&env, amount).unwrap()) - // );assert_eq!(deposit_with_referrer.referrer_fee as u128, expected_referrer_fee); - // assert_eq!( - // deposit_with_referrer.net_amount as u128, - // amount.saturating_sub(calculate_protocol_fee(&env, amount).unwrap()).saturating_sub(expected_referrer_fee) - // );
2285-2380
:⚠️ Potential issueCritical security feature lacks committed tests.
The commented-out two-step ownership transfer test is concerning. The comment "function names have to be shortened to test, did that locally" suggests that tests for this critical security feature have been run locally but not integrated into the continuous integration process.
Ownership transfer is a sensitive operation that should have automated tests in the repository. Please integrate the locally tested functionality into the codebase with proper test coverage.
stellar/contract/round/src/validation.rs (2)
142-144
: Corrected voting period validation logicThe condition for checking if voting has started has been modified from
>
to>=
.This change fixes a critical edge case where voting would be allowed exactly at the start time. The previous implementation would have allowed voting before the official start time if a transaction was processed at exactly the start timestamp. This ensures the validation is precise.
223-232
: 🛠️ Refactor suggestionCheck for mismatched
_use_whitelist_voting
vs function usage.This function assumes
round.voting_wl_list_id
is always set. If the caller invokesvalidate_voting_whitelist
without verifyinguse_whitelist_voting
is enabled,.unwrap()
could panic. Include a defensive check or ensure the function is only called whenuse_whitelist_voting
is true.+ if !round.use_whitelist_voting { + panic_with_error!(env, RoundError::WhitelistNotEnabled); + } let list_id = round.voting_wl_list_id.unwrap();stellar/contract/round/src/internal.rs (5)
313-326
: Error handling needed in KYC whitelist change function.Just like in the initialization, the call to
list_client.get_list()
lacks proper error handling in thechange_kyc_wl_list_id
function.Implement proper error handling similar to the suggestion for the initialization function:
let list_client = ListsClient::new(env, &config.list_contract); -let valid_list = list_client.get_list(&list_id); -assert!(valid_list.id == list_id, "Invalid voting whitelist list id"); +match list_client.try_get_list(&list_id) { + Ok(valid_list) => { + assert!(valid_list.id == list_id, "Invalid KYC whitelist list id"); + }, + Err(_) => panic_with_error!(env, Error::InvalidWhitelistId), +}
1042-1054
:⚠️ Potential issueUnsafe unwrap in whitelist_status function.
The
whitelist_status
function unwrapsround.voting_wl_list_id
without checking if it'sNone
, which could cause a panic.Handle the potential None case:
fn whitelist_status(env: &Env, round_id: u128, address: Address) -> bool { let round = read_round_info(env, round_id); - let list_id = round.voting_wl_list_id.unwrap(); + if round.voting_wl_list_id.is_none() { + return false; + } + let list_id = round.voting_wl_list_id.unwrap(); let list_contract = read_config(env).list_contract; let list_client = ListsClient::new(env, &list_contract); let is_whitelisted = list_client.is_registered( &Some(list_id), &address, &Some(RegistrationStatus::Approved), ); is_whitelisted }
107-114
: 🛠️ Refactor suggestionWhitelist validation needs error handling.
The call to
list_client.get_list()
lacks proper error handling. If the list doesn't exist or there are other issues, this will panic with a generic error instead of a specific error message.Implement proper error handling:
if kyc_wl_list_id.is_some() { let list_client = ListsClient::new(env, &list_address); - let valid_list = list_client.get_list(&kyc_wl_list_id.unwrap()); - assert!( - valid_list.id == kyc_wl_list_id.unwrap(), - "Invalid voting whitelist list id" - ); + // Using a try-catch pattern with match to handle potential errors + match list_client.try_get_list(&kyc_wl_list_id.unwrap()) { + Ok(valid_list) => { + assert!(valid_list.id == kyc_wl_list_id.unwrap(), "Invalid KYC whitelist list id"); + }, + Err(_) => panic_with_error!(env, Error::InvalidWhitelistId), + } }
855-859
: 🛠️ Refactor suggestionAdd logging for skipped payments when project not found.
When a payout is skipped because the project is not found, there's no logging to indicate this happened.
Add explicit logging:
if project.is_none() { + log!("Skipping payment for project ID {} as it was not found in registry", project_id); payout.paid_at_ms = Some(get_ledger_second_as_millis(env)); write_payout_info(env, payout_id, &payout); return; }
870-877
: 🛠️ Refactor suggestionAdd explicit logging for skipped KYC payments.
When a payout is skipped due to failed KYC verification, there's no logging to indicate this happened, which could lead to confusion and debugging difficulties.
Add explicit logging:
if !is_kyc_passed { + log!("Skipping payment to {} due to failed KYC verification", project_owner); if round.compliance_end_ms.unwrap_or(0) < get_ledger_second_as_millis(env) { + log!("Compliance period has ended, marking payment as processed without transfer"); payout.paid_at_ms = Some(get_ledger_second_as_millis(env)); write_payout_info(env, payout_id, &payout); } return; }
🧹 Nitpick comments (4)
stellar/contract/round/src/internal.rs (4)
1294-1313
: Duplicate whitelist validation code needs refactoring.The validation code for both voting and application whitelist IDs is nearly identical and should be refactored into a shared function to avoid duplication.
Create a helper function for whitelist ID validation:
+fn validate_whitelist_id(env: &Env, list_contract: &Address, list_id: u128, error_message: &str) { + let list_client = ListsClient::new(env, list_contract); + match list_client.try_get_list(&list_id) { + Ok(valid_list) => { + assert!(valid_list.id == list_id, "{}", error_message); + }, + Err(_) => panic_with_error!(env, Error::InvalidWhitelistId), + } +} // Then use it in the update_round function: if let Some(voting_wl_list_id) = round_detail.voting_wl_list_id { - let list_client = ListsClient::new(env, &read_config(env).list_contract); - let valid_list = list_client.get_list(&voting_wl_list_id); - assert!( - valid_list.id == voting_wl_list_id, - "Invalid voting whitelist list id" - ); + validate_whitelist_id(env, &read_config(env).list_contract, voting_wl_list_id, "Invalid voting whitelist list id"); round.voting_wl_list_id = Some(voting_wl_list_id); } if let Some(application_wl_list_id) = round_detail.application_wl_list_id { - let list_client = ListsClient::new(env, &read_config(env).list_contract); - let valid_list = list_client.get_list(&application_wl_list_id); - assert!( - valid_list.id == application_wl_list_id, - "Invalid application whitelist list id" - ); + validate_whitelist_id(env, &read_config(env).list_contract, application_wl_list_id, "Invalid application whitelist list id"); round.application_wl_list_id = Some(application_wl_list_id); }
701-713
: Improved duplicate pick detection.The code uses a vector to track seen pairs, which is fine for small numbers of picks, but could be inefficient for larger numbers.
Consider using a Map (or equivalent hash-based structure) for more efficient lookups:
-let mut seen_pairs: Vec<u32> = Vec::new(env); +let mut seen_pairs: Map<u32, bool> = Map::new(env); picks.iter().for_each(|picked_pair| { let picked_index = picked_pair.pair_id; if picked_index >= total_available_pairs { panic_with_error!(env, Error::IndexOutOfBound); } - if seen_pairs.contains(picked_index) { + if seen_pairs.contains_key(picked_index) { panic_with_error!(env, VoteError::DuplicatePick); } - seen_pairs.push_back(picked_pair.pair_id); + seen_pairs.set(picked_pair.pair_id, true);
1692-1700
: Inefficient payout retrieval inget_payouts
function.The current implementation loops through sequential payout IDs and breaks when one is not found. This is inefficient for sparse payout IDs and could lead to incorrect results if IDs aren't sequential.
Consider using a more explicit storage method that maintains a list of valid payout IDs:
fn get_payouts(env: &Env, from_index: Option<u64>, limit: Option<u64>) -> Vec<Payout> { let default_page_size = read_config(env).default_page_size; let limit_internal: u64 = limit.unwrap_or(default_page_size); let from_index_internal: u64 = from_index.unwrap_or(0); let mut payouts_external: Vec<Payout> = Vec::new(env); - for i in from_index_internal..limit_internal { - let payout = read_payout_info(env, i as u32); - - if payout.is_none() { - break; - } - - payouts_external.push_back(payout.unwrap().clone()); - } + // Get all payout IDs + let payout_ids = read_all_payout_ids(env); + + // Apply pagination + payout_ids.iter() + .skip(from_index_internal as usize) + .take(limit_internal as usize) + .for_each(|payout_id| { + let payout = read_payout_info(env, *payout_id); + if let Some(payout_info) = payout { + payouts_external.push_back(payout_info.clone()); + } + }); payouts_external }This would require adding a new function to read all payout IDs from storage.
912-940
: Improve error handling in can_vote function.The
can_vote
function returns false in several scenarios (blacklisted, whitelist required but missing, user not on whitelist) without providing a way to distinguish between these cases.Consider returning a structured result instead of a boolean:
-fn can_vote(env: &Env, round_id: u128, voter: Address) -> bool { +fn can_vote(env: &Env, round_id: u128, voter: Address) -> (bool, Option<String>) { let round = read_round_info(env, round_id); let current_ms = get_ledger_second_as_millis(env); if round.voting_start_ms <= current_ms && current_ms <= round.voting_end_ms { let is_blacklisted = is_blacklisted(env, round_id, voter.clone()); if is_blacklisted { - return false; + return (false, Some("Voter is blacklisted".into())); } if round.use_whitelist_voting { if round.voting_wl_list_id.is_none() { - return false; + return (false, Some("Whitelist ID not configured".into())); } let list_id = round.voting_wl_list_id.unwrap(); let list_contract = read_config(env).list_contract; let list_client = ListsClient::new(env, &list_contract); let is_whitelisted = list_client.is_registered( &Some(list_id), &voter, &Some(RegistrationStatus::Approved), ); - return is_whitelisted; + return (is_whitelisted, if is_whitelisted { None } else { Some("Voter not whitelisted".into()) }); } - return true; + return (true, None); } - false + (false, Some("Voting period not active".into())) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
stellar/contract/build/round.wasm
is excluded by!**/*.wasm
stellar/contract/build/round_opt.wasm
is excluded by!**/*.wasm
📒 Files selected for processing (6)
stellar/contract/round/src/core.rs
(1 hunks)stellar/contract/round/src/data_type.rs
(8 hunks)stellar/contract/round/src/error.rs
(4 hunks)stellar/contract/round/src/internal.rs
(52 hunks)stellar/contract/round/src/test.rs
(54 hunks)stellar/contract/round/src/validation.rs
(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- stellar/contract/round/src/data_type.rs
🧰 Additional context used
🧬 Code Graph Analysis (2)
stellar/contract/round/src/validation.rs (7)
stellar/contract/round/src/approval_writer.rs (2)
is_project_approved
(18-21)read_approved_projects
(5-11)stellar/contract/round/src/config_writer.rs (1)
read_config
(10-13)stellar/frontend/round-client/src/index.ts (4)
CreateRoundParams
(90-114)RoundDetail
(55-87)UpdateRoundParams
(117-133)RegistrationStatus
(359-359)stellar/frontend/lists-client/dist/index.d.ts (1)
RegistrationStatus
(14-29)stellar/contract/round/src/round_writer.rs (1)
read_round_info
(10-13)stellar/contract/round/src/utils.rs (1)
get_ledger_second_as_millis
(24-26)stellar/contract/round/src/voter_writer.rs (1)
is_blacklisted
(29-38)
stellar/contract/round/src/core.rs (2)
stellar/contract/round/src/internal.rs (5)
set_applications_config
(1190-1243)set_voting_period
(331-366)set_number_of_votes
(1074-1101)set_expected_amount
(368-382)set_minimum_deposit
(384-402)stellar/frontend/round-client/src/index.ts (1)
RoundDetail
(55-87)
🔇 Additional comments (14)
stellar/contract/round/src/core.rs (1)
12-16
: API improvement with consolidated configuration methods.The refactored method signatures provide a cleaner, more cohesive API. Consolidating related configuration aspects into single methods (
set_applications_config
,set_voting_period
, etc.) makes the interface more maintainable and reduces the chance of inconsistent states that could occur with separate methods.stellar/contract/round/src/test.rs (2)
47-74
: Good addition of list contract deployment helper.The helper functions for deploying and setting up the list contract provide clean test infrastructure and ensure consistent configuration across tests. Using a default KYC registration status of "Approved" is a pragmatic approach for test simplification.
156-163
: Useful test period helper for consistent test configuration.The
create_test_period
helper ensures consistent application and voting periods across tests, improving maintainability by centralizing timing logic. This reduces the chance of timing-related test errors and makes the test suite more robust.stellar/contract/round/src/validation.rs (4)
6-8
: Good addition of minimum duration constraints.Adding minimum duration constants for voting and application periods (24 hours) prevents creation of rounds with impractically short periods. These constraints help ensure fair participation opportunities for all users.
13-16
: Important validation that voting start is in the future.Checking that the voting start timestamp is strictly in the future prevents creation of rounds that immediately begin voting, which could give unfair advantage to users who know about the round in advance.
26-31
: Enhanced application period validation with future-time and minimum duration checks.Validating that application periods start in the future and have a minimum duration improves round fairness and usability. The future-time check prevents retroactive application periods, while the minimum duration ensures participants have reasonable time to apply.
58-60
: Enforcing minimum voting duration.Adding validation that enforces a minimum voting period duration (24 hours) ensures users have adequate time to participate in the voting process. This is an important fairness constraint.
stellar/contract/round/src/error.rs (4)
14-18
: Well-defined errors for ownership and initialization.These new error variants improve contract security by providing specific errors for ownership management and initialization states. The
NoPendingOwnershipTransfer
error specifically supports the two-step ownership transfer process which is a security best practice.
58-68
: Comprehensive timing and constraint errors.The new timing constraint errors (
VotingPeriodTooShort
,ApplicationPeriodTooShort
, etc.) directly support the enhanced validation logic. The deposit-related errors and whitelist errors improve clarity when operations fail due to specific conditions.
84-86
: Improved voting validation errors.The
DuplicatePick
andTooManyVotesForAvailablePairs
errors provide better feedback for voting validation failures, helping users understand specifically why their vote was rejected.
104-107
: Enhanced application period validation errors.These new error variants align with the enhanced application period validation logic, providing specific feedback when application periods overlap with voting or are too short, helping round creators fix configuration issues.
stellar/contract/round/src/internal.rs (3)
1209-1233
: Good improvements to application period validation.The added validations for the application period are quite thorough, checking for future start times, minimum duration, and no overlap with voting periods.
149-154
: Good validation of referrer fee basis points.The validation ensures that the referrer fee cannot exceed the maximum allowed percentage (5%).
614-619
: Clean conditional referrer fee calculation.The code now properly handles the case when referrer_id is None by setting the fee to 0.
let (application_start, application_end, voting_start, voting_end) = create_test_period(&env); | ||
|
||
// Create round | ||
let round_detail = &CreateRoundParams { | ||
description: String::from_str(&env, "description"), | ||
name: String::from_str(&env, "name"), | ||
is_video_required: false, | ||
contacts: Vec::new(&env), | ||
voting_start_ms: voting_start, | ||
voting_end_ms: voting_end, | ||
application_start_ms: Some(application_start), | ||
application_end_ms: Some(application_end), | ||
expected_amount: 5, | ||
minimum_deposit: 1, | ||
admins: admins.clone(), | ||
use_whitelist_voting: Some(false), | ||
use_whitelist_application: Some(false), | ||
voting_wl_list_id: None, | ||
application_wl_list_id: None, | ||
num_picks_per_voter: Some(2), | ||
max_participants: Some(10), | ||
allow_applications: true, | ||
owner: admin.clone(), | ||
cooldown_period_ms: None, | ||
compliance_req_desc: String::from_str(&env, ""), | ||
compliance_period_ms: None, | ||
allow_remaining_dist: false, | ||
remaining_dist_address: admin.clone(), | ||
referrer_fee_basis_points: None, | ||
use_vault: None, | ||
}; | ||
|
||
round.initialize( | ||
&admin, | ||
&token_contract.address, | ||
&project_contract.address, | ||
&list_contract.address, | ||
&Some(1), | ||
&None, | ||
&None, | ||
&None, | ||
); | ||
|
||
let created_round = round.create_round(&admin, round_detail); | ||
|
||
let reason1 = String::from_str(&env, "Challenge reason 1"); | ||
|
||
// Create three challenges | ||
round.challenge_payouts(&created_round.id, &challenger1, &reason1); | ||
|
||
// Resolve two of the challenges | ||
// let admin_notes = String::from_str(&env, "Admin notes"); | ||
// round.update_payouts_challenge( | ||
// &created_round.id, | ||
// &admin, | ||
// &challenger1, | ||
// &Some(admin_notes.clone()), | ||
// &Some(true), // Resolve this challenge | ||
// ); | ||
|
||
// round.update_payouts_challenge( | ||
// &created_round.id, | ||
// &admin, | ||
// &challenger2, | ||
// &Some(admin_notes.clone()), | ||
// &Some(true), | ||
// ); | ||
|
||
// let challenges_before = round.get_challenges_payout(&created_round.id, &None, &None); | ||
// assert_eq!(challenges_before.len(), 3); | ||
|
||
// // Count resolved challenges | ||
// let resolved_count = challenges_before.iter().filter(|c| c.resolved).count(); | ||
// assert_eq!(resolved_count, 2); | ||
|
||
// // Remove resolved challenges | ||
// round.remove_resolved_challenges(&created_round.id, &admin); | ||
|
||
// let challenges_after = round.get_challenges_payout(&created_round.id, &None, &None); | ||
// assert_eq!(challenges_after.len(), 1); | ||
|
||
// assert_eq!(challenges_after.get(0).unwrap().challenger_id, challenger3); | ||
// assert_eq!(challenges_after.get(0).unwrap().resolved, false); | ||
|
||
// // Resolve the last challenge | ||
// round.update_payouts_challenge( | ||
// &created_round.id, | ||
// &admin, | ||
// &challenger3, | ||
// &Some(admin_notes.clone()), | ||
// &Some(true), | ||
// ); | ||
|
||
// // Remove all resolved challenges | ||
// round.remove_resolved_challenges(&created_round.id, &admin); | ||
|
||
// // Verify no challenges remain | ||
// let final_challenges = round.get_challenges_payout(&created_round.id, &None, &None); | ||
// assert_eq!(final_challenges.len(), 0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Incomplete test implementation for challenge functionality.
This test verifies that non-participants cannot challenge payouts, but most of the test logic is commented out. The test currently only validates the initial error condition but doesn't test the rest of the challenge management workflow.
Consider uncommenting and completing the test implementation to verify all aspects of the challenge lifecycle:
- Creation of multiple challenges
- Resolution of challenges by admin
- Removal of resolved challenges
- Verification of challenge count before and after operations
pub fn validate_application_whitelist(env: &Env, round_id: u128, applicant: &Address) { | ||
let round = read_round_info(env, round_id); | ||
let list_id = round.application_wl_list_id.unwrap(); | ||
let list_contract = read_config(env).list_contract; | ||
let list_client = ListsClient::new(env, &list_contract); | ||
let is_whitelisted = list_client.is_registered(&Some(list_id), &applicant, &Some(RegistrationStatus::Approved)); | ||
if !is_whitelisted { | ||
panic_with_error!(env, RoundError::UserNotWhitelisted); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Same defensive check needed for application whitelist validation.
Like the voting whitelist validation, this function should check if use_whitelist_application
is true before attempting to unwrap the list ID.
pub fn validate_application_whitelist(env: &Env, round_id: u128, applicant: &Address) {
let round = read_round_info(env, round_id);
+ if !round.use_whitelist_application {
+ panic_with_error!(env, RoundError::WhitelistNotEnabled);
+ }
let list_id = round.application_wl_list_id.unwrap();
let list_contract = read_config(env).list_contract;
let list_client = ListsClient::new(env, &list_contract);
let is_whitelisted = list_client.is_registered(&Some(list_id), &applicant, &Some(RegistrationStatus::Approved));
if !is_whitelisted {
panic_with_error!(env, RoundError::UserNotWhitelisted);
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub fn validate_application_whitelist(env: &Env, round_id: u128, applicant: &Address) { | |
let round = read_round_info(env, round_id); | |
let list_id = round.application_wl_list_id.unwrap(); | |
let list_contract = read_config(env).list_contract; | |
let list_client = ListsClient::new(env, &list_contract); | |
let is_whitelisted = list_client.is_registered(&Some(list_id), &applicant, &Some(RegistrationStatus::Approved)); | |
if !is_whitelisted { | |
panic_with_error!(env, RoundError::UserNotWhitelisted); | |
} | |
pub fn validate_application_whitelist(env: &Env, round_id: u128, applicant: &Address) { | |
let round = read_round_info(env, round_id); | |
if !round.use_whitelist_application { | |
panic_with_error!(env, RoundError::WhitelistNotEnabled); | |
} | |
let list_id = round.application_wl_list_id.unwrap(); | |
let list_contract = read_config(env).list_contract; | |
let list_client = ListsClient::new(env, &list_contract); | |
let is_whitelisted = list_client.is_registered(&Some(list_id), &applicant, &Some(RegistrationStatus::Approved)); | |
if !is_whitelisted { | |
panic_with_error!(env, RoundError::UserNotWhitelisted); | |
} | |
} |
validate_blacklist(env, round_id, &voter); // validate that user is not already blacklisted | ||
add_to_blacklist(env, round_id, voter.clone()); | ||
log_update_user_flag(env, round.id, voter.clone(), true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic issue in blacklist validation.
The validate_blacklist
function is called to check if a user is not already blacklisted, but the function name suggests the opposite.
Either rename the function to better reflect its purpose or change the function call:
- validate_blacklist(env, round_id, &voter); // validate that user is not already blacklisted
+ // Option 1: Use a better named function
+ validate_not_already_blacklisted(env, round_id, &voter);
+ // Option 2: Invert the check in the existing function
+ if is_blacklisted(env, round_id, voter.clone()) {
+ panic_with_error!(env, Error::UserAlreadyBlacklisted);
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
validate_blacklist(env, round_id, &voter); // validate that user is not already blacklisted | |
add_to_blacklist(env, round_id, voter.clone()); | |
log_update_user_flag(env, round.id, voter.clone(), true); | |
if is_blacklisted(env, round_id, voter.clone()) { | |
panic_with_error!(env, Error::UserAlreadyBlacklisted); | |
} | |
add_to_blacklist(env, round_id, voter.clone()); | |
log_update_user_flag(env, round.id, voter.clone(), true); |
validate_blacklist(env, round_id, &voter); // validate that user is not already blacklisted | |
add_to_blacklist(env, round_id, voter.clone()); | |
log_update_user_flag(env, round.id, voter.clone(), true); | |
validate_not_already_blacklisted(env, round_id, &voter); | |
add_to_blacklist(env, round_id, voter.clone()); | |
log_update_user_flag(env, round.id, voter.clone(), true); |
build contract clients
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
stellar/deploy.testnet.sh (1)
5-6
: Use simple assignment instead of array assignment for contract IDs
Assigning the output ofstellar contract deploy
to an array and then expanding it can cause splitting issues (SC2207/SC2128). Since each command returns a single contract ID, prefer a quoted simple assignment.- lists_contract_id=($(stellar contract deploy --wasm target/wasm32-unknown-unknown/release/lists_opt.wasm --source potlock-testnet --network testnet)) - registry_contract_id=($(stellar contract deploy --wasm target/wasm32-unknown-unknown/release/project_registry_opt.wasm --source potlock-testnet --network testnet)) + lists_contract_id="$(stellar contract deploy --wasm target/wasm32-unknown-unknown/release/lists_opt.wasm --source potlock-testnet --network testnet)" + registry_contract_id="$(stellar contract deploy --wasm target/wasm32-unknown-unknown/release/project_registry_opt.wasm --source potlock-testnet --network testnet)"🧰 Tools
🪛 Shellcheck (0.10.0)
[warning] 5-5: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
[warning] 6-6: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
🧹 Nitpick comments (1)
stellar/deploy.testnet.sh (1)
14-15
: Quote variables in contract invocation commands
Wrapping interpolated variables in quotes prevents unintended word splitting if values ever contain spaces or special characters. For example:- stellar contract invoke --source potlock-testnet --network testnet --id ${lists_contract_id} -- initialize --owner ${my_address} - stellar contract invoke --source potlock-testnet --network testnet --id ${lists_contract_id} -- create_list --owner ${my_address} --name "Test List" --default_registration_status Approved + stellar contract invoke --source potlock-testnet --network testnet --id "${lists_contract_id}" -- initialize --owner "${my_address}" + stellar contract invoke --source potlock-testnet --network testnet --id "${lists_contract_id}" -- create_list --owner "${my_address}" --name "Test List" --default_registration_status Approved🧰 Tools
🪛 Shellcheck (0.10.0)
[warning] 14-14: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 14-14: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 15-15: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 15-15: Expanding an array without an index only gives the first element.
(SC2128)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
stellar/packages/lists-client/dist/index.d.ts
is excluded by!**/dist/**
stellar/packages/lists-client/dist/index.js
is excluded by!**/dist/**
stellar/packages/project-registry-client/dist/index.d.ts
is excluded by!**/dist/**
stellar/packages/project-registry-client/dist/index.js
is excluded by!**/dist/**
stellar/packages/round-client/dist/index.d.ts
is excluded by!**/dist/**
stellar/packages/round-client/dist/index.js
is excluded by!**/dist/**
📒 Files selected for processing (1)
stellar/deploy.testnet.sh
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
stellar/deploy.testnet.sh (6)
stellar/contract/lists/src/internal.rs (2)
initialize
(48-55)create_list
(57-126)stellar/contract/project-registry/src/internal.rs (1)
initialize
(23-31)stellar/contract/round/src/factory.rs (1)
initialize
(6-15)stellar/contract/lists/src/methods.rs (2)
initialize
(6-6)create_list
(7-16)stellar/contract/round/src/internal.rs (1)
initialize
(90-136)stellar/contract/project-registry/src/methods.rs (1)
initialize
(6-6)
🪛 Shellcheck (0.10.0)
stellar/deploy.testnet.sh
[warning] 5-5: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
[warning] 6-6: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
[warning] 7-7: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
[warning] 9-9: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 10-10: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 11-11: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 12-12: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 14-14: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 14-14: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 15-15: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 15-15: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 16-16: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 16-16: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
🔇 Additional comments (1)
stellar/deploy.testnet.sh (1)
19-21
: Validate commenting out TypeScript bindings generation
The threestellar contract bindings typescript
commands have been commented out. If your CI or developer workflow relies on auto‑generated client bindings, ensure you update documentation or reintroduce these steps in a separate CI job.
stellar contract invoke --source potlock-testnet --network testnet --id ${registry_contract_id} -- initialize --contract_owner ${my_address} | ||
stellar contract invoke --source potlock-testnet --network testnet --id ${round_contract_id} -- initialize --registry_address ${registry_contract_id} --caller ${my_address} --token_address ${native_token} --protocol_fee_basis_points 200 --protocol_fee_recipient ${my_address} --default_page_size 5 --list_address ${lists_contract_id} --kyc_wl_list_id 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid hardcoding the KYC whitelist list ID
Right now you pass --kyc_wl_list_id 1
, which assumes the newly created list will always have ID 1. This can break if the network already has existing lists. Consider capturing the list ID from the create_list
invocation (e.g., parse stdout or use JSON output) and reusing that variable:
created_list_id=$(stellar contract invoke ... -- create_list ... | jq -r '.id')
stellar contract invoke --source potlock-testnet --network testnet --id "${round_contract_id}" \
-- initialize \
--registry_address "${registry_contract_id}" \
--caller "${my_address}" \
--token_address "${native_token}" \
--protocol_fee_basis_points 200 \
--protocol_fee_recipient "${my_address}" \
--default_page_size 5 \
--list_address "${lists_contract_id}" \
--kyc_wl_list_id "${created_list_id}"
🧰 Tools
🪛 Shellcheck (0.10.0)
[warning] 16-16: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 16-16: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
[warning] 17-17: Expanding an array without an index only gives the first element.
(SC2128)
Audit Frontend Changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
stellar/frontend/project-registry-client/src/index.ts (1)
433-433
: Unsafe class-interface merging detected.This issue was previously flagged by static analysis. The class merging with an interface can be unsafe in TypeScript as it doesn't guarantee that the class implements all interface members.
🧰 Tools
🪛 Biome (1.9.4)
[error] 433-433: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🧹 Nitpick comments (1)
stellar/frontend/project-registry-client/src/index.ts (1)
148-148
: Address static analysis warnings for void types.Static analysis flags the use of
void
in the union type as confusing. Consider usingundefined
instead ofvoid
for better type clarity.-export type ContractKey = {tag: "NumOfProjects", values: void} | {tag: "Projects", values: void} | {tag: "Project", values: readonly [u128]} | {tag: "RegistryAdmin", values: void} | {tag: "ApplicantToProjectID", values: readonly [string]}; +export type ContractKey = {tag: "NumOfProjects", values: undefined} | {tag: "Projects", values: undefined} | {tag: "Project", values: readonly [u128]} | {tag: "RegistryAdmin", values: undefined} | {tag: "ApplicantToProjectID", values: readonly [string]};🧰 Tools
🪛 Biome (1.9.4)
[error] 148-148: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 148-148: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 148-148: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (10)
stellar/frontend/lists-client/dist/index.d.ts
is excluded by!**/dist/**
stellar/frontend/lists-client/dist/index.js
is excluded by!**/dist/**
stellar/frontend/lists-client/package-lock.json
is excluded by!**/package-lock.json
stellar/frontend/project-registry-client/dist/index.d.ts
is excluded by!**/dist/**
stellar/frontend/project-registry-client/dist/index.js
is excluded by!**/dist/**
stellar/frontend/project-registry-client/package-lock.json
is excluded by!**/package-lock.json
stellar/frontend/round-client/dist/index.d.ts
is excluded by!**/dist/**
stellar/frontend/round-client/dist/index.js
is excluded by!**/dist/**
stellar/frontend/round-client/package-lock.json
is excluded by!**/package-lock.json
stellar/frontend/yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
📒 Files selected for processing (5)
stellar/frontend/lists-client/README.md
(2 hunks)stellar/frontend/lists-client/src/index.ts
(12 hunks)stellar/frontend/project-registry-client/README.md
(2 hunks)stellar/frontend/project-registry-client/src/index.ts
(8 hunks)stellar/frontend/round-client/README.md
(2 hunks)
✅ Files skipped from review due to trivial changes (2)
- stellar/frontend/round-client/README.md
- stellar/frontend/lists-client/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- stellar/frontend/project-registry-client/README.md
🧰 Additional context used
🧬 Code Graph Analysis (1)
stellar/frontend/lists-client/src/index.ts (3)
stellar/frontend/lists-client/dist/index.d.ts (2)
ContractKey
(84-120)RegistrationStatus
(14-29)stellar/packages/lists-client/src/index.ts (3)
ContractKey
(107-107)Errors
(109-147)RegistrationStatus
(41-41)stellar/frontend/lists-client/dist/index.js (2)
Errors
(16-36)Errors
(16-36)
🪛 Biome (1.9.4)
stellar/frontend/lists-client/src/index.ts
[error] 106-106: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 106-106: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 106-106: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
stellar/frontend/project-registry-client/src/index.ts
[error] 148-148: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 148-148: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 148-148: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 433-433: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🔇 Additional comments (15)
stellar/frontend/project-registry-client/src/index.ts (10)
36-36
: Contract ID updated for testnet deployment.The contract ID has been updated to a new value, which aligns with the deployment changes mentioned in the AI summary.
112-112
: Field type change from enum to string.The
denomination
field has been changed from what was likely an enum to a string type, providing more flexibility for funding denomination specifications.
118-123
: New RoundPreCheck interface added.The new
RoundPreCheck
interface supports the pre-check functionality for projects and applicants, which aligns with the contract changes mentioned in the AI summary.
144-147
: Enhanced error handling with new error codes.The addition of error codes 10 (
DataNotFound
) and 11 (AlreadyInitialized
) improves error handling capabilities and aligns with the contract's enhanced error management.
215-215
: Method signature simplified by removing redundant parameters.The
add_admin
method signature has been simplified by removing redundant admin/owner parameters, which aligns with the contract method signature changes mentioned in the AI summary.
235-235
: Method signature simplified by removing redundant parameters.The
remove_admin
method signature has been simplified by removing redundant admin/owner parameters, consistent with the streamlining of admin management methods.
335-335
: Method signature simplified by removing redundant parameters.The
upgrade
method signature has been simplified by removing redundant admin/owner parameters, which improves the API's consistency and simplicity.
372-431
: New methods added for enhanced functionality.The addition of
owner
,get_precheck
, andget_precheck_by_id
methods aligns with the contract's enhanced functionality for ownership management and pre-check operations.
436-460
: Contract specifications updated to reflect interface changes.The contract specifications have been properly updated to include the new
RoundPreCheck
interface, updated error codes, and modified method signatures, ensuring the client bindings match the contract implementation.
475-478
: JSON mappings updated for new methods.The
fromJSON
mappings have been correctly updated to include the newowner
,get_precheck
, andget_precheck_by_id
methods with their appropriate return types.stellar/frontend/lists-client/src/index.ts (5)
109-145
: LGTM! Comprehensive error handling added.The addition of detailed error messages for all error codes (1-19) significantly improves debugging and user experience. The error mapping is clear and descriptive.
212-212
: LGTM! Consistent parameter removal across admin methods.The removal of
owner
parameters fromdelete_list
,transfer_ownership
,add_admins
,remove_admins
,clear_admins
, andupgrade
methods is consistent with the security improvement of using stored authorization.Also applies to: 272-272, 292-292, 312-312, 332-332, 632-632
592-592
: LGTM! Improved method signature for is_registered.Making
list_id
mandatory (removing Optional wrapper) improves the API design since checking registration status requires a specific list context.
681-706
:❓ Verification inconclusive
Verify contract specification alignment.
The base64-encoded contract specifications have been updated. Ensure these match the deployed contract's actual interface and that all method signatures are correctly represented.
🏁 Script executed:
#!/bin/bash # Compare with the dist version to ensure consistency diff <(grep -o '"[^"]*"' stellar/frontend/lists-client/src/index.ts | head -20) <(grep -o '"[^"]*"' stellar/frontend/lists-client/dist/index.js | head -20) || echo "Specifications may differ between source and dist"Length of output: 378
🏁 Script executed:
#!/bin/bash # Extract and sort base64-encoded specs from source and dist for comparison grep -Eo '"AAAAAAAA[A-Za-z0-9+/=]+"' stellar/frontend/lists-client/src/index.ts \ | sed 's/"//g' | sort > src_specs.txt grep -Eo '"AAAAAAAA[A-Za-z0-9+/=]+"' stellar/frontend/lists-client/dist/index.js \ | sed 's/"//g' | sort > dist_specs.txt diff src_specs.txt dist_specs.txt || echo "Specifications differ between source and dist"Length of output: 244
Specs Consistency Verified Locally; Please Confirm Against Deployed Contract
We ran a sorted diff of the base64-encoded specs in
src/index.ts
vs.dist/index.js
and found no discrepancies. All method signatures are identical between source and build.• src and dist payloads match exactly (no diff output)
• Next step: manually verify these specs against the live contract’s interface on chain to ensure every method signature is correctly represented
192-192
:✅ Verification successful
Verify consistency of owner parameter removal.
The
owner
parameter has been removed fromupdate_list
. This aligns with the broader pattern of using stored authorization rather than passed parameters, which is a security improvement.Verify that all method signature changes are consistent with the backend contract:
🏁 Script executed:
#!/bin/bash # Search for any remaining owner parameters in method signatures that might have been missed rg -A 2 -B 2 "owner.*:" stellar/frontend/lists-client/src/index.tsLength of output: 3441
Owner parameter removal in
update_list
confirmed
A ripgrep scan ofstellar/frontend/lists-client/src/index.ts
shows thatupdate_list
no longer destructures or expects anowner
field, while other methods (e.g.initialize
,create_list
,get_lists_for_owner
) continue to declare it where required. No unintended removals were detected.
@@ -33,7 +33,7 @@ if (typeof window !== 'undefined') { | |||
export const networks = { | |||
testnet: { | |||
networkPassphrase: "Test SDF Network ; September 2015", | |||
contractId: "CBAASQSA662PIZ26JQFRLDU2Q53WMJOHLUA2UGZE2RE2HZG2M7ZXV3ES", | |||
contractId: "CBD4OK7KMJERD2HM775IXQGY4XE5G3QBV5BFBYMQ6LB4ONFCPBZAXENP", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify the new contract ID is correct.
The contract ID has been updated for the testnet network. Ensure this corresponds to the correct deployed contract instance.
🏁 Script executed:
#!/bin/bash
# Verify the contract ID exists on Stellar testnet
curl -s "https://horizon-testnet.stellar.org/contracts/CBD4OK7KMJERD2HM775IXQGY4XE5G3QBV5BFBYMQ6LB4ONFCPBZAXENP" | jq '.type'
Length of output: 170
Contract ID Not Found on Stellar Testnet
The contract ID "CBD4OK7KMJERD2HM775IXQGY4XE5G3QBV5BFBYMQ6LB4ONFCPBZAXENP"
does not exist according to the Horizon testnet API.
• File: stellar/frontend/lists-client/src/index.ts
, line 36
• Action: Verify that the contract is deployed to testnet and update contractId
to the correct, existing ID.
🤖 Prompt for AI Agents
In stellar/frontend/lists-client/src/index.ts at line 36, the contractId value
"CBD4OK7KMJERD2HM775IXQGY4XE5G3QBV5BFBYMQ6LB4ONFCPBZAXENP" does not exist on the
Stellar testnet. Verify that the contract has been properly deployed to the
testnet and obtain the correct contract ID. Update the contractId field with
this valid, existing contract ID to ensure the application references the
correct deployed contract.
@@ -103,10 +103,46 @@ export interface RegistrationInput { | |||
updated_ms: Option<u64>; | |||
} | |||
|
|||
export type ContractKey = {tag: "ContractOwner", values: void} | {tag: "ListsNumber", values: void} | {tag: "Lists", values: void} | {tag: "ListAdmins", values: void} | {tag: "OwnedList", values: void} | {tag: "RegistrantList", values: void} | {tag: "RegistrationsNumber", values: void} | {tag: "Registrations", values: void} | {tag: "ListRegistration", values: void} | {tag: "RegistrationsIDs", values: void} | {tag: "Upvotes", values: void} | {tag: "UserUpvotes", values: void}; | |||
export type ContractKey = {tag: "ContractOwner", values: void} | {tag: "ListsNumber", values: void} | {tag: "Lists", values: readonly [u128]} | {tag: "ListAdmins", values: readonly [u128]} | {tag: "OwnedList", values: readonly [string]} | {tag: "RegistrantList", values: readonly [string]} | {tag: "RegistrationsNumber", values: void} | {tag: "Registrations", values: readonly [u128]} | {tag: "ListRegistration", values: readonly [u128]} | {tag: "RegistrationsIDs", values: readonly [string]} | {tag: "Upvotes", values: readonly [u128]} | {tag: "UserUpvotes", values: readonly [string]}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix confusing void
usage in union types.
The static analysis tool correctly identifies that using void
in union types is confusing and should be avoided. Use undefined
instead for better type clarity.
Apply this diff to fix the type definition:
-export type ContractKey = {tag: "ContractOwner", values: void} | {tag: "ListsNumber", values: void} | {tag: "Lists", values: readonly [u128]} | {tag: "ListAdmins", values: readonly [u128]} | {tag: "OwnedList", values: readonly [string]} | {tag: "RegistrantList", values: readonly [string]} | {tag: "RegistrationsNumber", values: void} | {tag: "Registrations", values: readonly [u128]} | {tag: "ListRegistration", values: readonly [u128]} | {tag: "RegistrationsIDs", values: readonly [string]} | {tag: "Upvotes", values: readonly [u128]} | {tag: "UserUpvotes", values: readonly [string]};
+export type ContractKey = {tag: "ContractOwner", values: undefined} | {tag: "ListsNumber", values: undefined} | {tag: "Lists", values: readonly [u128]} | {tag: "ListAdmins", values: readonly [u128]} | {tag: "OwnedList", values: readonly [string]} | {tag: "RegistrantList", values: readonly [string]} | {tag: "RegistrationsNumber", values: undefined} | {tag: "Registrations", values: readonly [u128]} | {tag: "ListRegistration", values: readonly [u128]} | {tag: "RegistrationsIDs", values: readonly [string]} | {tag: "Upvotes", values: readonly [u128]} | {tag: "UserUpvotes", values: readonly [string]};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export type ContractKey = {tag: "ContractOwner", values: void} | {tag: "ListsNumber", values: void} | {tag: "Lists", values: readonly [u128]} | {tag: "ListAdmins", values: readonly [u128]} | {tag: "OwnedList", values: readonly [string]} | {tag: "RegistrantList", values: readonly [string]} | {tag: "RegistrationsNumber", values: void} | {tag: "Registrations", values: readonly [u128]} | {tag: "ListRegistration", values: readonly [u128]} | {tag: "RegistrationsIDs", values: readonly [string]} | {tag: "Upvotes", values: readonly [u128]} | {tag: "UserUpvotes", values: readonly [string]}; | |
export type ContractKey = | |
| { tag: "ContractOwner"; values: undefined } | |
| { tag: "ListsNumber"; values: undefined } | |
| { tag: "Lists"; values: readonly [u128] } | |
| { tag: "ListAdmins"; values: readonly [u128] } | |
| { tag: "OwnedList"; values: readonly [string] } | |
| { tag: "RegistrantList"; values: readonly [string] } | |
| { tag: "RegistrationsNumber"; values: undefined } | |
| { tag: "Registrations"; values: readonly [u128] } | |
| { tag: "ListRegistration"; values: readonly [u128] } | |
| { tag: "RegistrationsIDs"; values: readonly [string] } | |
| { tag: "Upvotes"; values: readonly [u128] } | |
| { tag: "UserUpvotes"; values: readonly [string] }; |
🧰 Tools
🪛 Biome (1.9.4)
[error] 106-106: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 106-106: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 106-106: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
🤖 Prompt for AI Agents
In stellar/frontend/lists-client/src/index.ts at line 106, the ContractKey type
uses void in union types, which is confusing. Replace all occurrences of void
with undefined in the values field of the union types to improve type clarity
and satisfy static analysis.
pushed fixes to create round
pushing to master
Summary by CodeRabbit
New Features
RoundMenu
component for streamlined round interactions.Enhancements
Bug Fixes
Documentation