diff --git a/sources/ltc1.move b/sources/ltc1.move index 4a4bc47..c8c7791 100644 --- a/sources/ltc1.move +++ b/sources/ltc1.move @@ -113,6 +113,10 @@ public struct LTC1Package has key { // ==================== Initialization ==================== +/// Module initializer. +/// Automatically called when the package is published. Sets up the +/// IOTA Display standard for `LTC1Token` objects. + #[allow(lint(share_owned))] fun init(otw: LTC1, ctx: &mut iota::tx_context::TxContext) { // 1. Claim Publisher @@ -142,6 +146,28 @@ fun init(otw: LTC1, ctx: &mut iota::tx_context::TxContext) { // ==================== Public Functions ==================== +/// Creates a new LTC1 Package (NPL Fractionalization Contract) +/// +/// This is the entry point for Originators to tokenize an NPL package. +/// +/// # Arguments +/// * `registry` - The NPLEX Registry shared object, used to verify authorization. +/// * `name` - The display name of the NPL Package. +/// * `notarization` - The IOTA SDK Notarization object bounding the off-chain documents to this contract. +/// * `total_supply` - The total number of token shares to emit (must be >= `MIN_SUPPLY`). +/// * `token_price` - The price of a single token share in NANOS (1,000,000,000 = 1 IOTA). +/// * `nominal_value` - The gross book value (GBV) of the underlying NPL package. +/// * `investor_split_bps` - The percentage of future revenue destined to investors (in Basis Points). +/// * `metadata_uri` - A link (e.g., IPFS) to the prospectus or public metadata. +/// * `owner_identity` - The Decentralized Identifier (DID) of the Originator/Servicer. +/// * `token` - The sender's `DelegationToken` proving their `ROLE_INSTITUTION` authority. +/// * `clock` - The IOTA system clock for timestamping. +/// +/// # Aborts +/// * `E_INVALID_SPLIT` - if `investor_split_bps` > `MAX_INVESTOR_BPS`. +/// * `E_SUPPLY_TOO_LOW` - if `total_supply` < `MIN_SUPPLY`. +/// * Reverts if the `DelegationToken` does not authorize the caller as an Institution. + public entry fun create_contract( registry: &mut NPLEXRegistry, name: String, @@ -230,9 +256,26 @@ public entry fun create_contract( ); } -/// Buy tokens from the package -/// User specifies how many "shares" they want to buy (`amount`) -/// and provides the Payment in IOTA. +/// Purchase tokens (fractional shares) from the package +/// +/// Investors use this function to finance the NPL package by acquiring `LTC1Token` shares. +/// +/// # Arguments +/// * `registry` - The NPLEX Registry to verify the investor's identity. +/// * `package` - The `LTC1Package` offering the tokens. +/// * `payment` - An IOTA `Coin` used to pay for the tokens. Change is refunded. +/// * `amount` - The number of tokens requested. +/// * `token` - The sender's `DelegationToken` proving their `ROLE_INVESTOR` authority. +/// +/// # Logic +/// Implements "Dividend-stripping protection" by pre-calculating the `initial_claimed` +/// revenue. This ensures the new investor cannot claim past revenue that was generated +/// before they bought the token. The past revenue is credited to the Originator. +/// +/// # Aborts +/// * `E_SALES_CLOSED` - if the package sales are not active. +/// * `E_INSUFFICIENT_SUPPLY` - if the requested `amount` exceeds the `max_sellable_supply`. +/// * `E_INSUFFICIENT_PAYMENT` - if the `payment` coin value is lower than the required cost. public entry fun buy_token( registry: &NPLEXRegistry, package: &mut LTC1Package, diff --git a/sources/registry.move b/sources/registry.move index 4b09320..ca4ff5e 100644 --- a/sources/registry.move +++ b/sources/registry.move @@ -228,10 +228,25 @@ fun init(otw: REGISTRY, ctx: &mut TxContext) { // ==================== Admin Functions ==================== /// Register a new approved notarization in the registry -/// These are the documents which are used only for create_contract -/// Notarizations for other approvals are managed in other tables not in approved_notarizations -/// A note on this: The fact that we pass notarization_id and document_hash instead of the notarization object is because -/// the locked notarization object cannot be traded. The user has to create it and have it audited then pass it to the create_contract function. +/// +/// These are the documents which are used only for `create_contract`. +/// Notarizations for other approvals are managed in other tables, not in `approved_notarizations`. +/// +/// **Note:** We pass `notarization_id` and `document_hash` instead of the `Notarization` object +/// because the locked Notarization object cannot be traded. The user must create it via SDK, +/// have it audited off-chain, and then pass it to the `create_contract` function. +/// +/// # Arguments +/// * `registry` - The NPLEX Registry shared object. +/// * `_admin_cap` - The NPLEX Administrator Capability (authorization). +/// * `notarization_id` - The `ID` of the Notarization object created via SDK. +/// * `document_hash` - The `u256` SHA256/Keccak hash of the off-chain PDF asset document. +/// * `authorized_creator` - The address allowed to consume this hash to create an LTC1. +/// * `clock` - The system clock for auditing timestamp. +/// * `ctx` - Transaction context. +/// +/// # Aborts +/// * `E_NOTARIZATION_ALREADY_USED` - If the `notarization_id` is already registered. public entry fun register_notarization( registry: &mut NPLEXRegistry, _admin_cap: &NPLEXAdminCap, @@ -458,7 +473,25 @@ public entry fun revoke_identity( // ==================== Validation Functions ==================== -/// Claim a notarization to start usage flow +/// Claim a notarization to start the package creation flow +/// +/// Consumes an approved notarization and returns a "Hot Potato" `NotarizationClaim` +/// that must be immediately bound to a new contract via `bind_executor`. +/// +/// # Arguments +/// * `registry` - The NPLEX Registry shared object. +/// * `notarization_id` - The ID of the notarization being claimed. +/// * `document_hash` - The hash of the document, must match the registered one. +/// * `ctx` - Transaction context. +/// +/// # Returns +/// * `NotarizationClaim` - A Hot Potato struct containing the hash and ID. +/// +/// # Aborts +/// * `E_NOTARIZATION_NOT_APPROVED` - If not found or `document_hash` mismatches. +/// * `E_NOTARIZATION_REVOKED` - If it was revoked by NPLEX Admin. +/// * `E_NOTARIZATION_ALREADY_USED` - If it was already bound to a contract. +/// * `E_UNAUTHORIZED_CREATOR` - If the caller is not the `authorized_creator`. public fun claim_notarization( registry: &mut NPLEXRegistry, notarization_id: ID,