# usdcx-token

{% code title=".usdcx" lineNumbers="true" expandable="true" %}

```clarity
;; token USDCx
;;
;; Este contrato implementa la característica SIP-010 para contratos fungibles.
;;
;; Este contrato utiliza un sistema de control de acceso basado en roles para gestionar los permisos del protocolo.
;; Hay tres roles:
;;
;; - `governance`: Tiene अनुमति para actualizar los contratos del protocolo y agregar/quitar roles
;; - `mint`: Tiene permiso para acuñar y quemar tokens
;; - `pause`: Tiene permiso para pausar y reanudar el protocolo
;;

(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)

;; `tx-sender` o `contract-caller` intentó mover un token que no posee.
(define-constant ERR_NOT_OWNER (err u4))
;; `contract-caller` intentó usar una función que no está autorizado a usar.
(define-constant ERR_UNAUTHORIZED (err u400))
;; El protocolo está pausado.
(define-constant ERR_PAUSED (err u401))

(define-fungible-token usdcx-token)

(define-data-var token-name (string-ascii 32) "USDCx")
(define-data-var token-symbol (string-ascii 10) "USDCx")
;; La URI SIP-16 para los metadatos del token
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://ipfs.io/ipfs/bafkreifkhq47bgrlq2z2qgtps65eawgp6xsqkwldz57y2bjpefgo5zvza4"))
(define-constant token-decimals u6)

;; Tiene permiso para actualizar los contratos del protocolo
(define-constant governance-role 0x00)
;; Tiene permiso para acuñar y quemar tokens
(define-constant mint-role 0x01)
;; Tiene permiso para pausar y reanudar el protocolo
(define-constant pause-role 0x02)

;; Permitir que el protocolo sea pausado
(define-data-var paused bool false)

;; Mapeo de contratos activos del protocolo (por rol)
(define-map active-protocol-contracts
  {
    caller: principal,
    role: (buff 1),
  }
  bool
)

;; El contrato .usdcx-v1 tiene automáticamente el rol `mint`
(map-set active-protocol-contracts {
  caller: .usdcx-v1,
  role: mint-role,
}
  true
)
;; Establecer por defecto que el desplegador del contrato tiene el rol `governance`
(map-set active-protocol-contracts {
  caller: tx-sender,
  role: governance-role,
}
  true
)

;; Funciones SIP-010

(define-public (transfer
    (amount uint)
    (sender principal)
    (recipient principal)
    (memo (optional (buff 34)))
  )
  (begin
    (asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender))
      ERR_NOT_OWNER
    )
    (try! (ft-transfer? usdcx-token amount sender recipient))
    (match memo
      to-print (print to-print)
      0x
    )
    (ok true)
  )
)

(define-read-only (get-name)
  (ok (var-get token-name))
)

(define-read-only (get-symbol)
  (ok (var-get token-symbol))
)

(define-read-only (get-decimals)
  (ok token-decimals)
)

(define-read-only (get-balance (who principal))
  (ok (ft-get-balance usdcx-token who))
)

(define-read-only (get-balance-available (who principal))
  (ok (ft-get-balance usdcx-token who))
)

(define-read-only (get-balance-locked (who principal))
  (ok (ft-get-balance usdcx-token who))
)

(define-read-only (get-total-supply)
  (ok (ft-get-supply usdcx-token))
)

(define-read-only (get-token-uri)
  (ok (var-get token-uri))
)

;; Validación del llamador del protocolo

;; Comprueba si `contract-caller` es un contrato del protocolo
(define-read-only (is-protocol-caller
    (contract-flag (buff 1))
    (contract principal)
  )
  (validate-protocol-caller contract-flag contract)
)

;; Validar que un principal dado sea un contrato del protocolo
(define-read-only (validate-protocol-caller
    (contract-flag (buff 1))
    (contract principal)
  )
  (begin
    ;; Comprueba que el llamador tenga el rol requerido
    (asserts!
      (default-to false
        (map-get? active-protocol-contracts {
          caller: contract,
          role: contract-flag,
        })
      )
      ERR_UNAUTHORIZED
    )
    (ok true)
  )
)

;; Pausa del protocolo

(define-read-only (is-protocol-paused)
  (var-get paused)
)

;; Validar que el protocolo no esté pausado
(define-read-only (validate-protocol-active)
  (ok (asserts! (not (is-protocol-paused)) ERR_PAUSED))
)

;; --- Funciones del protocolo

;; Transfiere tokens de una cuenta a otra.
;; Solo el rol `mint` puede llamar a esta función.
(define-public (protocol-transfer
    (amount uint)
    (sender principal)
    (recipient principal)
  )
  (begin
    ;; #[filter(amount, sender, recipient)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller mint-role contract-caller))
    (ft-transfer? usdcx-token amount sender recipient)
  )
)

;; Acuña tokens a una cuenta.
;; Solo el rol `mint` puede llamar a esta función.
(define-public (protocol-mint
    (amount uint)
    (recipient principal)
  )
  (begin
    ;; #[filter(amount, recipient)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller mint-role contract-caller))
    (ft-mint? usdcx-token amount recipient)
  )
)

;; Quema tokens de una cuenta.
;; Solo el rol `mint` puede llamar a esta función.
(define-public (protocol-burn
    (amount uint)
    (owner principal)
  )
  (begin
    ;; #[filter(amount, owner)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller mint-role contract-caller))
    (ft-burn? usdcx-token amount owner)
  )
)

;; Establece el nombre del token.
;; Solo el rol `governance` puede llamar a esta función.
(define-public (protocol-set-name (new-name (string-ascii 32)))
  (begin
    ;; #[filter(new-name)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller governance-role contract-caller))
    (ok (var-set token-name new-name))
  )
)

;; Establece el símbolo del token.
;; Solo el rol `governance` puede llamar a esta función.
(define-public (protocol-set-symbol (new-symbol (string-ascii 10)))
  (begin
    ;; #[filter(new-symbol)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller governance-role contract-caller))
    (ok (var-set token-symbol new-symbol))
  )
)

;; Establece la URI SIP-16 para los metadatos del token.
;; Solo el rol `governance` puede llamar a esta función.
(define-public (protocol-set-token-uri (new-uri (optional (string-utf8 256))))
  (begin
    ;; #[filter(new-uri)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller governance-role contract-caller))
    (ok (var-set token-uri new-uri))
  )
)

;; Función auxiliar para acuñar tokens a múltiples destinatarios.
;; Solo el rol `mint` puede llamar a esta función.
(define-private (protocol-mint-many-iter (item {
  amount: uint,
  recipient: principal,
}))
  ;; #[allow(unchecked_data)]
  (ft-mint? usdcx-token (get amount item) (get recipient item))
)

;; Acuña tokens a múltiples destinatarios.
;; Solo el rol `mint` puede llamar a esta función.
(define-public (protocol-mint-many (recipients (list 200 {
  amount: uint,
  recipient: principal,
})))
  (begin
    ;; #[filter(recipients)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller mint-role contract-caller))
    (ok (map protocol-mint-many-iter recipients))
  )
)

;; Establece un llamador activo del protocolo.
;; Solo el rol `governance` puede llamar a esta función.
(define-public (set-active-protocol-caller
    (caller principal)
    (role (buff 1))
    (enabled bool)
  )
  (begin
    ;; #[filter(caller, role, enabled)]
    (try! (validate-protocol-active))
    (try! (validate-protocol-caller governance-role contract-caller))
    (map-set active-protocol-contracts {
      caller: caller,
      role: role,
    }
      enabled
    )
    (ok true)
  )
)

;; Pausa el protocolo.
;; Solo el rol `pause` puede llamar a esta función.
(define-public (pause)
  (begin
    (try! (validate-protocol-caller pause-role contract-caller))
    (print {
      topic: "pause",
      paused: true,
      caller: contract-caller,
    })
    (ok (var-set paused true))
  )
)

;; Reanuda el protocolo.
;; Solo el rol `pause` puede llamar a esta función.
(define-public (unpause)
  (begin
    (try! (validate-protocol-caller pause-role contract-caller))
    (print {
      topic: "pause",
      paused: false,
      caller: contract-caller,
    })
    (ok (var-set paused false))
  )
)

```

{% endcode %}

## **Resumen del contrato USDCx-Token**

Este contrato implementa **USDCx**, un token fungible SIP-010 en Stacks con un **sistema de control de acceso basado en roles** y **funcionalidad de pausa** para la seguridad del protocolo. Expone la interfaz estándar SIP-010 para transferencias, consultas de suministro y metadatos, al tiempo que proporciona funciones exclusivas del protocolo para acuñar, quemar, actualizaciones de gobernanza y pausado.

#### **Roles**

El contrato define tres roles privilegiados:

* **Gobernanza (`governance-role`)** – gestiona la configuración del protocolo, actualiza los metadatos del token y asigna roles.
* **Acuñar (`mint-role`)** – autorizado para acuñar, quemar y realizar transferencias a nivel de protocolo.
* **Pausa (`pause-role`)** – autorizado para pausar y reanudar el protocolo.

Una pausa del protocolo detiene las operaciones que cambian el estado por seguridad. El desplegador del contrato recibe automáticamente el **governance** rol. El contrato complementario `.usdcx-v1` recibe automáticamente el **mint** rol.

***

### Desglose función por función

### **Funciones estándar SIP-010**

#### **`transfer(amount, sender, recipient, memo)`**

Transfiere USDCx entre principales, siguiendo las reglas de SIP-010. La función comprueba que el emisor sea ya sea `tx-sender` o `contract-caller` (para contratos que gestionan escrow o bóvedas) y luego realiza la transferencia. Un memo opcional se registra en la cadena.

#### **`get-name()`**, **`get-symbol()`**, **`get-decimals()`**

Obtiene los metadatos estándar de SIP-010 que devuelven el nombre del token, el símbolo y la precisión decimal.

#### **`get-balance(who)`**, **`get-balance-available(who)`**, **`get-balance-locked(who)`**

Devuelve el saldo del token para el principal dado. En esta implementación, las tres funciones de acceso devuelven el mismo valor de saldo SIP-010.

#### **`get-total-supply()`**

Devuelve el suministro total de USDCx acuñado menos quemado.

#### **`get-token-uri()`**

Devuelve la URI de metadatos del token.

***

### **Validación del llamador del protocolo**

Estas funciones hacen cumplir los permisos basados en roles del contrato.

#### **`is-protocol-caller(role, contract)`**

Comprueba si el principal contractual especificado tiene el rol requerido.

#### **`validate-protocol-caller(role, contract)`**

Asegura que el llamador tenga el rol correcto. Si no, devuelve `ERR_UNAUTHORIZED`.

#### **`is-protocol-paused()`**

Devuelve si el protocolo está actualmente pausado.

#### **`validate-protocol-active()`**

Afirma que el protocolo no esté pausado; de lo contrario devuelve `ERR_PAUSED`.

***

### **Operaciones de token exclusivas del protocolo**

Estas funciones permiten acuñar/quemar/transferir estrictamente para contratos del protocolo autorizados.

#### **`protocol-transfer(amount, sender, recipient)`**

Realiza una transferencia a nivel de protocolo en nombre de otro contrato. Solo los llamadores con el **rol de mint** pueden usarlo. Falla si el protocolo está pausado.

#### **`protocol-mint(amount, recipient)`**

Acuña nuevo USDCx para un principal. Restringido al **rol de mint** y deshabilitado cuando está pausado.

#### **`protocol-burn(amount, owner)`**

Quema tokens del saldo de un principal. También restringido al **rol de mint** y deshabilitado cuando está pausado.

#### **`protocol-mint-many(recipients)`**

Acuña tokens por lotes a múltiples destinatarios en una sola llamada. Cada elemento incluye `{ amount, recipient }`. Solo puede ser llamado por entidades con el **rol de mint**.

***

### **Funciones de gobernanza**

Solo el **rol de gobernanza** puede llamar a estas funciones.

#### **`protocol-set-name(new-name)`**

Actualiza el nombre SIP-010 del token.

#### **`protocol-set-symbol(new-symbol)`**

Actualiza el símbolo ticker SIP-010 del token.

#### **`protocol-set-token-uri(new-uri)`**

Actualiza la URI de metadatos SIP-016.

#### **`set-active-protocol-caller(caller, role, enabled)`**

Agrega o elimina un principal de un rol específico del protocolo.\
Se usa para rotar sistemas, actualizar contratos complementarios o delegar nueva responsabilidad.

***

### **Controles de pausa**

Estas funciones permiten al protocolo detener operaciones por seguridad o mantenimiento.

#### **`pause()`**

Pausa el contrato, deshabilitando la acuñación, quema y todas las acciones exclusivas del protocolo. Solo puede ser llamada por el **rol de pausa**.

#### **`unpause()`**

Rehabilita el protocolo después de una pausa. También restringido al **rol de pausa**.

Ambas funciones emiten un evento en cadena para mayor transparencia.


---

# 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.stacks.co/learn/es/bridging/usdcx/contracts/usdcx-token.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.
