# Comment intégrer Gauntlet USD Alpha

[gtUSDa](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5) est l'ERC20 pour notre vault stablecoin phare sur Base, Arbitrum, Optimism et le réseau principal Ethereum, qui peut être intégré dans d'autres applications DeFi. Voici un guide d'intégration de base pour incorporer gtUSDa dans votre protocole ou application.

{% hint style="info" %}
**gtUSDa est un ERC20 transférable sur Base, Arbitrum, Optimism et le réseau principal Ethereum.**
{% endhint %}

Nous disposons également d'une interface dédiée pour fournir des fonds dans ce vault à [app.gauntlet.xyz/vaults/gtusda](https://app.gauntlet.xyz/vaults/gtusda).

### Adresses des contrats

**Adresses du vault gtUSDa**

* `0x000000000001CdB57E58Fa75Fe420a0f4D6640D5` (contrat gtUSDa sur Base)
* `0x3bd9248048df95Db4fBD748C6CD99C1bAa40bAD0` (contrat gtUSDa sur Ethereum)
* `0x000000001DC8bd45d7E7829fb1c969cbe4D0D1eC` (contrat gtUSDa sur Arbitrum)
* `0x000000001DC8bd45d7E7829fb1c969cbe4D0D1eC` (contrat gtUSDa sur Optimism)

**Adresses des tokens**

* &#x20;`0x833589fcd6edb6e08f4c7c32d4f71b54bda02913` (contrat USDC sur Base)
* &#x20;`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` (contrat USDC sur le réseau principal Ethereum)&#x20;
* &#x20;`0xaf88d065e77c8cC2239327C5EDb3A432268e5831` (contrat USDC sur Arbitrum)&#x20;
* &#x20;`0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85` (contrat USDC sur Optimism)

**Adresses des provisioners**

* `0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07` (contrat provisioner sur Base)
* `0x74C4A66CE4F4779B11E7c63D42e51EEef3A80D11` (contrat provisioner sur Ethereum)
* `0xDd4a42603E6d8E515C3468789375A98c376821b3` (contrat provisioner sur Arbitrum)
* `0xCC923371F0d3A9cA75d98E767Df9dE1cdf5799Ef` (contrat provisioner sur Optimism)

{% hint style="info" %}
Remarque : Tous les exemples ci‑dessous sont exécutés sur Base.&#x20;
{% endhint %}

### Approvisionnement via appels de contrat

Fournir dans gtUSDa est une combinaison de 2 appels de fonction : un `approve` appel pour autoriser la dépense de l'USDC, et un `requestDeposit` appel.

1. appel [`approve`](https://basescan.org/token/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913#writeProxyContract#F1) sur le contrat USDC pour permettre que la quantité d'USDC soit dépensée par le [contrat provisioner](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07)
   1. Notez qu'il ne s'agit pas du contrat du vault lui‑même, car la requête passe par le provisioner pour émettre des unités du vault de manière asynchrone via un mécanisme de résolution (voir [https://docs.aera.finance/entry-exit-with-provisioner](https://docs.aera.finance/entry-exit-with-provisioner "mention") pour plus de détails)
2. [`requestDeposit`](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07#writeContract#F7) . `requestDeposit` est une opération asynchrone, l'utilisateur soumettra l'USDC au provisioner et après que la requête soit résolue des unités gtUSDa seront renvoyées directement au portefeuille de l'utilisateur. Cela se produira généralement dans les 6 heures mais peut prendre jusqu'à 3 jours (ou autrement selon la date limite). Voir [https://docs.aera.finance/entry-exit-with-provisioner](https://docs.aera.finance/entry-exit-with-provisioner "mention") pour plus de détails
   1. token :  `0x833589fcd6edb6e08f4c7c32d4f71b54bda02913` (contrat USDC sur Base)
   2. tokensIn : montant d'USDC entrant (valeur ajustée selon les décimales)
   3. minUnitsOut : Ce paramètre doit être basé sur le prix actuel de gtUSDa. Pour le calculer, reportez‑vous au [PriceAndFeeCalculator](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#code) contrat, plus précisément à la [`convertTokenToUnits`](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#readContract#F4) appel de fonction.
      1. `convertTokenToUnits(0x000000000001CdB57E58Fa75Fe420a0f4D6640D5, 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, tokensIn)` -> Retourne les unités gtUSDa ajustées selon les décimales.
      2. Multipliez la valeur ci‑dessus par 0.97 (une marge au cas où il y aurait des variations de prix)
   4. solverTip : `0`
   5. deadline : `block.timestamp + 259200` (3 jours en secondes)
   6. maxPriceAge : `3600` (1 heure en secondes)
   7. isFixedPrice : `False`

{% hint style="info" %}
`minUnitsOut` n'est techniquement pas requis pour les ordres à prix automatique si le prix du vault est digne de confiance mais il est fortement recommandé pour des raisons de sécurité.\
\
Veuillez ne pas inclure un `solverTip` car le solver ne résoudra pas ces requêtes.\
\
Veuillez ne pas inclure une date limite longue car les ordres inexploitables ne peuvent pas être remboursés avant la `deadline`.
{% endhint %}

#### Exemple de requête pour déposer 1000 USDC

Appeler [`approve`](https://basescan.org/token/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913#writeProxyContract#F1) sur le contrat USDC de Base pour permettre au provisioner de dépenser

```
approve(
    0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07, // Adresse du contrat Provisioner 
    1000000000 // montant USDC ajusté selon les décimales
)
```

appel [`requestDeposit`](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07#writeContract#F7) sur le provisioner, paramétrer cet appel est important

```
requestDeposit(
    0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, // Contrat USDC sur Base
    1000000000, // montant USDC ajusté selon les décimales
    0.97 * convertTokensToUnit(0x000000000001CdB57E58Fa75Fe420a0f4D6640D5, 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, 1000000000), // minUnitsOut voir ci‑dessus pour plus de détails
    0, // solverTip
    block.timestamp + 259200, // deadline : Fixez au moins 3 jours, ceci correspond à 3 jours en secondes
    3600, // maxPriceAge : Fixez à 1 heure, 1 heure en secondes
    False // isFixedPrice
)
```

### Retrait via appels de contrat

Pour retirer, vous devez de même effectuer un `approve` appel suivi de `requestRedeem` sur le [contrat Provisioner](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07) avec les bons paramètres.

1. appel [`approve`](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5#writeContract#F2) sur le contrat gtUSDa pour permettre que la quantité de gtUSDa soit dépensée par le [contrat provisioner](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07)
2. [`requestRedeem`](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07#writeContract#F8) Il s'agit également d'un appel asynchrone où l'utilisateur fournit les vaultUnits au contrat Provisioner et après résolution de la requête l'utilisateur recevra de l'USDC dans son portefeuille
   1. token : `0x833589fcd6edb6e08f4c7c32d4f71b54bda02913` (contrat USDC sur Base)
   2. unitsIn : Le montant d'unités du vault que vous souhaitez racheter, correctement ajusté selon les décimales. Si vous voulez calculer les `unitsIn` basés sur la valeur en USDC pour l'utilisateur, vous pouvez à nouveau utiliser la [`convertTokenToUnits`](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#readContract#F4) fonction sur le [PriceAndFeeCalculator](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#code) contrat comme pour l'appel de dépôt.
   3. minTokensOut : Ce paramètre doit être basé sur le prix actuel de gtUSDa. Pour le calculer, reportez‑vous à la [PriceAndFeeCalculator](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#code) contrat, plus précisément à la [`convertUnitsToToken`](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#readContract#F7) fonction.
      1. `convertUnitsToToken(0x000000000001CdB57E58Fa75Fe420a0f4D6640D5, 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, unitsIn)` -> Retourne la valeur USDC ajustée selon les décimales des VaultUnits
      2. Multipliez la valeur ci‑dessus par 0.97 (une marge au cas où il y aurait des variations de prix)
   4. solverTip : `0`
   5. deadline : `block.timestamp + 259200` (3 jours en secondes)
   6. maxPriceAge : `3600` (1 heure en secondes)
   7. isFixedPrice : `False`

{% hint style="info" %}
`minTokensOut` n'est techniquement pas requis pour les ordres à prix automatique si le prix du vault est digne de confiance mais il est fortement recommandé pour des raisons de sécurité.\
\
Veuillez ne pas inclure un `solverTip` car le solver ne résoudra pas ces requêtes.\
\
Veuillez ne pas inclure une date limite longue car les ordres inexploitables ne peuvent pas être remboursés avant la `deadline`.
{% endhint %}

#### Exemple de requête pour retirer 1000 USDC

appel [`approve`](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5#writeContract#F2) sur le contrat gtUSDa pour permettre au provisioner de dépenser

```
approve(
    0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07, // Adresse du contrat Provisioner 
    convertTokensToUnit(0x000000000001CdB57E58Fa75Fe420a0f4D6640D5, 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, 1000000000) // montant gtUSDa ajusté selon les décimales
)
```

appel [`requestRedeem`](https://basescan.org/address/0x18CF8d963E1a727F9bbF3AEffa0Bd04FB4dBdA07#writeContract#F8) sur le provisioner, paramétrer cet appel est important

```
requestRedeem(
    0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, // token : contrat USDC sur Base
    convertTokensToUnit(0x000000000001CdB57E58Fa75Fe420a0f4D6640D5, 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, 1000000000), // unitsIn : 1000 USDC via le PriceAndFee calculator
    0.97 * convertUnitsToToken(0x000000000001CdB57E58Fa75Fe420a0f4D6640D5, 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, unitsIn), // minTokensOut : unitsIn est la réponse de la ligne précédente
    0, // solverTip
    block.timestamp + 259200, // deadline : Fixez au moins 3 jours, ceci correspond à 3 jours en secondes
    3600, // maxPriceAge : Fixez à 1 heure, ceci correspond à 1 heure en secondes
    False // isFixedPrice
)
```

### \[AVANCÉ] Surveillance et remboursement des ordres

**Suivi des ordres**

Lorsqu'un ordre asynchrone est placé, l'utilisateur aura un ordre actif mais non rempli. Pour fournir une transparence supplémentaire aux utilisateurs, ces ordres peuvent être surveillés en suivant les `DepositRequested` ou `RedeemRequested` événements :

```
/// @notice Émis lorsqu'un utilisateur crée une requête de dépôt
/// @param user L'adresse demandant le dépôt
/// @param token Le token déposé
/// @param tokensIn La quantité de tokens à déposer
/// @param minUnitsOut La quantité minimale d'unités attendue
/// @param solverTip Le pourboire offert au solver en termes de token de dépôt
/// @param deadline Horodatage jusqu'auquel la requête est valide
/// @param maxPriceAge Âge maximal des données de prix que le solver peut utiliser
/// @param isFixedPrice Indique si la requête est à prix fixe
/// @param depositRequestHash Le hash de la requête de dépôt
event DepositRequested(
    address indexed user,
    IERC20 indexed token,
    uint256 tokensIn,
    uint256 minUnitsOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice,
    bytes32 depositRequestHash
);

/// @notice Émis lorsqu'un utilisateur crée une requête de rachat
/// @param user L'adresse demandant le rachat
/// @param token Le token demandé en échange des unités
/// @param minTokensOut La quantité minimale de tokens que l'utilisateur s'attend à recevoir
/// @param unitsIn La quantité d'unités en cours de rachat
/// @param solverTip Le pourboire offert au solver en termes de token de rachat
/// @param deadline L'horodatage jusqu'auquel cette requête est valide
/// @param maxPriceAge Âge maximal des données de prix que le solver peut utiliser
/// @param isFixedPrice Indique si la requête est à prix fixe
/// @param redeemRequestHash Le hash de la requête de rachat
event RedeemRequested(
    address indexed user,
    IERC20 indexed token,
    uint256 minTokensOut,
    uint256 unitsIn,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice,
    bytes32 redeemRequestHash
);
```

**Vérifier quand les ordres sont remplis**

Lorsqu'un dépôt ou un rachat est rempli, l'un des événements suivants sera émis dans le Provisioner :

```
/// @notice Émis lorsqu'une requête de dépôt est résolue avec succès
/// @param depositHash L'identifiant unique de la requête de dépôt qui a été résolue
event DepositSolved(bytes32 indexed depositHash);

/// @notice Émis lorsqu'une requête de rachat est résolue avec succès
/// @param redeemHash L'identifiant unique de la requête de rachat qui a été résolue
event RedeemSolved(bytes32 indexed redeemHash);
```

**Remboursement des ordres expirés**

Si la date limite passe mais qu'un ordre n'est pas résolu (rare), l'utilisateur doit récupérer son USDC ou ses tokens gtUSDa en utilisant la `refundRequest` fonction.

```
/// @notice Paramètres de requête pour les dépôts et rachats
/// @dev
/// - Pour les dépôts :
///   - units : unités minimales que l'utilisateur souhaite recevoir (minUnitsOut)
///   - tokens : montant de tokens que l'utilisateur fournit (tokensIn)
/// - Pour les rachats :
///   - units : montant d'unités que l'utilisateur rachète (unitsIn)
///   - tokens : tokens minimaux que l'utilisateur souhaite recevoir (minTokensOut)
struct Request {
    /// @notice Type de requête (dépôt/rachat + prix auto/fixe)
    RequestType requestType;
    /// @notice Adresse de l'utilisateur effectuant la requête
    address user;
    /// @notice Montant d'unités du vault
    uint256 units;
    /// @notice Montant des tokens sous‑jacents
    uint256 tokens;
    /// @notice Pourboire payé au solver, toujours en tokens
    uint256 solverTip;
    /// @notice Horodatage après lequel la requête expire
    uint256 deadline;
    /// @notice Âge maximal des données de prix autorisé
    uint256 maxPriceAge;
}

/// @notice Rembourser une requête de dépôt ou de rachat expirée
/// @param token Le token impliqué dans la requête
/// @param request La requête à rembourser
/// @dev Ne peut être appelé qu'après expiration de la date limite de la requête
function refundRequest(IERC20 token, Request calldata request) external;
```

### Obtention du solde de l'utilisateur en gtUSDa

Appelez simplement la [balanceOf](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5#readContract#F5) fonction sur [gtUSDa](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5) avec l'adresse de l'utilisateur.

### Tarification des unités gtUSDa en USDC (et inversement)

Nous fournissons des utilitaires simples de conversion de prix entre gtUSDa et USDC via le [PriceAndFeeCalculator](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e) contrat.

Plus précisément, il y a deux fonctions pertinentes

* [`convertTokensToUnits`](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#readContract#F4) -> Prend une valeur USDC et retourne le montant d'unités du vault au prix courant
  * vault : `0x000000000001CdB57E58Fa75Fe420a0f4D6640D5` (contrat du vault gtUSDa)
  * token : `0x833589fcd6edb6e08f4c7c32d4f71b54bda02913` (contrat USDC sur Base)
  * tokenAmount : valeur USDC ajustée selon les décimales (USDC a [6 décimales](https://basescan.org/token/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913#readProxyContract#F11))
* [`convertUnitsToTokens`](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#readContract#F7) -> Prend des vaultUnits et retourne la valeur en USDC au prix courant
  * vault : `0x000000000001CdB57E58Fa75Fe420a0f4D6640D5` (contrat du vault gtUSDa)
  * token : `0x833589fcd6edb6e08f4c7c32d4f71b54bda02913` (contrat USDC sur Base)
  * unitsAmount : valeur gtUSDa ajustée selon les décimales (gtUSDa a [18 décimales](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5#readContract#F7))

### Récupération de l'APY du vault

Celle‑ci est un peu plus compliquée pour le moment, mais nous visons à simplifier cela à l'avenir via une API. Pour l'instant, la meilleure façon d'obtenir l'APY du vault est d'indexer le prix des unités du vault en USDC sur une période donnée et d'extrapoler cela en un chiffre d'APY annuel.

### Calcul du TVL du vault

Pour obtenir le TVL total du vault, utilisez la [`convertUnitsToTokens`](https://basescan.org/address/0x69dD4D44eed6BbC33B8A0bdFe17897Ab9044372e#readContract#F7) fonction et utilisez la [`totalSupply`](https://basescan.org/address/0x000000000001CdB57E58Fa75Fe420a0f4D6640D5#readContract#F21) de gtUSDa comme entrée.
