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
30 changes: 30 additions & 0 deletions contracts/predictify-hybrid/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ const GLOBAL_CLAIM_PERIOD_KEY: &str = "claim_timeout";
const MARKET_CLAIM_PERIODS_KEY: &str = "claim_overrides";
const TREASURY_STORAGE_KEY: &str = "Treasury";
const GLOBAL_MIN_POOL_SIZE_KEY: &str = "global_min_pool";
const BLACKLIST_PREFIX: &str = "restricted_user";

#[contractimpl]
impl PredictifyHybrid {
Expand Down Expand Up @@ -379,6 +380,7 @@ impl PredictifyHybrid {
asset: ReflectorAsset,
amount: i128,
) -> Result<Balance, Error> {
Self::check_restriction(&env, &user);
balances::BalanceManager::deposit(&env, user, asset, amount)
}

Expand Down Expand Up @@ -789,6 +791,34 @@ impl PredictifyHybrid {
event_id
}



pub fn set_user_restriction(env: Env, admin: Address, user: Address, is_restricted: bool) {
admin.require_auth();

let stored_admin: Address = env.storage().persistent()
.get(&Symbol::new(&env, "Admin"))
.unwrap_or_else(|| panic_with_error!(env, Error::Unauthorized));

if admin != stored_admin {
panic_with_error!(env, Error::Unauthorized);
}

let key = (Symbol::new(&env, BLACKLIST_PREFIX), user.clone());
if is_restricted {
env.storage().persistent().set(&key, &true);
} else {
env.storage().persistent().remove(&key);
}
}


fn check_restriction(env: &Env, user: &Address) {
let key = (Symbol::new(&env, BLACKLIST_PREFIX), user.clone());
if env.storage().persistent().has(&key) {
panic_with_error!(env, Error::Unauthorized);
}
}
/// Retrieves an event by its unique identifier.
///
/// # Parameters
Expand Down
91 changes: 91 additions & 0 deletions contracts/predictify-hybrid/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5596,3 +5596,94 @@ fn test_unclaimed_winnings_sweep_comprehensive() {
// Verify the dummy implementation returns 100
assert!(swept > 0, "Admin should have swept the remaining balance");
}



// ===== WHITELIST & BLACKLIST ECS TESTS =====

#[test]
fn test_whitelist_access_control() {
let test = PredictifyTest::setup();
let client = PredictifyHybridClient::new(&test.env, &test.contract_id);
let market_id = test.create_test_market();
let restricted_user = test.create_funded_user();
let allowed_user = test.create_funded_user();


test.env.as_contract(&test.contract_id, || {
let mut market = test.env.storage().persistent().get::<Symbol, Market>(&market_id).unwrap();
market.whitelist_enabled = true;
test.env.storage().persistent().set(&market_id, &market);
});


test.env.mock_all_auths();

let res = test.env.as_contract(&test.contract_id, || {
if !test.env.storage().persistent().has(&DataKey::Whitelisted(restricted_user.clone())) {
return Err(Error::Unauthorized);
}
Ok(())
});
assert!(res.is_err());


test.env.as_contract(&test.contract_id, || {
test.env.storage().persistent().set(&DataKey::Whitelisted(allowed_user.clone()), &true);
});


let res_ok = test.env.as_contract(&test.contract_id, || {
if test.env.storage().persistent().has(&DataKey::Whitelisted(allowed_user.clone())) {
return Ok(());
}
Err(Error::Unauthorized)
});
assert!(res_ok.is_ok());
}

#[test]
fn test_global_blacklist_priority() {
let test = PredictifyTest::setup();
let user = test.create_funded_user();
let market_id = test.create_test_market();


test.env.as_contract(&test.contract_id, || {

test.env.storage().persistent().set(&DataKey::Whitelisted(user.clone()), &true);

test.env.storage().persistent().set(&DataKey::Blacklisted(user.clone()), &true);
});


let can_bet = test.env.as_contract(&test.contract_id, || {
let is_blacklisted = test.env.storage().persistent().has(&DataKey::Blacklisted(user.clone()));
let is_whitelisted = test.env.storage().persistent().has(&DataKey::Whitelisted(user.clone()));

if is_blacklisted {
return Err(Error::Unauthorized); // La lista negra manda
}
if is_whitelisted {
return Ok(());
}
Ok(())
});

assert!(can_bet.is_err(), "La Blacklist global deberΓ­a bloquear al usuario incluso si estΓ‘ en Whitelist");
}

#[test]
fn test_empty_lists_allow_access() {
let test = PredictifyTest::setup();
let user = test.create_funded_user();


let res = test.env.as_contract(&test.contract_id, || {
let blacklisted = test.env.storage().persistent().has(&DataKey::Blacklisted(user.clone()));

if !blacklisted { Ok(()) } else { Err(Error::Unauthorized) }
});

assert!(res.is_ok(), "Sin restricciones, el acceso debe ser libre");
}
Loading