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
11 changes: 11 additions & 0 deletions contracts/artist-allowlist/src/access.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use soroban_sdk::{Address, Env};

use crate::Error;

pub fn require_artist_or_manager(env: &Env, artist: &Address, caller: &Address) -> Result<(), Error> {
caller.require_auth();
if caller == artist || crate::storage::is_manager(env, artist, caller) {
return Ok(());
}
Err(Error::Unauthorized)
}
23 changes: 20 additions & 3 deletions contracts/artist-allowlist/src/indexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ pub enum IndexKey {
ArtistEntries(Address),
}

const LIFETIME_THRESHOLD: u32 = 100_000;
const EXTEND_TO: u32 = 200_000;

fn bump(env: &Env, key: &IndexKey) {
env.storage()
.persistent()
.extend_ttl(key, LIFETIME_THRESHOLD, EXTEND_TO);
}

pub fn add_to_index(env: &Env, artist: &Address, address: &Address) {
let key = IndexKey::ArtistEntries(artist.clone());
let mut entries: Vec<Address> = env
Expand All @@ -15,6 +24,7 @@ pub fn add_to_index(env: &Env, artist: &Address, address: &Address) {
.unwrap_or_else(|| Vec::new(env));
entries.push_back(address.clone());
env.storage().persistent().set(&key, &entries);
bump(env, &key);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't extend the index TTL independently from the entry TTLs.

These paths now keep IndexKey::ArtistEntries alive, but the underlying DataKey::Entry records are only refreshed through storage::get_entry/has_entry. That means list_allowlist and get_allowlist_count can drift stale after entry keys expire, while is_on_allowlist correctly returns false. Please either refresh/prune the entry keys here as well, or stop bumping the index on its own.

Also applies to: 48-48, 62-64, 77-84

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/artist-allowlist/src/indexes.rs` at line 27, The code is extending
IndexKey::ArtistEntries TTL via bump(env, &key) without touching the underlying
DataKey::Entry TTLs, causing list_allowlist/get_allowlist_count to become stale;
either remove the index-only bump calls (references: bump,
IndexKey::ArtistEntries) from the affected functions or, if you must refresh the
index, also iterate the referenced DataKey::Entry items and call
storage::get_entry/has_entry (or explicitly refresh/prune those entry keys) so
entry TTLs stay in sync; update the logic in the functions that call bump (and
corresponding blocks at the other locations mentioned) to use one consistent
approach.

}

pub fn remove_from_index(env: &Env, artist: &Address, address: &Address) {
Expand All @@ -35,6 +45,7 @@ pub fn remove_from_index(env: &Env, artist: &Address, address: &Address) {
}
}
env.storage().persistent().set(&key, &entries);
bump(env, &key);
}
}

Expand All @@ -48,6 +59,9 @@ pub fn get_page(env: &Env, artist: &Address, page: u32, page_size: u32) -> Vec<A
.persistent()
.get(&key)
.unwrap_or_else(|| Vec::new(env));
if !entries.is_empty() {
bump(env, &key);
}
let start = page * page_size;
let total = entries.len();
let end = (start + page_size).min(total);
Expand All @@ -60,9 +74,12 @@ pub fn get_page(env: &Env, artist: &Address, page: u32, page_size: u32) -> Vec<A

pub fn get_count(env: &Env, artist: &Address) -> u32 {
let key = IndexKey::ArtistEntries(artist.clone());
env.storage()
let entries = env.storage()
.persistent()
.get::<IndexKey, Vec<Address>>(&key)
.map(|v| v.len())
.unwrap_or(0)
.unwrap_or_else(|| Vec::new(env));
if !entries.is_empty() {
bump(env, &key);
}
entries.len()
}
Loading
Loading