PaymentToken is now locked only by the first successful deposit_revenue
or deposit_revenue_with_snapshot call for an offering.
This hardening restores the storage model documented in the contract:
PaymentToken(OfferingId)records the canonical payout token only after successPeriodRevenue(OfferingId, period_id)records one successful deposit per periodPeriodEntry(OfferingId, index)enumerates only successfully deposited periods
There is no fallback from PaymentToken to Offering.payout_asset during
deposit processing or get_payment_token reads.
get_payment_tokenreturnsNoneif the offering is unknown or if the offering exists but has not yet recorded a successful deposit.- The first successful deposit writes
PaymentToken = payment_token. - Subsequent deposits must use that exact token or fail with
RevoraError::PaymentTokenMismatch. - Duplicate period deposits fail with
RevoraError::PeriodAlreadyDeposited. - Failed deposits do not write
PaymentToken,PeriodRevenue,PeriodEntry,PeriodCount, orLastPeriodId.
- Payment-token locking is success-based:
- A token is canonical only after a transfer-backed deposit succeeds.
- Validation failures or transfer failures must not partially initialize lock state.
- Asset identity is explicit:
- The contract never silently coerces
payment_tokenfrompayout_asset. - Integrators must pass the intended payout token on the first successful deposit.
- Retry safety is required:
- A failed first deposit for
period_id = Nmust leaveNreusable for a correct retry. - This prevents accidental
InvalidPeriodIdorPaymentTokenMismatchoutcomes on correct follow-up sequencing.
- Duplicate periods fail closed:
- Once
PeriodRevenue(offering, period_id)exists, the sameperiod_idis always rejected as already deposited.
Covered in src/test.rs:
register_offering_does_not_lock_payment_token_before_first_depositfailed_first_deposit_does_not_lock_payment_token_or_consume_periodfirst_deposit_uses_registered_payment_token_locksecond_deposit_rejects_wrong_payment_token_without_mutating_statedeposit_revenue_fails_for_duplicate_period- zero-amount and invalid-period rejection without lock mutation
PaymentTokenMismatchis now reserved for a real post-lock mismatch.- Correct integrator sequencing cannot trigger that error accidentally before any successful deposit has established the lock.