> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trusset.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practices

> Security considerations, operational patterns, and regulatory alignment for commodity token deployments.

This page covers operational and security patterns for running commodity token deployments in production. These recommendations apply to all contracts in the Commodity Token License suite.

## Access Control

**Use multisigs for all privileged roles.** The factory `admin`, token `mainIssuer`, token `upgradeAuthority`, identity registry `DEFAULT_ADMIN_ROLE`, and `LEGAL_OPERATOR_ROLE` should all be Gnosis Safe multisigs with appropriate signer thresholds. A single compromised EOA controlling any of these roles can drain or freeze the entire token.

**Separate the main issuer from operational delegates.** The `mainIssuer` role should be a cold multisig used only for high-impact operations: transferring the issuer role, setting the upgrade authority, and configuring sub-issuers. Day-to-day operations (pausing, freezing, whitelist management) should go through delegates. This limits the blast radius of a compromised operational key.

**Set mint limits on sub-issuers.** Any address configured as a minter via `configureIssuer` should have a non-zero `mintLimit` proportional to expected activity. A sub-issuer with `mintLimit = 0` (unlimited) has the same minting power as the main issuer. Review and adjust limits periodically.

**Isolate the upgrade authority from day-to-day operations.** The `upgradeAuthority` (TrussetDAO) has narrow but critical powers: proposing implementation upgrades and rotating the `platformWallet` via `updatePlatformWallet`. It should be a separate multisig from the `mainIssuer` so that neither side can unilaterally alter contract logic or redirect fee flows. Upgrades require both parties to sign off, and the platform wallet rotation path is intentionally locked to the DAO to prevent an issuer from unilaterally stripping the protocol fee share.

**Scope the keeper relayer tightly.** The `keeperRelayer` address is a published coordination target for off-chain automation that executes approved mint and burn requests. On-chain it holds no special privileges, but your off-chain systems and monitoring should gate sensitive automation logic to this exact address. Treat the keeper key as hot, rotate it regularly via `setKeeperRelayer`, and alert on requests executed from unexpected relayers.

**Rotate KYC provider keys.** The `KYC_PROVIDER_ROLE` on the identity registry can verify arbitrary identities. If a provider key is compromised, revoke it immediately via `removeKYCProvider` and re-grant to a new address.

## Reserve Management

**Update attestations on a regular cadence.** Call `updateReserveAttestation` at least as frequently as your custody provider issues vault reports. The on-chain `reserveAttestationURI` should always point to the most recent third-party attestation. Stale attestation URIs undermine investor confidence even if the reserve ratio is technically valid.

**Never call `updateReserveAttestation` with a `totalGrams` value you cannot prove.** The contract enforces that the reserve ratio holds, but it cannot verify that the grams actually exist in a vault. The attestation URI and vault location hash are your proof layer - ensure they reference verifiable, auditable documents.

**Monitor `isReserveCompliant()` off-chain.** Set up automated monitoring that calls this view function and alerts if it ever returns `false`. While the contract prevents minting into a non-compliant state, manual reserve updates that incorrectly lower `totalGramsReserve` could create a compliance gap.

## Oracle Configuration

**Set `maxOracleAge` conservatively.** The default of 3600 seconds (1 hour) is appropriate for most commodity markets. For highly volatile assets or during market stress, consider reducing this to 900-1800 seconds. An oracle that has not updated within `maxOracleAge` will cause all cash redemptions and oracle-priced sales to revert.

**Use a dedicated oracle per token.** Even if multiple tokens reference the same underlying commodity, deploy separate oracle instances. This prevents a single oracle failure from cascading across tokens and allows per-token staleness configuration.

**Test oracle failure modes.** Before going live, verify that your system handles `OraclePriceStale` reverts gracefully. Cash redemption and oracle-priced sale purchases will fail when the oracle is stale - your frontend and backend should surface this to users rather than showing generic transaction errors.

## Upgrade Governance

**Review proposed implementations before accepting.** When TrussetDAO proposes an upgrade via `proposeUpgrade`, the issuer should audit the new implementation contract before calling `acceptUpgrade`. Verify the bytecode matches a known, audited version. Never accept an upgrade without reviewing the code.

**Use `rejectUpgrade` explicitly.** If you do not intend to upgrade, call `rejectUpgrade` to clear the pending implementation. Leaving a pending upgrade indefinitely creates confusion about the contract's intended state.

**Test upgrades on a fork first.** Before accepting a production upgrade, deploy the new implementation on a mainnet fork and verify that all state is preserved, all functions behave correctly, and the storage layout is compatible.

## Identity and Compliance

**Set both soft and hard expiry on identities.** The soft expiry triggers `SOFT_EXPIRED` status, which still allows transfers but signals that KYC needs renewal. The hard expiry blocks transfers entirely. Use soft expiry as an early warning (e.g., 30 days before hard expiry) so investors have time to re-verify.

**Use claims for granular attestations.** Rather than encoding all compliance data into the `kycHash`, use the claims system for specific attestations (`ACCREDITATION`, `SANCTIONS_CHECK`, `PEP_CHECK`). This allows revoking individual attestations without invalidating the entire identity.

**Configure compliance modules before enabling KYC on the token.** If you add a compliance module to the identity registry after tokens are already circulating with KYC enabled, existing transfers that were previously valid may start failing. Add and configure modules before going live, or coordinate the rollout carefully.

**Handle `batchVerifyIdentities` partial failures.** The function returns `failedIndices` for entries that could not be processed (invalid data, duplicate identities, or gas exhaustion). Your integration layer should retry failed entries in a subsequent call rather than silently dropping them.

## Sale Operations

**Fund USDC before enabling cash redemption.** The token contract checks `IERC20(usdcToken).balanceOf(address(this))` during cash redemption execution. If the balance is insufficient, the burn request execution reverts with `InsufficientUSDCLiquidity` but the request remains in `APPROVED` state and can be retried after funding.

**Use slippage protection on purchases.** The `maxPayment` parameter in `purchase` protects buyers from oracle price spikes between transaction submission and execution. For oracle-priced sales, recommend that frontends set `maxPayment` to 1-2% above the displayed price.

**Deactivate completed sales.** After a sale round ends or sells out, call `updateSale` to set `active = false`. For pre-funded sales, call `withdrawUnsoldTokens` to recover remaining tokens. Leaving inactive sales in an active state wastes gas on validation checks for purchases that will fail anyway.

## Operational Monitoring

Key on-chain values to monitor continuously:

* `isReserveCompliant()` - should always return `true`
* `totalSupply` vs `maxSupply` - approaching the cap requires either increasing `maxSupply` or stopping mints
* `paused` state - unexpected pauses indicate an incident
* `frozen` accounts - track freezes for compliance reporting
* Oracle `timestamp` freshness - stale oracles block redemptions and sales
* `lockedBalances` - high locked balances indicate pending burn requests that may need attention
* Compliance module `canTransfer` rejections - monitor for unexpected transfer failures that could indicate misconfiguration

## Emergency Procedures

**Pause first, investigate second.** If you detect suspicious activity (unauthorized mints, compromised keys, oracle manipulation), call `pause()` on the token immediately. This halts all transfers, mints, and burns. The identity registry has its own `pause` function for registry-level emergencies.

**Freeze targeted accounts.** If the issue is isolated to specific addresses, use `freezeAccount` on the token and `freezeAddress` on the identity registry. Freezing is less disruptive than a full pause and allows legitimate activity to continue.

**Cancel pending requests.** Use `cancelRequest(requestId, isMint)` to cancel any pending mint or burn requests from compromised sub-issuers. For burn requests, cancellation unlocks the user's tokens.
