public entry fun register_pizza_lover(owner: &signer, user: address) acquires ModuleData, State {
let state = borrow_global_mut<State>(get_resource_address());
assert!(signer::address_of(owner) == state.owner, E_NOT_OWNER);
get_random_slice(user); // @> No check for available funds vs potential claims
event::emit(PizzaLoverRegistered {
user: user,
})
}
#[randomness]
entry fun get_random_slice(user_addr: address) acquires ModuleData, State {
let state = borrow_global_mut<State>(get_resource_address());
let time = timestamp::now_microseconds();
let random_val = time % 401
let random_amount = 100 + random_val;
table::add(&mut state.users_claimed_amount, user_addr, random_amount); // @> No limit check
}
#[test]
fun test_over_registration() acquires ModuleData, State {
init_module(deployer);
fund_pizza_drop(deployer, 1000);
// Register 10 users (each could get up to 500 APT = 5000 APT total needed)
let i = 0
while (i < 10) {
let user_addr = @0x100 + i;
register_pizza_lover(deployer, user_addr);
i = i + 1
}
let total_potential = 0
let j = 0
while (j < 10) {
let user_addr = @0x100 + j;
total_potential = total_potential + get_claimed_amount(user_addr)
j = j + 1
}
assert!(total_potential > 1000, 1);
}
struct State has key {
users_claimed_amount: Table<address, u64>,
claimed_users: Table<address, bool>,
owner: address,
balance: u64,
+ max_users: u64, // Maximum number of users that can be registered
+ registered_count: u64, // Current number of registered users
+ total_allocated: u64, // Total amount allocated to all users
}
fun init_module(deployer: &signer) {
// ... existing code ...
let state = State {
users_claimed_amount: table::new(),
claimed_users: table::new(),
owner: signer::address_of(deployer),
balance: 0,
+ max_users: 0, // Initially no registrations allowed
+ registered_count: 0,
+ total_allocated: 0,
};
// ... rest of function
}
+ // Owner must set registration limits based on available funds
+ public entry fun set_registration_limit(owner: &signer, max_users: u64) acquires ModuleData, State {
+ let state = borrow_global_mut<State>(get_resource_address());
+ assert!(signer::address_of(owner) == state.owner, E_NOT_OWNER);
+
+ // Ensure we have enough funds for worst case (all users get 500 APT)
+ let worst_case_total = max_users * 500;
+ assert!(state.balance >= worst_case_total, E_INSUFFICIENT_FUND);
+
+ state.max_users = max_users;
+ }
public entry fun register_pizza_lover(owner: &signer, user: address) acquires ModuleData, State {
let state = borrow_global_mut<State>(get_resource_address());
assert!(signer::address_of(owner) == state.owner, E_NOT_OWNER);
+ // Check if already registered
+ assert!(!table::contains(&state.users_claimed_amount, user), E_ALREADY_REGISTERED);
+
+ // Check registration limits
+ assert!(state.registered_count < state.max_users, E_REGISTRATION_LIMIT_REACHED);
get_random_slice(user);
+ state.registered_count = state.registered_count + 1;
event::emit(PizzaLoverRegistered {
user: user,
});
}
#[randomness]
entry fun get_random_slice(user_addr: address) acquires ModuleData, State {
let state = borrow_global_mut<State>(get_resource_address());
let time = timestamp::now_microseconds();
let random_val = time % 401;
let random_amount = 100 + random_val;
+ // Update total allocated amount
+ state.total_allocated = state.total_allocated + random_amount;
+
+ // Ensure we still have enough funds for this allocation
+ assert!(state.balance >= state.total_allocated, E_INSUFFICIENT_FUND);
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}
+ // Add new error codes
+ const E_ALREADY_REGISTERED: u64 = 5;
+ const E_REGISTRATION_LIMIT_REACHED: u64 = 6;