USDMD for developers
Integrate USDMD.
An ERC-20 with 6 decimals and EIP-2612 permit, on Midas Chain testnet (chain ID 64327). Every contract is source-verified on the explorer, where its ABI can be read and downloaded.
Chain ID
64327
RPC
https://rpc.testnet.onmidas.xyz
Explorer
https://explorer.testnet.onmidas.xyz
Gas
MIDS
Addresses
| Contract | Address | Notes |
|---|---|---|
| USDMD | 0xc63b4Bd2120faC3ea8f1Ff8658B8285E29918D14 | USDMD token. Immutable, no owner, no admin. |
| USDMDController (proxy) | 0xb7A0e3C4221A61Bae19dFD73599c85132f0b20D7 | The only minter. UUPS proxy; upgrades run through the timelock. |
| USDMDController (implementation) | 0xAB015dC5881Cc47b66f141e25Cc51e8eBC66EC7C | Controller implementation, version 1. |
| TimelockController | 0xb08b255ED84B414CefF177C4D794158dD52e42AD | 1-hour delay on testnet. Anyone can execute a ready operation. |
| CollateralRegistry | 0x7ab4C04DcAB052376998959670A3Bf3F021De803 | Accepted reserve assets and their haircuts and caps. |
| OracleAdapter | 0x8d5c3Ee7Ee4363a66aC40819C38DbD182bEC4F26 | XAU/USD: median of fresh sources, at least 2, spread under 1.5%, 120 s freshness. |
| ReserveManager | 0xa0A2896c1ae3139752e67DeC9172964b3D37133a | Holds the reserve's on-chain gold. Only the controller can pay out. |
| ProofOfReserves | 0x056Ede5c54dDf3e753fb033d269Dab059f2D6B89 | Hourly epochs. epochCount(), epoch(n), latestOffchain(). |
| USDMDDispenser | 0xD745f9f07799412F93214F2E05d786CDd011472B | claim(): 1,000 USDMD per address per 24 hours. |
| Treasury | 0x8e97178fc4d5b180e69AD36C72eaC27582cE6656 | Receives mint and redeem fees. An account, not a contract. |
| MockXAU (XAU-MOCK) | 0xd47F0EcD6f53bA48524c6C2E454aE716bC6174D5 | Testnet only, not gold. 18 decimals, 1 token = 1 troy ounce by convention. drip() gives 0.05 a day. |
| Bridged PAXG | 0x0Da5029c9567dAa3926d5754146F59606007026a | Listed, empty. For Sepolia PAXG over the canonical bridge. |
ABIs: open any contract on the explorer, where its verified source and ABI are published. The contracts' source is in the chain/src/usdmd directory of the Midas Chain repository.
The token
- Name and symbol USDMD, 6 decimals. Amounts are integers in millionths: 1 USDMD is 1000000.
- EIP-2612 permit. EIP-712 domain: name "USDMD", version "1", chain ID 64327, verifying contract the token address.
- Transfers are unrestricted. There is no fee on transfer, no rebase, no pause and no blacklist, and none can be added: the contract has no upgrade path.
- mint and burn can be called only by the controller. burn burns only the controller's own balance.
Minting and redeeming
- mint(asset, amountIn, minOut, to): pulls amountIn of a registry asset into the reserve, and mints its value at the oracle price, less haircut and mint fee, to to. Approve the controller for the asset first.
- redeem(amount, asset, minOut, to): takes amount USDMD, burns it less the redeem fee, and pays the asset at the oracle price. Approve the controller for USDMD first, or call redeemWithPermit with a signed permit.
- minOut protects against the price moving between your quote and the block. Quote with OracleAdapter.read(keccak256("XAU/USD")) and valueOf(asset, amount, price) on the controller.
- Reverts carry custom errors: MintIsPaused, MintCapExceeded(requested, remaining), RedeemCapExceeded(requested, remaining), CollateralRatioTooLow(crBps, floorBps), ProofStale(age, maxAge), Slippage(out, minOut) and, from the oracle, PriceUnavailable(id, fresh, spreadTooWide).
Events
- Token: Transfer and Approval (ERC-20).
- Controller: Minted(caller, to, asset, amountIn, price, minted, fee) and Redeemed(caller, to, asset, amount, price, paid, fee). MintPausedSet(paused, by) and ParamsSet(params) for state changes.
- ProofOfReserves: EpochPublished(epoch, supersedes, supply, onchainValue, offchainValue, crBps, docsRoot, docsCid).
- Dispenser: Claimed(to, amount).
Public API
Read-only, no key, CORS open, cached for 10 seconds. Base URL https://api.krysos.xyz. Amounts are decimal strings, already scaled.
| Route | Returns |
|---|---|
GET /v1/usdmd/supply/total | Total supply as a plain number. |
GET /v1/usdmd/supply/circulating | Supply less the issuer's own holdings, as a plain number. |
GET /v1/usdmd/reserves | The reserve now: per-asset holdings and values, price, ratio, latest epoch. |
GET /v1/usdmd/reserves/history | Every proof-of-reserves epoch. |
GET /v1/usdmd/docs | Every epoch statement with its hash and location. |
GET /v1/usdmd/flows | Mints and redemptions by day, and the latest 50. |
GET /v1/usdmd/status | Oracle sources and their age, mint paused, parameters, caps used. |
GET /v1/usdmd/contracts | Addresses, chain ID, decimals. |
GET /v1/usdmd/governance | Timelock operations: queued, ready, executed, cancelled. |
Examples
curl -s https://api.krysos.xyz/v1/usdmd/supply/total
curl -s https://api.krysos.xyz/v1/usdmd/reserves | jq '{supply, collateral_ratio_bps, xau_usd}'import { createPublicClient, http, parseAbi, formatUnits } from "viem";
const client = createPublicClient({ transport: http("https://rpc.testnet.onmidas.xyz") });
const erc20 = parseAbi(["function balanceOf(address) view returns (uint256)"]);
const raw = await client.readContract({
address: "0xc63b4Bd2120faC3ea8f1Ff8658B8285E29918D14", abi: erc20,
functionName: "balanceOf", args: ["0xYourAddress"],
});
console.log(formatUnits(raw, 6)); // USDMD has 6 decimals// approve, then mint with MockXAU (18 decimals) at a quoted minimum out
const ctl = parseAbi([
"function mint(address asset, uint256 amountIn, uint256 minOut, address to) returns (uint256)",
"function redeem(uint256 amount, address asset, uint256 minOut, address to) returns (uint256)",
]);
await wallet.writeContract({ address: "0xb7A0e3C4221A61Bae19dFD73599c85132f0b20D7", abi: ctl,
functionName: "mint", args: ["0xd47F0EcD6f53bA48524c6C2E454aE716bC6174D5", amountIn, minOut, account] });Nothing on these pages is an offer, a solicitation or a recommendation to buy, sell or hold any asset, in any jurisdiction. Test USDMD is not sold and has no value.