|
| 1 | +--- |
| 2 | +hip: 0000 # Assigned by HIP editor. |
| 3 | +title: Dollar-denominated values. |
| 4 | +author: Giuseppe Bertone (@neurone) |
| 5 | +working-group: Giuseppe Bertone (@neurone), Michael Garber (@mgarbs), Raphael Messian (@raphaelmessian), Ty Smith (@ty-swirldslabs), Keith Kowal (@reccetech) |
| 6 | +requested-by: Hashgraph (@hashgraph) |
| 7 | +discussions-to: <URL of the GitHub Pull Request for this HIP> # This will be filled by the HIP editor upon PR creation. |
| 8 | +type: Standards Track |
| 9 | +category: Core |
| 10 | +needs-hiero-approval: Yes |
| 11 | +needs-hedera-review: Yes |
| 12 | +status: Draft |
| 13 | +created: 2025-08-13 |
| 14 | +updated: 2025-08-13 |
| 15 | +requires: NA |
| 16 | +replaces: NA |
| 17 | +superseded-by: NA |
| 18 | +release: NA |
| 19 | +--- |
| 20 | + |
| 21 | +## Abstract |
| 22 | + |
| 23 | +This HIP proposes extending Hedera's existing automatic HBAR-dollar conversion for network fees to all transaction values and service settings. |
| 24 | + |
| 25 | +Users would be able to specify dollar amounts in transactions and have the network calculate the corresponding HBAR amount at consensus level using the existing exchange rate oracle. This would enable dollar-denominated transfers, custom fees, scheduled transactions, and service pricing while maintaining a single source of truth for exchange rates. |
| 26 | + |
| 27 | +The proposal leverages existing TokenID definition by introducing system token identifiers for fiat currencies, starting with USD, to minimize protocol changes while maximizing compatibility with existing tools and SDKs. |
| 28 | + |
| 29 | +## Motivation |
| 30 | + |
| 31 | +Hedera is positioned as a business-friendly network, but HBAR price volatility creates significant challenges for developers, service providers, and users: |
| 32 | + |
| 33 | +- Developers face transaction failures when preset HBAR limits become insufficient due to price changes |
| 34 | +- Service providers must continuously monitor and update custom fees to maintain consistent dollar pricing |
| 35 | +- Users cannot guarantee actual fiat transferred values in scheduled transactions spanning weeks or months |
| 36 | +- Payment and micropayment adoption is hindered by the need for constant price monitoring and conversion |
| 37 | + |
| 38 | +Current workarounds require off-chain conversion calculations that introduce complexity, errors, and security risks, or using stablecoins as an alternative payment mechanisms instead of HBAR. While possible in some cases, this introduced friction and forces users and service providers to deal with at least two cryptocurrencies (HBAR plus the stablecoin). |
| 39 | + |
| 40 | +In addition, no other public ledger offers consensus-level fiat denomination, representing a unique opportunity for Hedera to differentiate itself and streamline business adoption. |
| 41 | + |
| 42 | +## Rationale |
| 43 | + |
| 44 | +The design leverages Hedera's existing exchange rate infrastructure rather than creating new oracle mechanisms. This approach maintains consistency between network fees and transaction values, avoiding user confusion from multiple exchange rates. |
| 45 | + |
| 46 | +The TokenID-based implementation was chosen because: |
| 47 | + |
| 48 | +- It reuses existing protobuf structures, minimizing protocol changes |
| 49 | +- It maintains compatibility with current tools, UIs, and SDKs |
| 50 | +- It naturally extends to future fiat currencies through additional system tokens |
| 51 | +- It integrates seamlessly with existing custom fee and transfer mechanisms |
| 52 | + |
| 53 | +Alternative designs considered: |
| 54 | + |
| 55 | +- New protobuf fields: Would require extensive protocol changes and tool updates |
| 56 | +- Separate denomination flags: Would complicate transaction structure and validation |
| 57 | + |
| 58 | +## User stories |
| 59 | + |
| 60 | +- As a service provider, I want to set a price in dollars for my HCS paid topics and HTS royalties so that I can maintain consistent revenue regardless of HBAR price fluctuations. |
| 61 | +- As a business owner, I want to create scheduled payments in dollars so that the recipient receives the agreed dollar amount even if the transaction executes weeks later when HBAR prices may have changed. |
| 62 | +- As a user, I want to send a specific dollar amount to someone without having to calculate HBAR conversions or worry about price changes between transaction creation and execution (e.g., long lasting scheduled transaction) |
| 63 | +- As a developer, I want to set network fee limits in dollars so that my applications don't fail when HBAR prices change and my preset limits become insufficient. |
| 64 | +- As a developer, I want to avoid conversion bugs in my application by letting the network handle HBAR-dollar calculations at consensus time with provable accuracy and exchange rate. |
| 65 | +- As a developer, I want to my smart contracts to manage and transfer dollar amounts without relying on 3rd party owned oracles. |
| 66 | + |
| 67 | +## Specification |
| 68 | + |
| 69 | +### Core Mechanism |
| 70 | + |
| 71 | +Dollar denomination is implemented using system TokenID identifiers to indicate fiat currency intent: |
| 72 | + |
| 73 | +- USD: `TokenId(0, 0, 18446744073709551615)` (max uint64) |
| 74 | +- Future currencies: `TokenId(0, 0, 18446744073709551614)` (max uint64 - 1) for EUR, etc. |
| 75 | + |
| 76 | +When a system fiat TokenID is used in any amount field (service or network fee), the network: |
| 77 | + |
| 78 | +1. Calculates the equivalent HBAR amount at consensus time using the in memory exchange rate |
| 79 | +2. Executes the transaction using the calculated HBAR amount |
| 80 | +3. Records both dollar intent and actual HBAR amount in transaction records |
| 81 | + |
| 82 | +The record files already offer the structure to store all those information: |
| 83 | + |
| 84 | +- the transaction body contains the original dollar intent |
| 85 | +- the transaction record contains |
| 86 | + - the receipt with the exchange rate |
| 87 | + - the transferList with the real HBAR transfers |
| 88 | + |
| 89 | +This is an example of the information inside the record file for a random [[email protected]](https://hashscan.io/mainnet/transaction/1755109617.960565000) mainnet transfer transaction: |
| 90 | + |
| 91 | +```javascript |
| 92 | +=== Transaction #0 dkWHmEhnjmA604qdQrwoEdzkeKlStWwYyGNGxuA8lxGC3+UNCdRkiH0zWTZzvKGv 7645879848678e603ad38a9d42bc2811dce478a952b56c18c86346c6e03c971182dfe50d09d464887d33593673bca1af === |
| 93 | +{ |
| 94 | + transaction: { |
| 95 | + signedTransactionBytes: 'Cn8KEwoMCOex88QGEIDfqpkCEgMYnRkSAhgGGMCEPSICCHgyRjE3NTUxMDk2MTc1OTAgTW9uaXRvciBjcnlwdG8gb24gaGVkZXJhLW1pcnJvci1tb25pdG9yLTZmZGJjNTg5NmQtZnRmdnNyFAoSCgcKAxidGRABCgcKAxieGRACEmYKZAogJ0HRd0U560CTTYceVsIAtPQJ0t8/uzKzOrUskDRIXfcaQFbKkQw6bhlB1DCAWOEmy2Uhl+whLXqt3rvQICfxPkyaqndtWd4e/ZTQAFE1nve6JWHJtVf8b6N172Ozkr8jUA0=' |
| 96 | + }, |
| 97 | + record: { |
| 98 | + receipt: { |
| 99 | + status: 'SUCCESS', |
| 100 | + exchangeRate: { |
| 101 | + currentRate: { |
| 102 | + hbarEquiv: 30000, |
| 103 | + centEquiv: 791784, |
| 104 | + expirationTime: { seconds: '1755111600' } |
| 105 | + }, |
| 106 | + nextRate: { |
| 107 | + hbarEquiv: 30000, |
| 108 | + centEquiv: 791978, |
| 109 | + expirationTime: { seconds: '1755115200' } |
| 110 | + } |
| 111 | + } |
| 112 | + }, |
| 113 | + transactionHash: 'dkWHmEhnjmA604qdQrwoEdzkeKlStWwYyGNGxuA8lxGC3+UNCdRkiH0zWTZzvKGv', |
| 114 | + consensusTimestamp: { seconds: '1755109617', nanos: 960565000 }, |
| 115 | + transactionID: { |
| 116 | + transactionValidStart: { seconds: '1755109607', nanos: 590000000 }, |
| 117 | + accountID: { accountNum: '3229' } |
| 118 | + }, |
| 119 | + memo: '1755109617590 Monitor crypto on hedera-mirror-monitor-6fdbc5896d-ftfvs', |
| 120 | + transactionFee: '38860', |
| 121 | + transferList: { |
| 122 | + accountAmounts: [ |
| 123 | + { accountID: { accountNum: '6' }, amount: '1578' }, |
| 124 | + { accountID: { accountNum: '801' }, amount: '37282' }, |
| 125 | + { accountID: { accountNum: '3229' }, amount: '-38861' }, |
| 126 | + { accountID: { accountNum: '3230' }, amount: '1' } |
| 127 | + ] |
| 128 | + } |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +=== Signatures #0 dkWHmEhnjmA604qdQrwoEdzkeKlStWwYyGNGxuA8lxGC3+UNCdRkiH0zWTZzvKGv 7645879848678e603ad38a9d42bc2811dce478a952b56c18c86346c6e03c971182dfe50d09d464887d33593673bca1af === |
| 133 | +{ |
| 134 | + pubKeyPrefix: 'J0HRd0U560CTTYceVsIAtPQJ0t8/uzKzOrUskDRIXfc=', |
| 135 | + ed25519: 'VsqRDDpuGUHUMIBY4SbLZSGX7CEteq3eu9AgJ/E+TJqqd21Z3h79lNAAUTWe97olYcm1V/xvo3XvY7OSvyNQDQ==', |
| 136 | + pubKeyPrefixHex: '2741d1774539eb40934d871e56c200b4f409d2df3fbb32b33ab52c9034485df7' |
| 137 | +} |
| 138 | + |
| 139 | +=== Body #0 dkWHmEhnjmA604qdQrwoEdzkeKlStWwYyGNGxuA8lxGC3+UNCdRkiH0zWTZzvKGv 7645879848678e603ad38a9d42bc2811dce478a952b56c18c86346c6e03c971182dfe50d09d464887d33593673bca1af === |
| 140 | +{ |
| 141 | + transactionID: { |
| 142 | + transactionValidStart: { seconds: '1755109607', nanos: 590000000 }, |
| 143 | + accountID: { accountNum: '3229' } |
| 144 | + }, |
| 145 | + nodeAccountID: { accountNum: '6' }, |
| 146 | + transactionFee: '1000000', |
| 147 | + transactionValidDuration: { seconds: '120' }, |
| 148 | + memo: '1755109617590 Monitor crypto on hedera-mirror-monitor-6fdbc5896d-ftfvs', |
| 149 | + cryptoTransfer: { |
| 150 | + transfers: { |
| 151 | + accountAmounts: [ |
| 152 | + { accountID: { accountNum: '3229' }, amount: '-1' }, |
| 153 | + { accountID: { accountNum: '3230' }, amount: '1' } |
| 154 | + ] |
| 155 | + } |
| 156 | + } |
| 157 | +} |
| 158 | +``` |
| 159 | + |
| 160 | +The fee structure (transactionFee) is extended to specify TokenIDs as a payment for the network fees. |
| 161 | + |
| 162 | +### Transaction Integration |
| 163 | + |
| 164 | +If a field can be set using a TokenID, that same field can also be set in dollars: |
| 165 | + |
| 166 | +- Transfer amounts in `CryptoTransfer` |
| 167 | +- Custom fees in token creation and updates |
| 168 | +- Scheduled transaction amounts |
| 169 | +- Smart contract value transfers |
| 170 | + |
| 171 | +All existing HBAR amount fields support dollar denomination: |
| 172 | + |
| 173 | +- Max network fees |
| 174 | +- ... |
| 175 | + |
| 176 | +### SDK Integration Examples |
| 177 | + |
| 178 | +```javascript |
| 179 | +// Transfer $1.50 with an Hedera transfer, using $0.01 as max transaction fee |
| 180 | +const txTransfer = new TransferTransaction() |
| 181 | + .addDollarTransfer(senderAccount, -1.5) |
| 182 | + .addDollarTransfer(receiverAccount, 1.5) |
| 183 | + .setMaxTransactionFee(new Dollar(0.01)); |
| 184 | + |
| 185 | +// Create a custom fixed fee so that $0.50 worth of HBAR is sent to the collector every time fee applies |
| 186 | +new CustomFixedFee() |
| 187 | + .setDenominatingTokenId(TokenId.USD) |
| 188 | + .setAmount(0.5) |
| 189 | + .setFeeCollectorAccountId(feeCollectorAccountId); |
| 190 | +``` |
| 191 | + |
| 192 | +### Impact on Mirror Node |
| 193 | + |
| 194 | +Leveraging the TokenID, the Mirror Node already provides all the features needed: |
| 195 | + |
| 196 | +- Record the original dollar amounts alongside calculated HBAR amounts automatically |
| 197 | +- Maintain exchange rate information for each transaction |
| 198 | +- Provide historical dollar amounts and exchange rates used |
| 199 | + |
| 200 | +The mirror node must conform to the new `transactionFee` supporting TokenIDs. |
| 201 | + |
| 202 | +The `/api/v1/tokens` and `api/v1/tokens/*` endpoints are not expected to return results when queried with system token IDs, therefore, no changes are expected at the API level. |
| 203 | + |
| 204 | +### Impact on SDK |
| 205 | + |
| 206 | +SDKs will be updated to: |
| 207 | + |
| 208 | +- Add convenience methods for dollar denomination (e.g., `addDollarTransfer()`, `setMaxTransactionFee(new Dollar(0.5))`, etc.) |
| 209 | +- Provide system TokenID constants (e.g., `TokenId.USD`) |
| 210 | +- Support dollar amount validation and formatting |
| 211 | +- Maintain backward compatibility with existing HBAR-only methods |
| 212 | + |
| 213 | +## Backwards Compatibility |
| 214 | + |
| 215 | +This proposal is fully backward compatible: |
| 216 | + |
| 217 | +- Existing HBAR-denominated transactions continue to work unchanged |
| 218 | +- New dollar denomination is purely additive functionality |
| 219 | +- Few changes to existing protobuf field meanings or validations |
| 220 | +- SDKs can add new methods while preserving existing APIs |
| 221 | + |
| 222 | +## Security Implications |
| 223 | + |
| 224 | +Security considerations include: |
| 225 | + |
| 226 | +- Exchange rate oracle integrity: Leverages existing trusted oracle used for network fees |
| 227 | +- Transaction replay: Dollar amounts are converted at consensus time, preventing value manipulation |
| 228 | +- Validation: Network validates that only one denomination type is used per field |
| 229 | + |
| 230 | +The proposal actually improves security by: |
| 231 | + |
| 232 | +- Eliminating client-side conversion errors and bugs |
| 233 | +- Providing consensus-level validation of exchange calculations |
| 234 | +- Reducing fraud potential from manipulated conversion rates |
| 235 | + |
| 236 | +## How to Teach This |
| 237 | + |
| 238 | +Documentation and educational materials should emphasize: |
| 239 | + |
| 240 | +- Dollar denomination as an optional alternative to HBAR amounts |
| 241 | +- Use cases where dollar denomination provides the most benefit (scheduled transactions, service pricing) |
| 242 | +- Exchange rate consistency with network fees |
| 243 | +- SDK convenience methods for common dollar operations |
| 244 | +- Best practices for choosing between HBAR and dollar denomination |
| 245 | + |
| 246 | +Integration guides should show: |
| 247 | + |
| 248 | +- Migration paths for existing applications |
| 249 | +- Testing strategies for fiat-denominated transactions |
| 250 | + |
| 251 | +## Reference Implementation |
| 252 | + |
| 253 | +_The reference implementation must be complete before any HIP is given the status |
| 254 | +of “Final.” The final implementation must include test code and documentation._ |
| 255 | + |
| 256 | +TBD |
| 257 | + |
| 258 | +## Rejected Ideas |
| 259 | + |
| 260 | +- **Multiple Exchange Rate Sources**: Using different exchange rates for different transaction types would confuse users and complicate the system. Maintaining consistency with network fee rates provides better UX. |
| 261 | +- **Real-time Rate Updates**: More frequent exchange rate updates were considered but rejected to maintain consistency with existing network fee mechanisms and avoid creating conflicting rate sources. |
| 262 | + |
| 263 | +## Open Issues |
| 264 | + |
| 265 | +- **Precision Handling**: Specification of decimal precision and rounding rules for dollar amounts |
| 266 | +- **System TokenID Range**: Final determination of whether to use `max uint64` and below values or system account range (e.g., `0.0.150`) for fiat currency identifiers |
| 267 | +- **Future Currency Support**: Preparing the field for additional fiat currencies beyond USD |
| 268 | +- **Creating dedicated protobuf fields for HBAR-only fields**: The TokenID solution allow using USD when it is possible to use a token, but it does not allow to define USD for HBAR only fields, like for example max transaction fees. |
| 269 | + |
| 270 | +## References |
| 271 | + |
| 272 | +- [Hedera Exchange Rate API Documentation](https://docs.hedera.com/hedera/sdks-and-apis/rest-api#exchange-rates) |
| 273 | +- [Mirror Node Exchange Rate Endpoint](https://mainnet.mirrornode.hedera.com/api/v1/network/exchangerate) |
| 274 | +- [TokenID Protobuf Definition](https://github.com/hashgraph/hedera-protobufs/blob/main/services/basic_types.proto) |
| 275 | +- [Custom Fixed Fees Documentation](https://docs.hedera.com/hedera/sdks-and-apis/hedera-api/token-service/customfees/fixedfee) |
| 276 | + |
| 277 | +## Copyright/license |
| 278 | + |
| 279 | +This document is licensed under the Apache License, Version 2.0 — |
| 280 | +see [LICENSE](../LICENSE) or <https://www.apache.org/licenses/LICENSE-2.0>. |
0 commit comments