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

# Integrate USDh

> What your app or contract needs to handle, and a checklist before going live.

USDh is a standard ERC-20 on Ethereum mainnet. Most apps only need to hold and move it. Approved routes, such as aggregators, can also mint and redeem it for their users.

This page describes the contract code live today (in force since 13 August 2026). Addresses are on [Contracts](https://docs.hamilton.xyz/for-developers/contract-addresses.md).

## Holding and moving USDh

* **Use the proxy address** `0xbcFC42391e55484129191eDfcC766a2c6F9eb503`. Never the implementation address behind it.
* **6 decimals**, like USDC. Read `decimals()` rather than hard-coding it.
* **Gasless approvals.** EIP-2612 `permit`. The signing domain is name `USDh`, version `1`, chain ID 1.
* **Gasless transfers.** EIP-3009 `transferWithAuthorization` and `receiveWithAuthorization`, with a random 32-byte nonce and a valid-after and valid-before time window. Signatures from contract wallets such as Safes work through EIP-1271. An unused authorization can be cancelled with `cancelAuthorization`.

## When a transfer can fail

Plan for these, so a failed transfer doesn't break your app.

| Situation | What happens | How to check first |
| - | - | - |
| Everything is paused | Every transfer, mint and redeem fails with `EnforcedPause()` | `paused()` returns `true` |
| The sender is frozen | Fails with `from frozen` | `frozen(address)` returns `true` |
| The receiver is frozen | Fails with `to frozen` | `frozen(address)` returns `true` |

A freeze never takes a balance. A frozen address keeps its USDh until it is unfrozen.

## Minting and redeeming as an approved route

An approved route is a contract Hamilton has approved, after signing up, to mint and redeem for its users. To sign up, see [How it works](https://docs.hamilton.xyz/using-hamilton/minting-and-redeeming-primary-users.md).

* **Approval is per calling address.** Minting and redeeming are approved separately. The contract checks the address that calls it, not the one receiving USDh.
* **Mint.** Approve the stablecoin to the USDh contract, then call `mintWithStable(stable, stableAmount, to)`. USDh is minted to `to`, 1:1, in the same transaction. The accepted stablecoins are listed by `supportedStables()`.
* **Redeem.** Call `redeemForStable(stable, usdhAmount, to)`. USDh is burned from the caller and the stablecoin is sent to `to`, 1:1.
* **Redemption limit.** Each address has its own limit every 7 days, checked by `effectiveRedeemCap(address)`. By default it is set to half the balance of the address USDh is minted to. If your contract mints to your users rather than to itself, ask Hamilton to set your limit, or redeeming fails with `redeem cap not set`.
* **No cap on minting with stablecoins.** The daily ceiling applies only to minting against bank wires.

```solidity theme={null}
interface IUSDh {
    function mintWithStable(address stable, uint256 stableAmount, address to) external;
    function redeemForStable(address stable, uint256 usdhAmount, address to) external;
    function supportedStables() external view returns (address[] memory);
    function effectiveRedeemCap(address user) external view returns (uint256);
    function mintWhitelist(address user) external view returns (bool);
    function redeemWhitelist(address user) external view returns (bool);
    function frozen(address account) external view returns (bool);
    function paused() external view returns (bool);
}
```

## Events to watch

| Event | Means |
| - | - |
| `MintedWithStable` | USDh minted against a stablecoin |
| `RedeemedForStable` | USDh redeemed for a stablecoin |
| `AddressFrozen` | An address was frozen or unfrozen |
| `Paused`, `Unpaused` | The whole system was paused or restarted |
| `CallScheduled` on the timelock | A change to USDh is waiting its 48 hours. See [Security](https://docs.hamilton.xyz/trust-and-transparency/security-and-audits.md) |

## Go-live checklist

1. You use the proxy address from [Contracts](https://docs.hamilton.xyz/for-developers/contract-addresses.md).
2. You read `decimals()` from the contract.
3. Your app handles a paused system and a frozen address without breaking.
4. You watch the timelock for scheduled changes to USDh.
5. For approved routes: Hamilton has confirmed which of your addresses can mint and which can redeem.
6. For approved routes: you have tested a small mint and a small redemption, and your redemption limit is set.
7. For approved routes: your sanctions screening matches what your agreement with Hamilton requires.

Questions: [legal@hamilton.xyz](mailto:legal@hamilton.xyz).

*Last updated: 9 November 2026*


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.