# Instrument Registry

## Overview <a href="#overview" id="overview"></a>

The Instrument Registry (<mark style="color:red;">`InstrumentRegistry.sol`</mark>) is used to store information about instruments. In addition to the logic for creating and initializing instruments, it also contains functions to aid with the instrument lifecycle. Like most registries, it makes use of the eternal storage pattern to store information, inheriting the base registry. The Instrument Registry uses instrument Ids to store their corresponding data.

## Instrument

Instruments contain all the logic for the tokenization engine. Their data is managed at a high level by the instrument registry, which also contains the logic for creating and initializing them.

### Instrument Creation

* **Function**: `addInstrument(bytes32 _senderRole, bytes32 _instrumentId, bytes32 _fundId)`
* **Purpose**: Creates a new Instrument in the KAIO system, seting all the required values.
* **Parameters**:
  * `bytes32 _senderRole`: Role of the caller.
  * `bytes32 _instrumentId`: Id of the instrument to create.
  * `bytes32 _fundId`: Id of the fund the instrument will belong to.
* **Validation Checks**:
  * Checks the fund Id is not 0.
  * Ensures the caller is the corresponding fund admin or otherwise has a valid role.
  * Makes sure the instrument does not already exist.
* **Behavior**:
  * Creates the new instrument in the system.
  * Emits a `NewInstrumentAdded` event, signaling the instrument has been created.
* **Example**:

  ```solidity
  addInstrument(0xFundAdminRole, 0xInstrumentId, 0xFundId);
  ```

### Instrument Initialization

* **Function**: `initializeInstrument( bytes32 _senderRole, bytes32 _instrumentId, address _paymentToken, address _rulesEngineImpl, string _name, string _symbol, address _subscriptionBookImp, address _redemptionBookImp, address _stTokenImpl, address _treasury )`
* **Purpose**: Initializes a newly created instrument, to get it ready for operation. This includes deploying necessary contract and setting configuration values.
* **Parameters**:
  * `bytes32 _senderRole`: Role of the caller.
  * `bytes32 _instrumentId`: Id of the instrument.
  * `address _paymentToken`: Address of the settlement token to be used for payments.
  * `address _rulesEngineImpl`: Address of the rules engine to clone as a base for the instrument's rules engine.
  * `string _name`: Name given to the instrument's security token.
  * `string _symbol`: Symbol given to the instrument's security token.
  * `address _subscriptionBookImp`: Address of the subscription book to clone as a base for the instrument's subscription book.
  * `address _redemptionBookImp`: Address of the redemption book to clone as a base for the instrument's redemption book.
  * `address _stTokenImpl`: Address of the security token to clone as a base for the instrument's security token.
  * `address _treasury`: Address of the treasury where collected fees will be sent.
* **Validation Checks**:
  * Ensures the caller is the corresponding fund admin or otherwise has a valid role.
  * Makes sure the instrument is not already initialized.
* **Behavior**:
  * Sets reserved keys for the instrument in the eternal registry.
  * Creates and initializes the instrument's rules engine.
  * Creates and initializes the instrument's subscription book.
  * Creates and initializes the instrument's redemption book.
  * Creates and initializes the instrument's security token.
  * Grants settlement token burner and minter roles to the subscription and redemption books respectively.
  * Emits a `InstrumentInitialized` event, signaling the instrument has been initialized.
* **Example**:

  ```solidity
  initializeInstrument(0xFundAdminRole, 0xInstrumentId, 0xSettlementToken, 0xRulesEngineImp, "Tokenized Fund 1", "TF1", 0xSubscriptionBookImp, 0xRedemptionBookIpm, 0xSecurityTokenImp, 0xTreasury);
  ```

## Access

Some instruments are configured to require investors to be explicitly allowed in order to use them, instead of only requiring their dealer to have access.

### Investor Access

* **Function**: `allowInvestor(bytes32 _instrumentId, bytes32 _investorId, bool _allowed, bytes32 _senderRole)`
* **Purpose**: Manually allows or un-allows an investor into an instrument.
* **Parameters**:
  * `bytes32 _instrumentId`: Id of the instrument.
  * `bytes32 _investorId`: Id of the investor.
  * `bool _allowed`: Signals if the investor should be allowed or un-allowed.
  * `bytes32 _senderRole`: Role of the caller.
* **Validation Checks**:
  * Ensures the caller is the corresponding fund admin or otherwise has a valid role.
* **Behavior**:
  * Allows or un-allows investor from the instrument.
  * Emits a `investorAllowedUpdated` event, signaling the investor access to the instrument has changed.
* **Example**:

  ```solidity
  allowInvestor(0xInstrumentId, 0xInvestorId, true, 0xFundAdminRole);
  ```

## Lifecycle

The lifecycle of an instrument includes regular updates such as Net Asset Value (NAV) updates, which are done through the instrument registry. In addition some functions are available to read information related to the current state of the instrument.

### NAV Update (Unaudited)

* **Function**: `updateUnauditedNavPerShare(bytes32 _senderRole, bytes32 _instrumentId, uint256 _newNavPerShare)`
* **Purpose**: Updates the value of the NAV of the instrument (unaudited, per share).
* **Parameters**:
  * `bytes32 _senderRole`: Role of the caller.
  * `bytes32 _instrumentId`: Id of the instrument.
  * `uint256 _newNavPerShare`: New value of the NAV price.
* **Validation Checks**:
  * Ensures the caller is the corresponding fund admin or otherwise has a valid role.
* **Behavior**:
  * Updates the unaudited NAV.
  * Stores new NAV data for lookback purposes.
  * Checks and sets the `GLOBAL_AGGREGATE_MINIMUM_BREACH` according to the new NAV.
* **Example**:

  ```solidity
  updateUnauditedNavPerShare(0xFundAdminRole, 0xInstrumentId, 46200);
  ```

### NAV Update (Audited)

* **Function**: `updateAuditedNavPerShare(bytes32 _senderRole, bytes32 _instrumentId, uint256 _newNavPerShare)`
* **Purpose**: Updates the value of the NAV of the instrument (audited, per share).
* **Parameters**:
  * `bytes32 _senderRole`: Role of the caller.
  * `bytes32 _instrumentId`: Id of the instrument.
  * `uint256 _newNavPerShare`: New value of the NAV price.
* **Validation Checks**:
  * Ensures the caller is the corresponding fund admin or otherwise has a valid role.
* **Behavior**:
  * Updates the audited NAV.
  * Checks and sets the `GLOBAL_AGGREGATE_MINIMUM_BREACH` according to the new NAV.
* **Example**:

  ```solidity
  updateAuditedNavPerShare(0xFundAdminRole, 0xInstrumentId, 38100);
  ```

### Getting NAV Lookback (Unaudited)

* **Function**: `getNavLookback(bytes32 _instrumentId, uint256 _timestamp)`
* **Purpose**: Returns the maximum unaudited NAV value stored in the lookback from the provided date to the present.
* **Parameters**:
  * `bytes32 _instrumentId`: Id of the instrument.
  * `uint256 _timestamp`: Timestamp indicating the date to perform the lookback to.
* **Return Values:**
  * `uint256`: Indicates the highest unaudited NAV value stored after the provided timestamp.
* **Example**:

  ```solidity
  getNavLookback(0xInstrumentId, 1714880880);
  ```

### Getting Subscription Period

* **Function**: `currentSubscriptionPeriod(bytes32 _instrumentId)`
* **Purpose**: Returns the current subscription period number, along with the start and end timestamps. Can return 0 when the first subscription period has not started, or *type(uint256).max* if the last period has ended.
* **Parameters**:
  * `bytes32 _instrumentId`: Id of the instrument.
* **Return Values:**
  * `uint256`: Current subscription period number.
  * `uint256`: Timestamp indicating the start of the current subscription period.
  * `uint256`: Timestamp indicating the end of the current subscription period.
* **Example**:

  ```solidity
  currentSubscriptionPeriod(0xInstrumentId);
  ```

### Getting Redemption Period

* **Function**: `currentRedemptionPeriod(bytes32 _instrumentId)`
* **Purpose**: Returns the current redemption period number, along with the start and end timestamps. Can return 0 when the first redemption period has not started, or *type(uint256).max* if the last period has ended.
* **Parameters**:
  * `bytes32 _instrumentId`: Id of the instrument.
* **Return Values:**
  * `uint256`: Current redemption period number.
  * `uint256`: Timestamp indicating the start of the current redemption period.
  * `uint256`: Timestamp indicating the end of the current redemption period.
* **Example**:

  ```solidity
  currentRedemptionPeriod(0xInstrumentId);
  ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kaio.xyz/how-kaio-works/smart-contracts/registries/instrument-registry.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
