Skip to main content

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.

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:
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:
AssetSymbol StringAsset 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.
// ✅ 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;
// ❌ 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:
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

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)

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

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

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.
1

Take the symbol string

Use the exact format: "SYMBOL/USD" — uppercase, forward slash, no spaces.
2

Hash it with keccak256

Use any of the generation methods above — JavaScript, Python, Solidity, or a Foundry test.
3

Compare against the published ID

The output should exactly match the value in the asset ID reference table above.
4

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.

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.
// ✅ 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: 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

Gas Optimization Tips

Reduce the cost of your oracle integration in production.

Complete Example Contract

See all integration patterns combined in a single production-ready contract.