Skip to main content
IFÁ Labs is deployed natively on Sui as a Move package — not a port of the EVM contracts, but a ground-up Sui implementation using shared objects, Move’s type system, and Sui’s object model. This page gives you the full picture before you write any code.

What Is Deployed on Sui

Three packages are live on Sui Testnet:

Oracle Contract

The core price feed. Stores and exposes stablecoin prices via shared objects. This is what your protocol integrates against.

Faucet

Multi-token testnet faucet. Claim SUI and WAL for development and testing.

HLP Token

Heterogeneous Liquidity Provider token. Foundation for the upcoming Sui swap contract. Not yet available for integration.

Sui Testnet Object IDs

Oracle

ObjectID
Package ID0x4d165602d4bb3a7d428a3aa567e27cbe03c9de2ed5995f8c13d1adc4cd3d196f
Feed Object ID0x9d5fc0fce3dc11efd95ef4b3218f3b45ff17012fbc629b35529f66833e46d91a
Verifier Object ID0x49ba59356bdd51f42ed433f452099e32251601027d4e7d39bf86e8e1c12c3ad5

Faucet

ObjectID
Package ID0xf77385d9dc49cf4774c0411a2b36d89d294ad5fe42ab1f52cc7d515044b1fa27
Registry ID0x5c0dc844ba7647af146e9edf7618bdbf47025dd0816e60db7ad9256cafda1054
When reading prices, always pass the Feed Object ID — not the Package ID. The Package ID is only needed when importing ifa_oracle as a dependency in your own Move package’s Move.toml.

How Sui Differs from EVM

This is the most important section for developers coming from the EVM integration. Every one of these differences will cause a bug if you miss it.

1. Shared Objects Instead of Contract Addresses

On EVM you call a function on a contract address. On Sui, the price feed is stored in a shared object — a piece of on-chain state that any transaction can reference.
// EVM mental model — call a contract
oracle.getAssetInfo(assetId);

// Sui mental model — pass the shared object by reference
price_feed::get_asset_info(&feed, asset_id);
When building a transaction, you pass the Feed Object ID as an object argument — not as a raw address.

2. Positive Decimal Convention

EVM returns a negative int8 decimal (e.g. -18). Sui returns a positive u8 decimal (e.g. 18). The math is identical — divide by 10^18 — but the sign is different.
ChainDecimal fieldFormula
EVM-18 (int8)price / 10^(-decimal) = price / 10^18
Sui18 (u8)price / 10^decimal = price / 10^18

3. Timestamps Are in Milliseconds

On EVM, block.timestamp is in seconds. On Sui, clock::timestamp_ms(clock) is in milliseconds.
// Sui — 1 hour in milliseconds
let max_age_ms: u64 = 3_600_000;

// NOT 3_600 — that would be 3.6 seconds
This affects every staleness check you write. Getting the unit wrong means your freshness check either never triggers (too large) or always triggers (too small).

4. Derived Pair Decimal Is Always 30

On EVM, derived pairs inherit the decimal from the underlying assets. On Sui, all derived pairs always return decimal = 30 — regardless of which assets are involved. derived_price is always scaled by 10^30.
let pair        = price_feed::get_pair_by_id(feed, cngn_id, usdt_id, 0);
let raw_price   = price_feed::derived_price(pair);
let human_price = raw_price / 1_000_000_000_000_000_000_000_000_000_000; // 10^30

5. Missing Assets Abort — No False Flag

On EVM, getAssetInfo returns exists = false for unsupported assets. On Sui, derived pair functions abort the transaction if either underlying asset is missing. get_asset_info and get_assets_info are safe — they return a bool exists flag. But get_pair_by_id and all batch pair functions abort on missing assets.
// Safe — returns (PriceFeed, bool)
let (feed, exists) = price_feed::get_asset_info(oracle_feed, asset_id);
if (!exists) { /* handle gracefully */ };

// Aborts if either asset missing — verify first
assert!(exists_0 && exists_1, E_ASSET_NOT_FOUND);
let pair = price_feed::get_pair_by_id(oracle_feed, id0, id1, 0);

6. Asset IDs Use a Different Format

The underlying 32-byte values are identical across all networks. But on Sui they are passed as vector<u8> wrapped in a Bytes32 struct — not as bytes32 hex strings.
// Sui Move — hex literal, no 0x prefix
use ifa_oracle::bytes32;
let usdt_id = bytes32::new(
    x"6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d"
);
// TypeScript — byte array, no 0x prefix
const usdtId = Array.from(
  Buffer.from("6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d", "hex")
);

7. Built-In Freshness Helper

The Sui contract exposes price_feed::is_fresh directly — you don’t need to implement the staleness subtraction yourself.
// Sui — built-in helper
let fresh = price_feed::is_fresh(price_feed, current_time_ms, max_age_ms);

// EVM — you implement this yourself
require(block.timestamp - info.lastUpdateTime <= MAX_PRICE_AGE, "Stale");

Supported Assets on Sui

All feeds available on EVM are also available on Sui Testnet. Asset IDs are identical across chains — only the format differs.
AssetCategoryAsset ID
USDT/USDGlobal0x6ca0cef6107263f3b09a51448617b659278cff744f0e702c24a2f88c91e65a0d
USDC/USDGlobal0xf989296bde68043d307a2bc0e59de3445defc5f292eb390b80d78162c8a6b13d
CNGN/USDEmerging Market0x83a18c73cf75a028a24b79cbedb3b8d8ba363b748a3210ddbcaa95eec3b87b3a
ZARP/USDEmerging Market0x12373a3b1c4827c84bf6d7b11df100442695d0abfdb7a20d30a41d67d58e75a8
BRZ/USDEmerging Market0xbc60b55b031dce1ee5679098bf2f35d66a94a566124e2b233324d2bafcc6d5b5
ETH/USDReference0x8c3fb07cab369fe230ca4e45d095f796c4c1a30131f1799766d4fec5ee1325c0

Architecture Overview

                    ┌─────────────────────────────────┐
                    │         IFÁ Labs Relayer          │
                    │  Aggregates prices off-chain and  │
                    │  submits via IfaPriceFeedVerifier  │
                    └───────────────┬─────────────────┘


                    ┌─────────────────────────────────┐
                    │     IfaPriceFeedVerifier          │
                    │  Shared object — validates        │
                    │  relayer address and feed ID      │
                    │  before writing to the feed       │
                    └───────────────┬─────────────────┘
                                    │  submit_price_feed

                    ┌─────────────────────────────────┐
                    │         IfaPriceFeed              │
                    │  Shared object — stores all       │
                    │  asset prices keyed by Bytes32    │
                    │  asset ID                         │
                    └───────────────┬─────────────────┘
                                    │  get_asset_info
                                    │  get_assets_info
                                    │  get_pair_by_id

                    ┌─────────────────────────────────┐
                    │       Your Move Protocol          │
                    │  Passes &IfaPriceFeed by          │
                    │  immutable reference to read      │
                    │  prices                           │
                    └─────────────────────────────────┘
Key point: Your protocol only ever interacts with IfaPriceFeed — the bottom shared object. You never interact with the verifier directly. The relayer and verifier are IFÁ Labs infrastructure.

Integration Checklist

Before writing your first line of Move or TypeScript, confirm these:
1

Sui CLI installed and testnet environment active

    sui client switch --env testnet
    sui client active-env  # should print "testnet"
2

Testnet SUI available for gas

Price reads via devInspectTransactionBlock are free. You need SUI for deploying your own contracts. Claim from the IFÁ Labs Faucet or faucet.sui.io.
3

Feed Object ID saved — not Package ID

The value you use in transactions is: 0x9d5fc0fce3dc11efd95ef4b3218f3b45ff17012fbc629b35529f66833e46d91aNot the Package ID. Save this now.
4

Understood the millisecond timestamp convention

All last_update_time values and the max_age parameter in is_fresh are in milliseconds. 3_600_000 = 1 hour.
5

Asset IDs formatted correctly for Sui

No 0x prefix. Use x"..." hex literal syntax in Move. Use Buffer.from("...", "hex") in TypeScript.

What to Integrate Against

If you are building…Use this
A Move smart contract on Suiifa_oracle::price_feed — import as a Move dependency
A TypeScript frontend or backendSui TypeScript SDK + devInspectTransactionBlock
A quick test or CLI checkSui CLI client call
An AI tool or agentIFÁ Labs MCP Server — get_network_info returns Sui object IDs

Coming Soon on Sui

FeatureStatus
Sui Mainnet deploymentPlanned — after testnet validation
Sui swap contractIn development — HLP token deployed
Additional Sui feedsBased on ecosystem demand

Next Steps

Read Latest Price

Full code examples for reading prices in Move and TypeScript.

Function Reference

Complete reference for every public function in the Sui Move contracts.

Testnet Faucet

Claim testnet SUI and WAL for development.

Contract Addresses

All Sui object IDs and EVM addresses in one place.