Skip to content

Commit d5b3ff6

Browse files
committed
feat: creator registry - spam fee or rate limit
1 parent a3c26dc commit d5b3ff6

1 file changed

Lines changed: 58 additions & 3 deletions

File tree

  • contract/contracts/creator-registry/src

contract/contracts/creator-registry/src/lib.rs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ use soroban_sdk::{
44
contract, contracterror, contractimpl, contracttype, panic_with_error, Address, Env, Symbol,
55
};
66

7+
use soroban_sdk::token::Client;
8+
79
/// Minimum number of ledgers between registrations per caller (anti-spam).
8-
const RATE_LIMIT_LEDGERS: u32 = 10;
10+
const DEFAULT_RATE_LIMIT: u32 = 10;
911

1012
#[contracttype]
1113
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -14,7 +16,11 @@ pub enum DataKey {
1416
Creator(Address), // maps creator address -> creator_id (u64)
1517
// Canonical storage name: `registration_ledger`.
1618
// Keep the legacy `LastRegLedger` variant to preserve deployed key serialization.
17-
LastRegLedger(Address), // last ledger when this caller did a registration
19+
LastRegLedger(Address),
20+
21+
RateLimit,
22+
SpamFee,
23+
FeeToken,
1824
}
1925

2026
impl DataKey {
@@ -34,6 +40,8 @@ pub enum Error {
3440
RateLimited = 4,
3541
AlreadyRegistered = 5,
3642
NotRegistered = 6,
43+
44+
InvalidAmount = 7,
3745
}
3846

3947
#[contract]
@@ -47,6 +55,31 @@ impl CreatorRegistryContract {
4755
panic_with_error!(&env, Error::AlreadyInitialized);
4856
}
4957
env.storage().instance().set(&DataKey::Admin, &admin);
58+
59+
env.storage()
60+
.instance()
61+
.set(&DataKey::RateLimit, &DEFAULT_RATE_LIMIT);
62+
env.storage().instance().set(&DataKey::SpamFee, &0i128);
63+
}
64+
// set the number of ledgers for rate limiting (admin only)
65+
pub fn set_rate_limit(env: Env, ledgers: u32) {
66+
let admin = Self::get_admin(&env);
67+
admin.require_auth();
68+
69+
env.storage().instance().set(&DataKey::RateLimit, &ledgers);
70+
}
71+
72+
// set the fee for spamming registrations (admin only)
73+
pub fn set_spam_fee(env: Env, token: Address, amount: i128) {
74+
let admin = Self::get_admin(&env);
75+
admin.require_auth();
76+
77+
if amount < 0 {
78+
panic_with_error!(&env, Error::InvalidAmount);
79+
}
80+
81+
env.storage().instance().set(&DataKey::SpamFee, &amount);
82+
env.storage().instance().set(&DataKey::FeeToken, &token);
5083
}
5184

5285
/// Register a creator with a specific creator_id
@@ -68,7 +101,7 @@ impl CreatorRegistryContract {
68101
let current = env.ledger().sequence();
69102
let last_key = DataKey::registration_ledger(caller.clone());
70103
if let Some(last) = env.storage().persistent().get::<DataKey, u32>(&last_key) {
71-
if current < last.saturating_add(RATE_LIMIT_LEDGERS) {
104+
if current < last.saturating_add(DEFAULT_RATE_LIMIT) {
72105
panic_with_error!(&env, Error::RateLimited);
73106
}
74107
}
@@ -80,6 +113,21 @@ impl CreatorRegistryContract {
80113

81114
env.storage().persistent().set(&last_key, &current);
82115
env.storage().persistent().set(&key, &creator_id);
116+
117+
let fee: i128 = env.storage().instance().get(&DataKey::SpamFee).unwrap_or(0);
118+
119+
if fee > 0 {
120+
let token_address: Address = env
121+
.storage()
122+
.instance()
123+
.get(&DataKey::FeeToken)
124+
.unwrap_or_else(|| panic_with_error!(&env, Error::NotInitialized));
125+
126+
let token_client = Client::new(&env, &token_address);
127+
128+
// transfer fee from caller to contract if fee is set
129+
token_client.transfer(&caller, &env.current_contract_address(), &fee);
130+
}
83131
}
84132

85133
/// Unregister a creator (admin only).
@@ -116,6 +164,13 @@ impl CreatorRegistryContract {
116164
pub fn get_creator_id(env: Env, address: Address) -> Option<u64> {
117165
env.storage().persistent().get(&DataKey::Creator(address))
118166
}
167+
// Internal helper to enforce authorization of admin or creator
168+
fn get_admin(env: &Env) -> Address {
169+
env.storage()
170+
.instance()
171+
.get(&DataKey::Admin)
172+
.unwrap_or_else(|| panic_with_error!(env, Error::NotInitialized))
173+
}
119174
}
120175

121176
mod test;

0 commit comments

Comments
 (0)