Rootstock DeFi 101
This document is a DeFi 101 catalog – it lists common token standards, vulnerabilities, and best practices to review before deploying to production.
If you want step‑by‑step practical tutorials that run on Rootstock testnet:
- AMM tutorial: Constant‑Product AMM on Rootstock testnet
- Oracle tutorial: Chainlink oracle (mock) on Rootstock testnet
- Shared setup: Shared Setup Guide (Rootstock testnet)
Tokens are the lifeblood of DeFi. Rootstock is fully EVM-compatible, so all Ethereum token standards work seamlessly. This section covers ERC-20, ERC-721, and important extensions like ERC-20 Permit, ERC-4626, and RBTC wrapping.
Token Standards & Best Practices
1. ERC-20 Tokens
The ERC-20 standard is the foundation of fungible tokens on Ethereum-compatible blockchains like Rootstock. It defines a common interface that wallets, exchanges, and DeFi protocols can rely on.
Basic ERC-20 Implementation
OpenZeppelin provides battle-tested, audited implementations. Always use these instead of writing your own from scratch.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
constructor() ERC20("MyToken", "MTK") {
// Mint initial supply to the contract deployer
_mint(msg.sender, 1000000 * 10 ** decimals());
}
// Optional: allow owner to mint more tokens
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
Key points:
-
decimals() defaults to 18; you can override if needed.
-
_mint is internal; you control minting logic through public functions.
-
Ownable restricts minting to the owner; you can use AccessControl for more granular permissions.
Important Extensions
OpenZeppelin provides several extensions that add functionality while maintaining security.
ERC20Permit (EIP-2612)
Allows users to approve token spending with a signature, enabling gasless transactions. This is essential for meta-transactions and improving user experience.
How it works: Users sign a message off-chain containing approval details (spender, amount, deadline, nonce). Anyone can submit that signature to the permit function, which sets the allowance without requiring the token holder to pay gas.
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
contract MyTokenPermit is ERC20, ERC20Permit {
constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}