miracle_api/instruction.rs
1use solana_program::pubkey::Pubkey;
2use steel::*;
3
4#[repr(u8)]
5#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
6pub enum MiracleInstruction {
7 // User
8 BatchClaim = 0, // Claim rewards for multiple epochs
9 Claim = 1, // Claim rewards with merkle proof
10 Close = 2,
11 Open = 3,
12 Reset = 4,
13
14 // Admin
15 Initialize = 100,
16
17 // Oracle
18 UpdateMetrics = 101, // Update community metrics
19 UpdateOracle = 102, // Update oracle authority
20 UpdateSnapshot = 103, // Update daily payment snapshot
21 UpdateTargets = 104, // Update community targets and activity limits
22}
23
24#[repr(C)]
25#[derive(Clone, Copy, Debug, Pod, Zeroable)]
26pub struct Close {}
27
28#[repr(C)]
29#[derive(Clone, Copy, Debug, Pod, Zeroable)]
30pub struct Open {}
31
32#[repr(C)]
33#[derive(Clone, Copy, Debug, Pod, Zeroable)]
34pub struct Reset {}
35
36#[repr(C)]
37#[derive(Clone, Copy, Debug, Pod, Zeroable)]
38pub struct Initialize {
39 pub project_wallet: Pubkey, // Project wallet for pre-mint allocation
40}
41
42// #[repr(C)]
43// #[derive(Clone, Copy, Debug, Pod, Zeroable)]
44// pub struct UpdateEvolver {
45// pub new_evolver: Pubkey,
46// }
47
48#[repr(C)]
49#[derive(Clone, Copy, Debug, Pod, Zeroable)]
50pub struct UpdateOracle {
51 pub new_oracle_authority: Pubkey,
52}
53
54#[repr(C)]
55#[derive(Clone, Copy, Debug, Pod, Zeroable)]
56pub struct UpdateMetrics {
57 pub weekly_active_users: [u8; 4], // u32
58 pub weekly_retention_rate: [u8; 2], // u16
59 pub user_weight: [u8; 2], // u16
60 pub activity_weight: [u8; 2], // u16
61 pub retention_weight: [u8; 2], // u16
62 pub weekly_activity_count: [u8; 4], // u32
63 pub customer_reward_share: [u8; 2], // u16
64 pub merchant_reward_share: [u8; 2], // u16
65 pub _padding: [u8; 4], // 4 bytes padding for 8-byte alignment
66}
67
68// ===== PAYMENT-BASED REWARDS SYSTEM INSTRUCTIONS =====
69
70/// Claim instruction data for Dual Merkle Tree system with optional social rewards.
71///
72/// This instruction allows users to claim rewards based on their activity contributions
73/// for a specific epoch using the Dual Merkle Tree verification system. The claim is verified
74/// using both a payment merkle proof and a seal merkle proof, with the payment root embedded
75/// in the seal proof data for explicit verification. Optionally, users can also claim social
76/// marketing rewards for the same epoch if they have verified social media engagement.
77///
78/// ## Dual Merkle Verification
79/// 1. **Payment Proof**: Verifies user's activity within the epoch
80/// 2. **Seal Proof**: Verifies the payment merkle root is authentic (from oracle)
81/// 3. **Payment Root**: Embedded in seal proof data for explicit verification
82/// 4. **Dual Verification**: Both proofs must pass for a valid claim
83///
84/// ## Social Rewards Support
85/// - **Payment-First**: Social rewards require payment activity verification
86/// - **Oracle Verification**: Social posts must be verified by oracle signature
87/// - **Optional**: Users can choose payment-only or payment+social claims
88/// - **Unified**: Single instruction supports both reward types
89///
90/// ## Data Structure
91/// The instruction uses a hybrid approach with fixed-size fields followed by variable-length data:
92///
93/// ```rust
94/// // Fixed-size struct (23 bytes)
95/// struct Claim {
96/// epoch: [u8; 8], // 8 bytes - Epoch number for the claim
97/// payment_proof_length: u8, // 1 byte - Length of payment merkle path
98/// seal_proof_length: u8, // 1 byte - Length of seal merkle path
99/// participant_type: u8, // 1 byte - 0 for customer, 1 for merchant
100/// has_social: u8, // 1 byte - 0=payment only, 1=has social data
101/// _padding: [u8; 4], // 4 bytes - Padding for alignment
102/// }
103///
104/// // Variable-size additional data (appended after fixed struct)
105/// // participant_data: DailyParticipantData // Variable size - Actual participant data for verification
106/// // payment_proof: Vec<[u8; 32]> // payment_proof_length * 32 bytes
107/// // payment_indices: Vec<u8> // payment_proof_length * 1 byte
108/// // seal_proof: Vec<[u8; 32]> // seal_proof_length * 32 bytes
109/// // seal_indices: Vec<u8> // seal_proof_length * 1 byte
110/// // payment_root: [u8; 32] // Payment root (embedded in seal proof data)
111/// // epoch_data: EpochClaimData // Epoch-specific data for accurate historical reward calculation
112/// // social_data: SocialClaimData // Optional: only if has_social = 1
113/// ```
114///
115/// ## Security Features
116/// - **Payment Proof**: Ensures claim data integrity within an epoch
117/// - **Seal Proof**: Ensures payment merkle root is authentic (from oracle)
118/// - **Payment Root**: Explicitly provided for verification
119/// - **Dual Verification**: Both proofs must pass for a valid claim
120/// - **Oracle Verification**: Social posts verified by authorized oracle
121/// - **Unlimited History**: No storage limits for historical claims
122///
123/// ## On-Chain Reward Calculation
124/// The reward amount is calculated on-chain using the transparent formula:
125/// payment_reward = (activity_count * customer_reward_pool) / total_customer_activity
126/// social_reward = base_reward_per_post * (1 + engagement_score / 1000)
127///
128/// Where:
129/// - `activity_count` is extracted from the payment merkle proof
130/// - `customer_reward_pool` and `total_customer_activity` are read from the Snapshot
131/// - `base_reward_per_post` and engagement data come from social verification
132///
133/// ## Historical Claims Support
134/// For historical epoch claims, the instruction includes epoch-specific data:
135/// - **Current Epoch**: Uses on-chain snapshot data for reward calculation
136/// - **Historical Epochs**: Uses epoch-specific data embedded in the instruction
137/// - **No On-Chain Storage**: Historical data comes with the claim instruction
138/// - **Accurate Rewards**: Users get correct rewards for historical activity
139///
140/// This enables the Dual Merkle Tree's promise of unlimited claim history without
141/// requiring expensive on-chain storage of historical snapshots.
142///
143/// ## Off-Chain Development
144/// When building claim instructions off-chain:
145/// 1. Set `payment_proof_length` and `seal_proof_length` to actual path lengths
146/// 2. Set `has_social` to 1 if social data is included, 0 otherwise
147/// 3. Append payment proof data after the fixed struct
148/// 4. Append payment indices data (1 = right, 0 = left)
149/// 5. Append seal proof data
150/// 6. Append seal indices data (1 = right, 0 = left)
151/// 7. Append payment root data (32 bytes)
152/// 8. Append epoch-specific data (EpochClaimData) for accurate historical calculations
153/// 9. If has_social = 1, append SocialClaimData
154/// 10. Verify total instruction size doesn't exceed Solana limits
155///
156/// See `DUAL_MERKLE_TREE_DESIGN.md` for detailed implementation examples.
157#[repr(C)]
158#[derive(Clone, Copy, Debug, Pod, Zeroable)]
159pub struct Claim {
160 pub epoch: [u8; 8], // Epoch number for the claim
161 pub payment_proof_length: u8, // Length of payment merkle path
162 pub seal_proof_length: u8, // Length of seal merkle path
163 pub participant_type: u8, // 0 for customer, 1 for merchant
164 pub has_social: u8, // 0=payment only, 1=has social data
165 pub _padding: [u8; 4], // Padding for alignment
166
167 // Note: payment_proof, payment_indices, seal_proof, seal_indices, social_data will be passed as additional data
168}
169
170/// BatchClaim instruction data for Dual Merkle Tree system.
171///
172/// This instruction allows users to claim rewards for multiple epochs in a single transaction
173/// using the Dual Merkle Tree verification system. Each epoch requires both payment and seal
174/// merkle proofs for complete security verification.
175///
176/// ## Dual Merkle Verification for Batch Claims
177/// For each epoch in the batch:
178/// 1. **Payment Proof**: Verifies user's activity within the epoch
179/// 2. **Seal Proof**: Verifies the payment merkle root is authentic (from oracle)
180/// 3. **Dual Verification**: Both proofs must pass for each epoch
181///
182/// ## Data Structure
183/// The instruction uses a hybrid approach supporting different claim types:
184///
185/// ```rust
186/// // Fixed-size struct (25 bytes)
187/// struct BatchClaim {
188/// start_epoch: [u8; 8], // 8 bytes - Start epoch for range claims
189/// end_epoch: [u8; 8], // 8 bytes - End epoch for range claims
190/// participant_type: u8, // 1 byte - 0 for customer, 1 for merchant
191/// claim_type: u8, // 1 byte - 0=range, 1=vector, 2=date_range
192/// epoch_count: u8, // 1 byte - Number of epochs for vector claims
193/// max_batch_size: u8, // 1 byte - Maximum epochs to process
194/// _padding: [u8; 4], // 4 bytes - Padding for alignment
195/// }
196///
197/// // Variable-size additional data (appended after fixed struct)
198/// // For vector claims: Vec<u64> of epochs
199/// // For each epoch: payment_proof + payment_indices + payment_root + seal_proof + seal_indices + epoch_data
200/// // Social flags array: 1 byte per epoch (0=no social, 1=has social)
201/// // Social data array: SocialClaimData for epochs with social claims
202/// ```
203///
204/// ## Claim Types
205/// - **Range Claims (0)**: Claim all epochs from start_epoch to end_epoch (inclusive)
206/// - **Vector Claims (1)**: Claim specific epochs listed in variable data
207/// - **Date Range Claims (2)**: Convert date range to epoch range automatically
208///
209/// ## Benefits
210/// - **Gas Efficiency**: Single transaction for multiple epochs
211/// - **User Experience**: Natural date-based interface
212/// - **Flexibility**: Support for both contiguous and non-contiguous epochs
213/// - **Security**: Each epoch validated independently with dual merkle proofs
214/// - **Unified**: Supports both payment and social rewards in single batch
215/// - **Payment-First**: All social claims require payment activity
216/// - **Unlimited History**: No storage limits for historical claims
217///
218/// ## Historical Claims Support
219/// For historical epoch claims, each epoch includes epoch-specific data:
220/// - **Current Epochs**: Use on-chain snapshot data for reward calculation
221/// - **Historical Epochs**: Use epoch-specific data embedded in the instruction
222/// - **No On-Chain Storage**: Historical data comes with the batch claim instruction
223/// - **Accurate Rewards**: Users get correct rewards for historical activity across all epochs
224///
225/// This enables the Dual Merkle Tree's promise of unlimited claim history without
226/// requiring expensive on-chain storage of historical snapshots.
227///
228/// ## Error Handling
229/// - **No Activity**: Skip epochs with no user activity
230/// - **Invalid Proofs**: Fail on security-critical errors (payment or seal)
231/// - **Batch Limits**: Respect max_batch_size to prevent gas limit issues
232/// - **Pool Limits**: Validate against both payment and social pool limits
233#[repr(C)]
234#[derive(Clone, Copy, Debug, Pod, Zeroable)]
235pub struct BatchClaim {
236 /// Start epoch for range claims (inclusive)
237 pub start_epoch: [u8; 8],
238
239 /// End epoch for range claims (inclusive)
240 pub end_epoch: [u8; 8],
241
242 /// Participant type: 0 for customer, 1 for merchant
243 pub participant_type: u8,
244
245 /// Claim type: 0=range, 1=vector, 2=date_range
246 pub claim_type: u8,
247
248 /// Number of epochs for vector claims
249 pub epoch_count: u8,
250
251 /// Maximum epochs to process (gas limit protection)
252 pub max_batch_size: u8,
253
254 /// Padding to ensure proper alignment (4 bytes)
255 pub _padding: [u8; 4],
256}
257
258#[repr(C)]
259#[derive(Clone, Copy, Debug, Pod, Zeroable)]
260pub struct UpdateSnapshot {
261 pub epoch: [u8; 8], // Epoch number
262
263 /// The seal merkle root of all historical payment merkle roots
264 /// This is the root of the incremental seal merkle tree containing all payment roots
265 pub seal_merkle_root: [u8; 32],
266
267 /// The payment merkle root for the current epoch
268 /// Used to compute epoch hash for tamper detection in the Epoch Hash Chain security solution
269 pub payment_merkle_root: [u8; 32],
270
271 /// Epoch hash for tamper detection in the Epoch Hash Chain security solution
272 /// This field is computed as Hash(previous_epoch_hash + current_payment_merkle_root)
273 pub epoch_hash: [u8; 32],
274
275 pub customer_reward_pool: [u8; 8], // Customer reward pool for this epoch
276 pub merchant_reward_pool: [u8; 8], // Merchant reward pool for this epoch
277 pub customer_participants: [u8; 4], // Total customer participants
278 pub merchant_participants: [u8; 4], // Total merchant participants
279 pub total_customer_payments: [u8; 4], // Total customer payment count (activities)
280 pub total_merchant_payments: [u8; 4], // Total merchant payment count (activities)
281}
282
283/// Update community targets, activity limits, and claim rewards threshold.
284/// This instruction allows the oracle to update community health targets, activity limits,
285/// and claim rewards threshold based on real-world community performance and operational needs.
286///
287/// ## Data Structure
288/// Fixed-size struct (28 bytes) containing all configurable parameters:
289///
290/// ```rust
291/// struct UpdateTargets {
292/// // Claim Rewards Threshold
293/// claim_rewards_threshold: [u8; 8], // u64
294///
295/// // Community Health Targets
296/// target_weekly_users: [u8; 4], // u32
297/// target_weekly_activity: [u8; 4], // u32
298/// target_retention_rate: [u8; 2], // u16
299///
300/// // Activity Limits
301/// max_customer_activity_per_epoch: [u8; 4], // u32
302/// max_merchant_activity_per_epoch: [u8; 4], // u32
303/// activity_cap_enabled: u8, // u8
304/// claim_cap_enabled: u8, // u8
305///
306/// // Padding
307/// _padding: [u8; 4], // 4 bytes padding
308/// }
309/// ```
310///
311/// ## Parameters
312/// - `target_weekly_users`: Target weekly active users (default: 10,000)
313/// - `target_weekly_activity`: Target weekly activity count (default: 50,000)
314/// - `target_retention_rate`: Target retention rate in basis points (default: 7,000 = 70%)
315/// - `max_customer_activity_per_epoch`: Max customer activities per epoch (default: 5)
316/// - `max_merchant_activity_per_epoch`: Max merchant activities per epoch (default: 50)
317/// - `activity_cap_enabled`: Whether activity capping is enabled (default: 1 = enabled)
318/// - `claim_cap_enabled`: Whether claim capping is enabled (default: 1 = enabled)
319/// - `claim_rewards_threshold`: Risk threshold for rewards claim requests (default: BASE_DAILY_REWARDS)
320///
321/// ## Authority
322/// - **Oracle Authority**: Only the oracle can update these parameters
323/// - **Rationale**: Oracle has the data to make informed decisions about community health
324///
325/// ## Benefits
326/// - **Operational Flexibility**: Adjust parameters based on real community performance
327/// - **Anti-Gaming**: Update activity limits to prevent new gaming strategies
328/// - **Community Adaptation**: Adjust targets as community grows and evolves
329/// - **Economic Balance**: Fine-tune parameters for sustainable tokenomics
330/// - **Risk Management**: Adjust claim rewards threshold based on market conditions
331#[repr(C)]
332#[derive(Clone, Copy, Debug, Pod, Zeroable)]
333pub struct UpdateTargets {
334 /// Risk threshold for rewards claim requests.
335 pub claim_rewards_threshold: [u8; 8], // u64
336
337 /// Target weekly active users for sustainable rewards.
338 pub target_weekly_users: [u8; 4], // u32
339
340 /// Target weekly activity count for sustainable rewards.
341 pub target_weekly_activity: [u8; 4], // u32
342
343 /// Maximum customer activity count per epoch (prevents payment splitting).
344 pub max_customer_activity_per_epoch: [u8; 4], // u32
345
346 /// Maximum merchant activity count per epoch (prevents payment splitting).
347 pub max_merchant_activity_per_epoch: [u8; 4], // u32
348
349 /// Target weekly retention rate in basis points (0-10000).
350 pub target_retention_rate: [u8; 2], // u16
351
352 /// Whether activity capping is enabled (1=enabled, 0=disabled).
353 pub activity_cap_enabled: u8, // u8
354
355 /// Whether claim capping is enabled (1=enabled, 0=disabled).
356 pub claim_cap_enabled: u8, // u8
357
358 /// Padding to ensure proper alignment (4 bytes).
359 pub _padding: [u8; 4],
360}
361
362/*
363/// ## Off-Chain Development
364/// When building batch claim instructions off-chain:
365/// 1. Set claim parameters (participant_type, claim_type, start/end epochs, etc.)
366/// 2. For each epoch in the batch:
367/// - Generate payment proof and indices
368/// - Generate seal proof and indices
369/// - Include epoch-specific data (EpochClaimData) for accurate historical calculations
370/// 3. Append social flags array (1 byte per epoch)
371/// 4. Append social data array for epochs with social claims
372/// 5. Verify total instruction size doesn't exceed Solana limits
373///
374/// ## Epoch Data Requirements
375/// - **Current Epoch Claims**: Can omit epoch data (uses on-chain snapshot)
376/// - **Historical Epoch Claims**: Must include epoch-specific data for each epoch
377/// - **Mixed Batches**: Include epoch data only for historical epochs
378/// - **Validation**: Ensure epoch data matches the specific epoch being claimed
379*/
380instruction!(MiracleInstruction, BatchClaim);
381instruction!(MiracleInstruction, Claim);
382instruction!(MiracleInstruction, Close);
383instruction!(MiracleInstruction, Open);
384instruction!(MiracleInstruction, Reset);
385
386instruction!(MiracleInstruction, Initialize);
387
388instruction!(MiracleInstruction, UpdateMetrics);
389instruction!(MiracleInstruction, UpdateOracle);
390instruction!(MiracleInstruction, UpdateSnapshot);
391instruction!(MiracleInstruction, UpdateTargets);