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

# Working with Asset IDs

> How IFÁ Labs asset IDs are structured, generated with keccak256, and used in Solidity calls — plus a complete reference table for every supported feed.

Every price feed in IFÁ Labs is identified by a fixed `bytes32` value called an asset ID. Understanding how asset IDs work — how they're generated, how to use them safely, and how to generate new ones — is foundational to building a correct integration.

***

## What an Asset ID Is

An asset ID is a deterministic `bytes32` identifier generated by hashing the asset's symbol string using `keccak256`:

```solidity theme={null}
bytes32 assetId = keccak256(abi.encodePacked("USDT/USD"));
```

This produces a fixed 32-byte value that serves as the key in the oracle's on-chain storage mapping. The same asset ID works identically across every network IFÁ Labs is deployed on — Base Mainnet, Base Sepolia, AssetChain Testnet, and all future deployments.

**Why `keccak256`?**

* **Collision-resistant.** Virtually impossible for two different symbol strings to produce the same ID.
* **Deterministic.** Given the same input string, the output is always identical — across languages, environments, and chains.
* **Gas-efficient.** `keccak256` is a native EVM opcode. Computing it costs minimal gas and it's the standard pattern for on-chain key generation.
* **Self-documenting.** A developer can verify any asset ID independently by hashing the symbol string themselves — no trust required.

***

## Complete Asset ID Reference

All currently supported feeds and their verified asset IDs:

| Asset        | Symbol String | Asset ID (bytes32)                                                   |
| ------------ | ------------- | -------------------------------------------------------------------- |
| **USDT/USD** | `"USDT/USD"`  | `0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d` |
| **USDC/USD** | `"USDC/USD"`  | `0xf989296bde68043d307a2bc0e59de3445defc5f292eb390b80d78162c8a6b13d` |
| **CNGN/USD** | `"CNGN/USD"`  | `0x83a18c73cf75a028a24b79cbedb3b8d8ba363b748a3210ddbcaa95eec3b87b3a` |
| **ZARP/USD** | `"ZARP/USD"`  | `0x12373a3b1c4827c84bf6d7b11df100442695d0abfdb7a20d30a41d67d58e75a8` |
| **BRZ/USD**  | `"BRZ/USD"`   | `0xbc60b55b031dce1ee5679098bf2f35d66a94a566124e2b233324d2bafcc6d5b5` |
| **ETH/USD**  | `"ETH/USD"`   | `0x8c3fb07cab369fe230ca4e45d095f796c4c1a30131f1799766d4fec5ee1325c0` |

***

## Using Asset IDs in Solidity

### Declare as Constants

Always declare asset IDs as `bytes32 constant` at the contract level. This eliminates runtime computation and saves gas on every single call that references them.

```solidity theme={null}
// ✅ Correct — computed once at compile time
bytes32 public constant USDT_ASSET_ID =
    0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d;

bytes32 public constant USDC_ASSET_ID =
    0xf989296bde68043d307a2bc0e59de3445defc5f292eb390b80d78162c8a6b13d;

bytes32 public constant CNGN_ASSET_ID =
    0x83a18c73cf75a028a24b79cbedb3b8d8ba363b748a3210ddbcaa95eec3b87b3a;
```

```solidity theme={null}
// ❌ Avoid — computes keccak256 at runtime on every call
function getPrice() external view returns (int256) {
    bytes32 assetId = keccak256(abi.encodePacked("USDT/USD")); // wasted gas
    (IIfaPriceFeed.PriceFeed memory info,) = ORACLE.getAssetInfo(assetId);
    return info.price;
}
```

### Use a Central Registry

For protocols that support multiple assets dynamically, manage asset IDs in a central mapping rather than scattering them across functions:

```solidity theme={null}
contract AssetRegistry {
    mapping(string => bytes32) private _assetIds;
    address public owner;

    constructor() {
        owner = msg.sender;

        _assetIds["USDT/USD"] =
            0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d;
        _assetIds["USDC/USD"] =
            0xf989296bde68043d307a2bc0e59de3445defc5f292eb390b80d78162c8a6b13d;
        _assetIds["CNGN/USD"] =
            0x83a18c73cf75a028a24b79cbedb3b8d8ba363b748a3210ddbcaa95eec3b87b3a;
        _assetIds["BRZ/USD"]  =
            0xbc60b55b031dce1ee5679098bf2f35d66a94a566124e2b233324d2bafcc6d5b5;
        _assetIds["ZARP/USD"]  =
            0x12373a3b1c4827c84bf6d7b11df100442695d0abfdb7a20d30a41d67d58e75a8;
    }

    function getAssetId(string calldata symbol)
        external
        view
        returns (bytes32 assetId)
    {
        assetId = _assetIds[symbol];
        require(assetId != bytes32(0), "Registry: unknown asset");
    }

    function registerAsset(string calldata symbol, bytes32 assetId)
        external
    {
        require(msg.sender == owner, "Registry: not owner");
        require(assetId != bytes32(0), "Registry: invalid asset ID");
        _assetIds[symbol] = assetId;
    }
}
```

***

## Generating Asset IDs

If you're testing locally, requesting a new feed, or verifying an existing ID independently, you can generate asset IDs yourself.

### In Solidity

```solidity theme={null}
bytes32 assetId = keccak256(abi.encodePacked("USDT/USD"));
```

Use this in tests or scripts. Never use runtime `keccak256` generation in production contract logic — declare constants instead.

### In JavaScript (ethers.js)

```javascript theme={null}
const { ethers } = require("ethers");

function getAssetId(symbol) {
    return ethers.keccak256(ethers.toUtf8Bytes(symbol));
}

console.log(getAssetId("USDT/USD"));
// 0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d

console.log(getAssetId("CNGN/USD"));
// 0x83a18c73cf75a028a24b79cbedb3b8d8ba363b748a3210ddbcaa95eec3b87b3a
```

### In Python

```python theme={null}
from eth_abi import encode
from eth_hash.auto import keccak

def get_asset_id(symbol: str) -> str:
    return "0x" + keccak(symbol.encode("utf-8")).hex()

print(get_asset_id("USDT/USD"))
# 0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d
```

### In a Foundry Test

```solidity theme={null}
function test_assetIdGeneration() public pure {
    bytes32 expected =
        0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d;

    bytes32 generated = keccak256(abi.encodePacked("USDT/USD"));

    assertEq(generated, expected, "Asset ID mismatch");
}
```

Use this test pattern to verify any asset ID before hardcoding it in a production contract.

***

## Verifying an Asset ID Independently

The deterministic nature of `keccak256` means you never have to trust IFÁ Labs' published asset IDs — you can verify them yourself in seconds.

<Steps>
  <Step title="Take the symbol string">
    Use the exact format: `"SYMBOL/USD"` — uppercase, forward slash, no spaces.
  </Step>

  <Step title="Hash it with keccak256">
    Use any of the generation methods above — JavaScript, Python, Solidity, or a Foundry test.
  </Step>

  <Step title="Compare against the published ID">
    The output should exactly match the value in the [asset ID reference table](#complete-asset-id-reference) above.
  </Step>

  <Step title="Verify on-chain">
    Call `getAssetInfo` on the deployed contract with the generated ID. If `exists` returns `true`, the feed is live and the ID is correct.
  </Step>
</Steps>

***

## Common Mistakes

**Using the wrong string format.** Asset IDs are generated from `"SYMBOL/USD"` — uppercase, with a forward slash. `"usdt/usd"`, `"USDT-USD"`, and `"USDT"` all produce different hashes and will return `exists = false`.

```solidity theme={null}
// ✅ Correct
keccak256(abi.encodePacked("USDT/USD"))

// ❌ Wrong — lowercase
keccak256(abi.encodePacked("usdt/usd"))

// ❌ Wrong — hyphen instead of slash
keccak256(abi.encodePacked("USDT-USD"))
```

**Hardcoding a typo in the hex string.** A single wrong character in a `bytes32` hex value produces a completely different ID. Always verify asset IDs against this page and the on-chain contract before deploying.

**Assuming asset IDs are network-specific.** They are not. The same `bytes32` value works on every network IFÁ Labs is deployed on. There is no remapping or per-network ID table.

***

## Requesting a New Asset ID

New feeds are added by the IFÁ Labs team based on ecosystem demand. To request a new asset:

* **Email:** [support@ifalabs.com](mailto:support@ifalabs.com)
* **Telegram:** [t.me/ifalabs](https://t.me/ifalabs)
* **GitHub:** [IFA-Labs/oracle\_contract/issues](https://github.com/IFA-Labs/oracle_contract/issues)

Include the token contract address, backing proof, and the protocol or use case driving the request. Once approved and deployed, the asset ID will be added to the reference table on this page.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Gas Optimization Tips" icon="gauge" href="/gas-optimization-tips">
    Reduce the cost of your oracle integration in production.
  </Card>

  <Card title="Complete Example Contract" icon="file-code" href="/complete-example-contract">
    See all integration patterns combined in a single production-ready contract.
  </Card>
</CardGroup>
