Skip to content
Merged
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
18 changes: 18 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ pub enum RevoraError {
SignerKeyNotRegistered = 29,
/// The provided attestation network identifier does not match the active ledger network.
NetworkIdMismatch = 62,
/// Transfer blocked because shares are still locked (lockup schedule active).
LockupViolation = 63,
/// Multisig proposal has expired.
/// Wire value: 30. Stable since v1.
ProposalExpired = 30,
Expand Down Expand Up @@ -595,6 +597,9 @@ const EVENT_ADMIN_ROTATION_LOGGED: Symbol = symbol_short!("adm_log");
const EVENT_ADMIN_ROTATION_REVOKED: Symbol = symbol_short!("adm_rvk");
/// Emitted when a lockup schedule is configured for an offering.
const EVENT_LOCKUP_SET: Symbol = symbol_short!("lock_set");
/// Emitted when a transfer is attempted while the offering has active lockup restrictions.
/// Includes the caller, unlock timestamp, and attempted amount for indexer alerting.
const EVENT_LOCKUP_VIOLATION: Symbol = symbol_short!("lock_viol");
const EVENT_PLATFORM_FEE_SET: Symbol = symbol_short!("fee_set");
const EVENT_FRZ_SET: Symbol = symbol_short!("frz_set");
const EVENT_FRZ_CLR: Symbol = symbol_short!("frz_clr");
Expand Down Expand Up @@ -6802,6 +6807,19 @@ impl RevoraRevenueShare {
return Ok(());
}

// Lockup violation check: reject transfer if lockup is still active
if let Some(schedule) = Self::get_lockup_schedule(env.clone(), issuer.clone(), namespace.clone(), token.clone()) {
let now = env.ledger().timestamp();
let unlocked_bps = schedule.calculate_unlocked_bps(now);
if unlocked_bps < 10_000 {
env.events().publish(
(EVENT_LOCKUP_VIOLATION, from.clone()),
(to.clone(), amount_bps, schedule.clone()),
);
return Err(RevoraError::LockupViolation);
}
}

// Zero-value transfer is meaningless
if amount_bps == 0 {
return Err(RevoraError::InvalidAmount);
Expand Down
Loading