@@ -96,7 +96,12 @@ with regulatory required features: freezing, pausing and recovery.
9696
9797### Architecture Overview
9898
99- The T-REX token contract requires only ** two external functions** to operate:
99+ The T-REX token integrates with ** two external contracts** — a Compliance
100+ contract and an Identity Verifier contract — through a small set of hooks. The
101+ token calls these hooks during transfers, minting, burning, and recovery; the
102+ contracts behind them encapsulate all regulatory logic.
103+
104+ For example, the two most visible hooks are:
100105
101106``` rust
102107// Compliance validation - returns true if transfer is allowed
@@ -106,11 +111,20 @@ fn can_transfer(e: &Env, from: Address, to: Address, amount: i128, token: Addres
106111fn verify_identity (e : & Env , user_address : & Address );
107112```
108113
109- - ` can_transfer() ` is expected to be exposed from a "Compliance" contract.
110- - ` verify_identity() ` is expected to be exposed from an "Identity Verifier"
111- contract.
114+ The full hook set is specified later in this document:
115+
116+ - The ** Compliance** contract exposes pre-validation hooks (` can_transfer ` ,
117+ ` can_create ` ) and post-event state-update hooks (` transferred ` , ` created ` ,
118+ ` destroyed ` ). Pre-validation hooks default to ` true ` and post-event hooks
119+ default to no-ops when no compliance modules are registered, so a token with
120+ no modules behaves as if compliance is permissive. See the
121+ [ Compliance Trait] ( #the-compliance-trait ) section for the complete interface.
122+ - The ** Identity Verifier** contract exposes ` verify_identity ` and
123+ ` recovery_target ` (the latter is consumed by ` recover_balance ` ). See the
124+ [ IdentityVerifier Trait] ( #the-identityverifier-trait ) section for the
125+ complete interface.
112126
113- These functions are ** deliberately abstracted** as implementation details,
127+ These hooks are ** deliberately abstracted** as implementation details,
114128enabling:
115129
116130- ** Regulatory Flexibility** : Different jurisdictions can implement different
@@ -120,9 +134,9 @@ enabling:
120134- ** Cost Optimization** : Shared contracts across multiple tokens
121135- ** Future-Proofing** : New compliance approaches without interface changes
122136
123- In other words, the only thing required by this T-REX design, is that the token
124- should be able to call these expected functions made available by the
125- compliance and identity verification contracts.
137+ In other words, the only thing required by this T-REX design is that the token
138+ be able to call the hooks exposed by the compliance and identity verification
139+ contracts.
126140
127141### Contract Connection Interface
128142
@@ -249,7 +263,7 @@ pub trait RWAToken: TokenInterface {
249263 ///
250264 /// * topics - `["transfer", old_account: Address, new_account: Address]`
251265 /// * data - `[amount: i128]`
252- /// * topics - `["recovery ", old_account: Address, new_account: Address]`
266+ /// * topics - `["recovery_success ", old_account: Address, new_account: Address]`
253267 /// * data - `[]`
254268 fn recover_balance (
255269 e : & Env ,
@@ -272,8 +286,7 @@ pub trait RWAToken: TokenInterface {
272286 ///
273287 /// # Events
274288 ///
275- /// * topics - `["address_frozen", user_address: Address, is_frozen: bool,
276- /// operator: Address]`
289+ /// * topics - `["address_frozen", user_address: Address, is_frozen: bool]`
277290 /// * data - `[]`
278291 fn set_address_frozen (e : & Env , user_address : Address , freeze : bool , operator : Address );
279292
@@ -704,6 +717,24 @@ token contract. This allows a single compliance contract to serve multiple
704717tokens while maintaining per-token state and applying token-specific business
705718logic (e.g., per-token transfer limits, per-token balance tracking).
706719
720+ ** Validity requirements for state-update hooks:**
721+
722+ Because ` transferred ` , ` created ` , and ` destroyed ` mutate per-token state, they
723+ MUST be protected against caller spoofing of the ` token ` parameter. Concretely,
724+ implementations MUST:
725+
726+ 1 . Require authorization from ` token ` (e.g., ` token.require_auth() ` ), so the
727+ call can only originate from the token contract whose state is being
728+ updated.
729+ 2 . Reject calls where ` token ` is not bound to the compliance contract.
730+
731+ Without both checks, an attacker could call a state-update hook directly with a
732+ ` token ` they do not control and corrupt that token's per-module state (e.g.,
733+ transfer counters, holding-period trackers). Read-only hooks (` can_transfer ` ,
734+ ` can_create ` ) cannot corrupt state, but implementations SHOULD apply the same
735+ checks for consistency and to avoid leaking module-internal decisions to
736+ untrusted callers.
737+
707738#### Hook-Based Architecture
708739
709740The compliance system uses a sophisticated hook mechanism:
0 commit comments