Skip to main content

Stablecoins on Sui

Stablecoins are a type of cryptocurrency that are designed to maintain a stable value relative to a fiat currency or a basket of assets. They are widely used for trading, lending, and as a store of value.

Available stablecoins

On Sui, you can interact with various stablecoins such as USDC, USDT, Agora, and Ondo USDY.

USDC (USD Coin)

USDC is a fully collateralized US dollar stablecoin issued by regulated financial institutions. Each USDC token is backed by one US dollar held in reserve. USDC is widely used for trading, payments, and as a stable store of value.

For more detailed information on how to interact with USDC on Sui, refer to the USDC guide.

Site: Circle

USDT (Tether)

USDT, also known as Tether, is one of the oldest and most widely used stablecoins. It is pegged to the US dollar and is backed by a mix of reserves, including cash, cash equivalents, and other assets.

USDT is currently not issued natively on Sui. For more information on bridging USDT to Sui, refer to SUI Bridging.

Site: Tether

Agora

AUSD is a fully collateralized US dollar stablecoin issued by Agora Finance.

Site: Agora Finance

Ondo USDY

USDY is a fully collateralized US dollar stablecoin issued by Ondo Finance, allowing users to earn yield from US Treasury Bills.

Site: Ondo Finance

How to use USDC on Sui

info

While this example uses USDC, the same principles can be applied to any asset on Sui that uses the Sui Coin standard.

Prerequisites

  • Make sure you have some USDC tokens. Get Testnet tokens from Circle's faucet.

USDC stablecoin source code

The USDC stablecoin source code is available in the circlefin/stablecoin-sui repository.

Import the USDC module in your Move package

To import the USDC module, add the following line to the [dependencies] section of your Move package's Move.toml file:

usdc = { git = "https://github.com/circlefin/stablecoin-sui.git", subdir = "packages/usdc", rev = "master" }

After importing the module, your Move package should look like the following:

[package]
name = "usdc_usage"
edition = "2024.beta"

[dependencies]
Sui = { override = true, local = "../../../crates/sui-framework/packages/sui-framework" }
usdc = { git = "https://github.com/circlefin/stablecoin-sui.git", subdir = "packages/usdc", rev = "master" }

[addresses]
usdc_usage = "0x0"
warning

The usdc package uses a specific version of the sui package, which causes a version conflict with the Sui package in the Sui framework. You can override the version of the Sui package in your Move.toml file to use a different version. Add the override = true flag to the Sui package in your Move.toml file.

Using USDC in Move

USDC uses the Sui Coin standard and can be used just like any other coin type in the Sui framework.

After importing the usdc package, you can use the USDC type.

use usdc::usdc::USDC;

Then use the USDC type just as you would use the SUI type when accepting a Coin<SUI> parameter.

public fun buy_sword_with_usdc(
coin: Coin<USDC>,
tx_context: &mut TxContext
): Sword {
let sword = create_sword(coin.value(), tx_context);

transfer::public_transfer(coin, @0x0); // Essentially burning the coin, would send to actual recipient in production

sword
}

The following example demonstrates how to use the USDC stablecoin in a Move package and how it relates to using the SUI type as well as any generic coin types.

module usdc_usage::example;

use sui::coin::Coin;
use sui::sui::SUI;
use usdc::usdc::USDC;

public struct Sword has key, store {
id: UID,
strength: u64
}

public fun buy_sword_with_usdc(
coin: Coin<USDC>,
tx_context: &mut TxContext
): Sword {
let sword = create_sword(coin.value(), tx_context);

transfer::public_transfer(coin, @0x0); // Essentially burning the coin, would send to actual recipient in production

sword
}

public fun buy_sword_with_sui(
coin: Coin<SUI>,
tx_context: &mut TxContext
): Sword {
let sword = create_sword(coin.value(), tx_context);

transfer::public_transfer(coin, @0x0); // Essentially burning the coin, would send to actual recipient in production

sword
}

public fun buy_sword_with_arbitrary_coin<CoinType>(
coin: Coin<CoinType>,
tx_context: &mut TxContext
): Sword {
let sword = create_sword(coin.value(), tx_context);

transfer::public_transfer(coin, @0x0); // Essentially burning the coin, would send to actual recipient in production

sword
}

fun create_sword(strength: u64, tx_context: &mut TxContext): Sword {
let id = object::new(tx_context);
Sword { id, strength }
}

Using USDC in PTBs

Use USDC in your PTBs just like any other coin type.

Create a Coin<USDC> object with the coinWithBalance function.

const usdcCoin = coinWithBalance({
type: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',
balance: 1_000_000
})
info

0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29 is the Testnet address for USDC, while 0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7 is the Mainnet address.

This coin object can be used as a parameter for any function that accepts a Coin<USDC> parameter or a generic Coin parameter.

const [sword] = tx.moveCall({
target: '0xcbbf37a851ed7b625731ca497e2d4aea18cf18145fac3b78bd64f274f6a09d30::usdc_usage::buy_sword_with_usdc',
arguments: [
usdcCoin
]
});
const [sword] = tx.moveCall({
target: '0xcbbf37a851ed7b625731ca497e2d4aea18cf18145fac3b78bd64f274f6a09d30::usdc_usage::buy_sword_with_arbitrary_coin',
typeArguments: ['0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC'],
arguments: [
usdcCoin
]
});

This coin object can also be used as input for the transferObjects function.

tx.transferObjects([usdcCoin], recipientAddress);