Description
RWA securities typically have lock-up periods where shares cannot be transferred or redeemed for a specified duration after purchase. The current contract allows immediate transfer of shares after deposit — a user can deposit, receive shares, and transfer them in the same ledger. This undermines:
- Regulatory compliance — many jurisdictions require holding periods for securities
- Anti-speculation — prevents deposit-and-flip arbitrage
- Yield fairness — prevents gaming the epoch snapshot system by depositing just before a yield distribution and transferring immediately after
Requirements
- Add a
lock_up_period: u64 field to InitParams (seconds after deposit during which shares are non-transferable)
- Store
DataKey::DepositTimestamp(Address) → u64 — the timestamp of the user's last deposit
- In
transfer, transfer_from, withdraw, redeem, and request_early_redemption: check that e.ledger().timestamp() >= deposit_timestamp + lock_up_period
redeem_at_maturity should bypass the lock-up (the vault has matured, users must be able to exit)
- Add error variant:
Error::SharesLocked
- Add a view function:
lock_up_remaining(user: Address) -> u64
- Allow admin to update
lock_up_period for future deposits (existing deposits keep their original lock-up)
Key Files
- types.rs —
InitParams new field
- lib.rs —
transfer, transfer_from, withdraw, redeem, request_early_redemption
- storage.rs — new
LockUpPeriod, DepositTimestamp(Address) keys
- errors.rs — new
SharesLocked variant
Definition of Done
Description
RWA securities typically have lock-up periods where shares cannot be transferred or redeemed for a specified duration after purchase. The current contract allows immediate transfer of shares after deposit — a user can deposit, receive shares, and transfer them in the same ledger. This undermines:
Requirements
lock_up_period: u64field toInitParams(seconds after deposit during which shares are non-transferable)DataKey::DepositTimestamp(Address) → u64— the timestamp of the user's last deposittransfer,transfer_from,withdraw,redeem, andrequest_early_redemption: check thate.ledger().timestamp() >= deposit_timestamp + lock_up_periodredeem_at_maturityshould bypass the lock-up (the vault has matured, users must be able to exit)Error::SharesLockedlock_up_remaining(user: Address) -> u64lock_up_periodfor future deposits (existing deposits keep their original lock-up)Key Files
InitParamsnew fieldtransfer,transfer_from,withdraw,redeem,request_early_redemptionLockUpPeriod,DepositTimestamp(Address)keysSharesLockedvariantDefinition of Done
redeem_at_maturitybypasses lock-up