> For the complete documentation index, see [llms.txt](https://docs.t-rex.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.t-rex.network/t-rex-network/t-rex-apps/dino/dino-primary/admin-and-management.md).

# Admin & Management

This page explains **how to operate and configure** the Dino Primary contract:

* How access control works (roles & responsibilities)
* Which functions are available to admins, token managers, and rules managers
* How payment tokens, subscription windows, redemption windows and malus are configured
* How fees and events fit into the operational model

For Solidity interfaces, function signatures, and low-level integration details, see the [**Dino Primary – Developer Reference**](/t-rex-network/t-rex-apps/dino/dino-primary/developer-reference.md)

## Access Control System

Dino Primary uses [OpenZeppelin’s **AccessManager**](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessManager) to enforce fine-grained permissions.

Instead of hard-coding `onlyOwner` logic, each mutating function is protected by AccessManager, which checks whether the caller has the appropriate **role** before allowing execution.

### Roles

Dino Primary defines three logical roles:

| Role                 | Value | Description                                                     | Typical Holder(s)                          |
| -------------------- | ----- | --------------------------------------------------------------- | ------------------------------------------ |
| `ADMIN_ROLE`         | `0`   | Global administrative role                                      | Issuer Safe / Issuer Ops / Governance Safe |
| `TOKEN_MANAGER_ROLE` | `1`   | Manages accepted payment tokens                                 | Issuer Treasury / Ops Team                 |
| `RULES_MANAGER_ROLE` | `2`   | Manages subscription & redemption rules (timing, limits, malus) | Issuer Risk / Product / Compliance         |

{% hint style="info" %}
The numeric values (`0`, `1`, `2`, …) are configured in the AccessManager contract. Dino Primary only checks that the caller is **authorized** for a given function via its `restricted` modifier; it is the AccessManager that maps accounts to roles.
{% endhint %}

### How Roles Are Granted

Roles are not granted directly by Dino Primary itself. Instead:

1. Dino Primary is deployed and **initialized** with the address of an `AccessManager` contract.
2. That AccessManager is responsible for:
   * Attaching permissions to each Dino Primary function selector
   * Assigning roles to actual addresses (EOAs, multisigs, other contracts).

Typical pattern:

* The Token Owner is set as **admin** of the AccessManager.
* The Token Owner then assigns:
  * `ADMIN_ROLE` to the issuer’s main treasury or governance multisig;
  * `TOKEN_MANAGER_ROLE` to treasury/ops;
  * `RULES_MANAGER_ROLE` to the team in charge of product / risk / compliance.

{% hint style="success" %}
In practice, you usually want:

* A **multisig** (e.g. Safe) to hold `ADMIN_ROLE`;
* One or more dedicated ops / treasury addresses to hold `TOKEN_MANAGER_ROLE`;
* A separated address (or multisig) for `RULES_MANAGER_ROLE` to keep configuration changes auditable and controlled.
  {% endhint %}

### Admin Management Settings (`ADMIN_ROLE`)

Holders of `ADMIN_ROLE` can manage **core configuration** of Dino Primary.

#### Core Admin Functions

| Setting          | Function           | Role         | Description                                                                 |
| ---------------- | ------------------ | ------------ | --------------------------------------------------------------------------- |
| Issuer Safe      | `updateIssuerSafe` | `ADMIN_ROLE` | Updates the address receiving subscription proceeds and paying redemptions. |
| Preminted Status | `updatePreminted`  | `ADMIN_ROLE` | Sets whether the asset is **preminted** or not.                             |

#### Issuer Safe

The **issuer safe** is the central wallet used for:

* **Subscriptions**: subscription proceeds (payment tokens) are sent *to* this address.
* **Redemptions**: redemption payments (payment tokens) are paid *from* this address.

Changing the issuer safe:

* Does **not** affect past transactions,
* But all future fund flows will use the new address.

{% hint style="warning" %}
Make sure the new issuer safe:

* Is under appropriate control (e.g. issuer’s treasury multisig),
* Holds enough balance of each **payment token** to fulfil redemptions,
* Is properly set up so that the `DinoPrimary` contract has an allowance to transfer payment tokens out of the issuer safe address for paying redemptions.
* Is properly integrated with your off-chain bookkeeping and reporting.
  {% endhint %}

#### **Preminted vs Non-Preminted Mode**

The `preminted` flag indicates **how the ERC-3643 token supply is handled**:

* `preminted = true`
  * The issuer has already **minted** a supply of tokens into a treasury address.
  * Dino Primary will **transfer** tokens from that treasury to investors on subscription, and back to treasury on redemption.
* `preminted = false`
  * Token supply is minted **on demand**.
  * Dino Primary acts as an **authorized agent** on the ERC-3643 token and:
    * **Mints** new tokens directly to the investor on subscription;
    * **Burns** tokens from the investor on redemption.

{% hint style="info" %}
The choice between preminted / non-preminted is defined at product design level. Changing it mid-life is a sensitive operation and should be aligned with your token economics and legal documentation.
{% endhint %}

### Token Manager Settings (`TOKEN_MANAGER_ROLE`)

Holders of `TOKEN_MANAGER_ROLE` configure which **payment tokens** can be used for subscriptions and redemptions, and how they are priced.

#### Payment Token Management

Dino Primary exposes three management functions:

| Setting              | Function             | Role                 | Description                                                              |
| -------------------- | -------------------- | -------------------- | ------------------------------------------------------------------------ |
| Add Payment Token    | `addPaymentToken`    | `TOKEN_MANAGER_ROLE` | Registers a new payment token with its price feed and stability flag.    |
| Remove Payment Token | `removePaymentToken` | `TOKEN_MANAGER_ROLE` | Deregisters a payment token (no longer accepted for new flows).          |
| Update Payment Token | `updatePaymentToken` | `TOKEN_MANAGER_ROLE` | Updates price feed and/or stability status of an existing payment token. |

Each payment token is associated with:

* `token` – ERC-20 address of the payment token;
* `priceFeed` – an oracle contract implementing the [AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference#aggregatorv3interface);
* `isStable` – boolean indicating whether the token is considered *stable* vs the pricing currency used for the asset (e.g. NAV in USD).

{% hint style="info" %}

* For **stable tokens** (e.g. fully backed USD stablecoins), the price feed may be trivial (1:1) or reflect a tight peg.
* For **non-stable tokens** (e.g. volatile crypto), Dino Primary uses the price feed to compute how many asset tokens correspond to a given payment amount.
  {% endhint %}

#### Operational Guidelines

* Only add payment tokens that:
  * Have reliable liquidity and oracle feeds;
  * Are supported by your compliance / risk policies.
* Removing a payment token:
  * Does **not** affect past subscriptions/redemptions,
  * But prevents **new** operations using that token.
* Updating a price feed is **sensitive**:
  * Always ensure the feed address is correct and from a trusted oracle provider;
  * Consider multi-sig confirmation or governance procedures for changes.

### Rules Manager Settings (`RULES_MANAGER_ROLE`)

Holders of `RULES_MANAGER_ROLE` configure **when** subscriptions/redemptions are allowed and within which **limits**, plus the **malus** applied on redemption.

#### Subscription Rules

Subscription rules are updated via:

| Setting            | Function                  | Role                 | Description                                 |
| ------------------ | ------------------------- | -------------------- | ------------------------------------------- |
| Subscription Rules | `updateSubscriptionRules` | `RULES_MANAGER_ROLE` | Sets subscription period and amount limits. |

Parameters:

* `dateOpened` – timestamp when subscriptions become possible;
* `dateClosed` – optional timestamp when subscriptions end (`0` may mean “no end”);
* `minAmount` – minimum amount of ERC-3643 tokens that an investor can subscribe in a single transaction;
* `maxAmount` – maximum amount of ERC-3643 tokens that an investor can subscribe in a single transaction.

Subscriptions are only accepted when:

* `dateOpened <= block.timestamp`, and
* `dateClosed == 0` *or* `block.timestamp <= dateClosed`, and
* `minAmount <= amount <= maxAmount`.

{% hint style="success" %}
You can use `minAmount` / `maxAmount` to enforce ticket size policies (e.g. minimum investment amount or tranche-specific caps). It can be combined with specific Compliance Modules on the ERC-3643 token to limit volumes on a time basis or holdings per investor for example.
{% endhint %}

#### Redemption Rules & Malus

Redemption rules are updated via:

| Setting          | Function                | Role                 | Description                                                                 |
| ---------------- | ----------------------- | -------------------- | --------------------------------------------------------------------------- |
| Redemption Rules | `updateRedemptionRules` | `RULES_MANAGER_ROLE` | Sets redemption period, amount limits, and **redemption malus** percentage. |

Parameters mirror subscription rules, with one extra field:

* `redemptionMalus` – a **basis point** value (e.g. 100 = 1%, 500 = 5%) representing a haircut applied to redemption amounts.

When investors redeem:

1. Dino Primary computes the gross amount owed based on the asset price and quantity.
2. It applies the **malus**:
   * Malus amount = `grossAmount * malusBps / 10_000`;
   * Net paid to investor = `grossAmount - malusAmount`.

This allows the issuer to model:

* Exit penalties,
* Early redemption haircuts,
* Liquidity management fees.

{% hint style="danger" %}
Any change to redemption rules (especially `malus`) should be clearly disclosed to investors and reflected in legal / regulatory documentation.
{% endhint %}

### Fee System

Dino Primary integrates with the **T-REX Ecosystem Fee Collector** to charge protocol-level fees on top of the asset economics.

#### Operation Fees

Per design, Dino Primary applies **multipliers** on a base ecosystem fee:

| Operation | Fee Multiplier | Description                                  |
| --------- | -------------- | -------------------------------------------- |
| Subscribe | `3x` base fee  | Fee charged on each subscription transaction |
| Redeem    | `3x` base fee  | Fee charged on each redemption transaction   |

The **base fee**, fee token, and recipient are managed by the **ecosystem fee collector**, not by the Dino Primary contract itself.

#### Fee Collection Flow

* On each subscription or redemption:
  * Dino Primary calls `ecosystemFeeCollector.collectFee(msg.sender, FEE_MULTIPLIER_*)`.
  * The user must have:
    * **Approved** the fee token for the ecosystem fee collector;
    * Sufficient fee token balance.

{% hint style="info" %}
Issuers do *not* configure fee amounts inside Dino Primary. They only need to ensure users are aware of the ecosystem fee and that the fee set at the protocol level is acceptable for their use case.
{% endhint %}

{% hint style="success" %}
A fee abstraction layer can be used to allow users to pay the ecosystem fees with any payment token for more convenience and reduced user friction.
{% endhint %}

### Events & Monitoring

Dino Primary emits events for all important administrative and economic actions. These can be indexed by back-office systems, analytics, and monitoring tools.

#### Admin / Config Events

| Event                      | Description                                               |
| -------------------------- | --------------------------------------------------------- |
| `IssuerSafeUpdated`        | Emitted when the issuer safe address is changed.          |
| `PremintedUpdated`         | Emitted when the `preminted` status is updated.           |
| `PaymentTokenAdded`        | Emitted when a new payment token is added.                |
| `PaymentTokenRemoved`      | Emitted when a payment token is removed.                  |
| `PaymentTokenUpdated`      | Emitted when a payment token’s feed/stability is updated. |
| `SubscriptionRulesUpdated` | Emitted when subscription rules are changed.              |
| `RedemptionRulesUpdated`   | Emitted when redemption rules / malus are changed.        |

#### Economic Events

| Event        | Description                               |
| ------------ | ----------------------------------------- |
| `Subscribed` | Emitted on every successful subscription. |
| `Redeemed`   | Emitted on every successful redemption.   |

Each `Subscribed` / `Redeemed` event contains the **nonce**, investor, amounts and payment token, allowing:

* Portfolio reconstruction,
* Regulatory reporting,
* Reconciliation with off-chain systems (fund admin, custodian, TA, etc.).

#### AccessManaged Events

Inherited from the AccessManaged / AccessManager system:

| Event              | Description                                                         |
| ------------------ | ------------------------------------------------------------------- |
| `AuthorityUpdated` | Emitted when the AccessManager controlling Dino Primary is updated. |

{% hint style="success" %}
In production, you should index at least: `IssuerSafeUpdated`, `PaymentToken*`, `SubscriptionRulesUpdated`, `RedemptionRulesUpdated`, `Subscribed`, and `Redeemed`. This makes it easy to audit configuration changes and reconstruct investor activity.
{% endhint %}

### Typical Operational Lifecycle

Putting it all together, a typical lifecycle for a new asset is:

1. **Deployment & Initialization**
   * Dino Primary is deployed and initialized with:
     * ERC-3643 token address,
     * Initial issuer safe,
     * `preminted` flag,
     * AccessManager address,
     * Ecosystem fee collector.
2. **Role Assignment**
   * AccessManager admin assigns:
     * `ADMIN_ROLE` to issuer governance / treasury,
     * `TOKEN_MANAGER_ROLE` to treasury/ops,
     * `RULES_MANAGER_ROLE` to risk/product/compliance.
3. **Payment Token Setup**
   * `TOKEN_MANAGER_ROLE` adds one or more payment tokens (USD1, USDC, etc.) with price feeds.
4. **Rule Setup**
   * `RULES_MANAGER_ROLE` sets initial subscription and redemption rules (dates, min/max, malus).
5. **Operation**
   * Investors subscribe and redeem via connected dApps/platforms.
   * Ops teams can adjust rules, add/remove payment tokens, and eventually update issuer safe if needed.
6. **Monitoring**
   * Back-office systems listen to events to track configuration changes and investor activity.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.t-rex.network/t-rex-network/t-rex-apps/dino/dino-primary/admin-and-management.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
