How to Write and Deploy a Simple Stablecoin on Linea
Learn how to write and deploy your own stablecoin on the Linea network
Stablecoins have become a key part of the blockchain and web3 ecosystem, helping users avoid the volatility of cryptocurrencies like Bitcoin and Ethereum. In this blog, we’ll learn what stablecoins are and how to write a simple stablecoin contract. In this blog, we’ll learn what stablecoins are and how to write and deploy a simple stablecoin contract on Linea.
What are stablecoins?
Stablecoins are a type of cryptocurrency designed to keep its value steady. They do this by pegging their value to something more stable, like a traditional currency, such as the US dollar, a commodity like gold, or even another cryptocurrency. The goal of stablecoins is to combine the advantages of cryptocurrencies—such as fast transactions and decentralization—with the stability of traditional financial assets, making them more reliable and useful for everyday transactions.
stablecoins can be classified based on several factors, including their collateral structure, stability mechanism, and relative stability. Here's a comprehensive breakdown of stablecoin types:
1. Fiat-collateralized stablecoins
Traditional currencies back fiat-collateralized stablecoins like the US dollar or Euro, held in reserves (e.g., Tether USDT, USD Coin USDC). Since they're directly tied to fiat, they are stable and easy to use. However, they rely on centralized entities for reserves and face regulatory oversight.
2. Crypto-collateralized stablecoins
Crypto-collateralized stablecoins, like DAI and LUSD, are backed by other cryptocurrencies and are often over-collateralized to handle crypto’s volatility. They are more decentralized than fiat-backed options. However, they're complex and can be less stable during market downturns, requiring active management to maintain stability.
3. Algorithmic stablecoins
Algorithmic stablecoins, such as Ampleforth (AMPL), rely on algorithms to adjust supply and stabilize prices without direct collateral. While highly decentralized and flexible, they are difficult to understand and can be vulnerable to rapid loss of value ("death spirals") if confidence drops.
There are also a few others, like hybrid stablecoins such as Frax (FRAX), which combine collateral and algorithmic methods to achieve stability, offering a balance of different models but with added complexity. Commodity-backed stablecoins, like Paxos Gold (PAXG), are tied to physical assets, providing digital exposure to real-world commodities. Yield-bearing stablecoins, such as Compound USD (cUSD), generate returns through lending or investments, offering passive income but with higher associated risks.
Now that we understand stablecoins and the types of stablecoins in the ecosystem today let’s explore how to create a stablecoin on the Linea network.
Set up the development environment
The first step is to ensure your environment is set up properly:
-
Install Node.js and npm (Node package manager).
-
Install Hardhat by running:
npm install --save-dev hardhat
Create a new Hardhat project
In your project directory, initialize a new Hardhat project:
npx hardhat init
We’ll use TypeScript for this tutorial, as Hardhat already has all the necessary dependencies for you. After initialization, you'll have a project structure that includes:
- contracts/: Solidity contracts
- ignition/: Ignition deployment modules
- test/: Test files
- hardhat.config.js: Hardhat configuration
Now, let’s dive into writing our own stablecoin contract for the RadStablecoin (RAD). This will be a simple Ethereum-collateralized stablecoin with a 150% collateralization ratio.
In this contract:
- ETH will be used as collateral.
- A 150% collateralization ratio will ensure stability.
- Users can mint stablecoins by sending ETH and burn them to reclaim their collateral.
- A simple price oracle will be used to fetch the price of ETH (in a real-world scenario, you’d use a secure decentralized oracle).
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/// @title RadStablecoin
/// @notice A simple stablecoin implementation with collateral-based minting
/// @dev Inherits from ERC20 and Ownable
contract RadStablecoin is ERC20, Ownable {
/// @notice The collateralization ratio (150%)
uint256 public constant COLLATERAL_RATIO = 150;
/// @notice The precision for price calculations (2 decimal places)
uint256 public constant PRICE_PRECISION = 100;
/// @notice Mapping to track collateral balances for each user
mapping(address => uint256) public collateralBalances;
/// @notice Initializes the RadStablecoin contract
constructor() ERC20("RadStablecoin", "RAD") {}
/// @notice Allows users to deposit LineaETH as collateral
/// @dev The deposited amount is added to the user's collateral balance
function depositCollateral() external payable {
collateralBalances[msg.sender] += msg.value;
}
/// @notice Allows users to withdraw their deposited collateral
/// @dev Implements the checks-effects-interactions pattern to prevent reentrancy
/// @param amount The amount of collateral to withdraw (in wei)
function withdrawCollateral(uint256 amount) external {
require(collateralBalances[msg.sender] >= amount, "Insufficient collateral");
collateralBalances[msg.sender] -= amount; // Update state before making external call
payable(msg.sender).transfer(amount); // Safely transfer LineaETH after updating state
}
/// @notice Mints stablecoin (RAD) based on the user's deposited collateral
/// @dev Calculates required collateral based on current LineaETH price and mints RAD tokens
/// @param stablecoinAmount The amount of stablecoin to mint
function mintStablecoin(uint256 stablecoinAmount) external {
uint256 collateralRequired = (stablecoinAmount * COLLATERAL_RATIO * PRICE_PRECISION) / (100 * getCurrentPrice());
require(collateralBalances[msg.sender] >= collateralRequired, "Insufficient collateral");
collateralBalances[msg.sender] -= collateralRequired;
_mint(msg.sender, stablecoinAmount);
}
/// @notice Burns stablecoin (RAD) and returns the equivalent collateral to the user
/// @dev Calculates collateral to return based on current LineaETH price and burns RAD tokens
/// @param stablecoinAmount The amount of stablecoin to burn
function burnStablecoin(uint256 stablecoinAmount) external {
require(balanceOf(msg.sender) >= stablecoinAmount, "Insufficient stablecoin balance");
uint256 collateralToReturn = (stablecoinAmount * COLLATERAL_RATIO * PRICE_PRECISION) / (100 * getCurrentPrice());
_burn(msg.sender, stablecoinAmount);
collateralBalances[msg.sender] += collateralToReturn;
}
/// @notice Gets the current price of LineaETH in USD
/// @dev In a real-world scenario, this would fetch the price from an oracle
/// @return The current LineaETH price in USD (fixed at $2000 for simplicity)
function getCurrentPrice() public view returns (uint256) {
// In a real-world scenario, this would fetch the current LineaETH/USD price from an oracle
// For simplicity, we'll use a fixed price of $2000 per LineaETH
return 200000; // $2000.00
}
}
- Collateral Management:
- Depositing Collateral:
- Users can deposit Ether (ETH) as collateral by calling depositCollateral.
- The deposited ETH is stored in the collateralBalances mapping, tracking total collateral for users.
- Withdrawing Collateral:
- Users can withdraw their collateral using withdrawCollateral.
- Depositing Collateral:
- Stablecoin Operations:
- Minting Stablecoins:
- The mintStablecoin function ensures that the user has sufficient collateral to mint the requested amount of RAD tokens.
- Burning Stablecoins:
- The burnStablecoin function burns the specified amount of RAD and returns the equivalent amount of ETH based on the 150% collateralization ratio and the current price of ETH.
- Minting Stablecoins:
- Price Feeds:
- Fetching the Price of ETH:
- The contract includes a function getCurrentPrice that returns a fixed price of $2000 for ETH in this simplified example.
- Fetching the Price of ETH:
Configure Hardhat for Linea
Update your hardhat.config.js to include the Linea testnet configuration. Add the following network configuration:
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import * as dotenv from "dotenv";
dotenv.config();
const config: HardhatUserConfig = {
solidity: "0.8.24",
networks: {
"linea-testnet": {
url: `https://linea-sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts: [process.env.ACCOUNT_PRIVATE_KEY!],
},
},
};
export default config;
Create the deployment script
In the ignition/modules/ directory, create a file called RadStablecoin.ts and include the following script:
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
const RadStablecoinModule = buildModule("RadStablecoinModule", (m) => {
// Deploy the RadStablecoin contract
const radStablecoin = m.contract("RadStablecoin");
// Return the deployed contract instance
return { radStablecoin };
});
export default RadStablecoinModule;
To compile the contract run the following command:
npx hardhat compile
Before deploying the smart contract, make sure to update the .env file in the directory with the following values:
# Infura API key for connecting to Ethereum networks
INFURA_API_KEY=your_infura_api_key_here
# Private key of the account to be used for deployments and transactions
ACCOUNT_PRIVATE_KEY=your_account_private_key_here
Deploy the contract
Finally, deploy the RadStablecoin contract to Linea:
npx hardhat ignition deploy ignition/modules/RadStablecoin.ts --network linea-testnet
This will deploy the marketplace smart contract on Linea Sepolia.
What next?
Stablecoins play a crucial role in the cryptocurrency ecosystem, offering much-needed stability for financial applications. In this tutorial, we explored the core concepts of stablecoins, their various types, and how they bridge traditional finance with decentralized technology. We also gained hands-on experience by creating and deploying RadStablecoin on the Linea network, deepening our understanding of collateral-backed stablecoins —happy coding!
Keep reading our latest stories
Developers, security news, and more