Make a token on PRANA · deploy it, then use it for things
PRANA is a standard EVM chain (chainId 712217 /
0xade19). Deploying a token is an ordinary ERC-20 deploy — and then it plugs
straight into the live economy: list it on KulaSwap, use it as CDP collateral, and
LP it for gauge rewards. This page is the whole path. (No-code? A SCOT
side-token on MELEK-Engine needs zero Solidity — see that page.)
1 · The contract
A standard OpenZeppelin ERC-20. Change the name, symbol and supply; that's the whole edit:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
// A standard ERC-20 — a PRC-20 the moment it lands on PRANA (see /tokens).
contract MyToken is ERC20, Ownable {
constructor(address owner_)
ERC20("My Token", "MYT") // <- change name + symbol
Ownable(owner_)
{
_mint(owner_, 1_000_000 ether); // 1,000,000 MYT (18 decimals) to you
}
// OPTIONAL — remove this for a fixed, un-inflatable supply.
function mint(address to, uint256 amount) external onlyOwner {
_mint(to, amount);
}
}
Deploy it
# Foundry forge install OpenZeppelin/openzeppelin-contracts forge create src/MyToken.sol:MyToken \ --rpc-url https://rpc.prana.melek.salon --private-key $PK --broadcast \ --constructor-args $YOUR_ADDRESS cast code <deployed-address> --rpc-url https://rpc.prana.melek.salon # confirm bytecode exists # Hardhat npx hardhat run scripts/deploy.js --network prana
Full toolchain config (Foundry / Hardhat / viem / ethers) is on PRANA contract dev. Gas comes from the faucet or from mining PRANA.
2 · How copying / forking a contract actually works
Almost nobody writes a token from a blank file. The real workflow is copy a proven contract and change the parameters. Four honest ways:
- OpenZeppelin Contracts Wizard (wizard.openzeppelin.com)
— click the features you want, copy the generated Solidity, deploy on PRANA.
// wizard.openzeppelin.com — toggle Mintable / Burnable / Capped / Ownable / Votes, // copy the generated Solidity, and deploy it on PRANA exactly as above. No hand-writing.
- Copy verified source from a block explorer — on Etherscan / Polygonscan / any EVM
explorer, open a token's Contract → Code tab, copy the verified source, change
name/symbol/ supply, redeploy on PRANA. - Fork a reference repo — clone the canonical implementation and edit constructor args. A token: OpenZeppelin or Solmate. A whole DEX: Uniswap/v2-core + v2-periphery — which is exactly what KulaSwap is.
- Verify your source on PRANAScan so others can read + fork it too. (Source verification on the explorer is coming; until then publish your ABI alongside the address — that's what Deployed contracts does.)
Licenses — check the SPDX line. The// SPDX-License-Identifier:at the top of a file tells you if you may copy it. OpenZeppelin is MIT; Uniswap-V2 is GPL-3.0 — both are open and forkable (GPL means keep it open too). Do not copy a contract markedUNLICENSEDor one with no SPDX line and closed source — that's someone's proprietary code.
3 · What the token is FOR
A token nobody can use is a number in a mapping. Here's how it becomes useful on PRANA — all against the live KulaSwap contracts (addresses + ABIs):
a) List it on KulaSwap (a tradable market)
import { Contract, parseUnits } from 'ethers'; // v6, signer already on chainId 712217
// Authoritative Router / Factory / WPRANA addresses: https://witness.melek.salon/dev/contracts
const ROUTER = '0x24e53792B7f6609c85Bd3a3179A90638c9Dbc8B5';
const MYT = '<your-token-address>';
const token = new Contract(MYT, ['function approve(address,uint256) returns (bool)'], signer);
const router = new Contract(ROUTER, [
'function addLiquidityETH(address token,uint amountTokenDesired,uint amountTokenMin,uint amountETHMin,address to,uint deadline) payable returns (uint,uint,uint)',
], signer);
// 1) let the router pull your token
await (await token.approve(ROUTER, parseUnits('10000', 18))).wait();
// 2) seed a MYT / PRANA pool: 10,000 MYT + 5 PRANA. The pair is CREATED on the first add.
const deadline = Math.floor(Date.now() / 1000) + 600;
await (await router.addLiquidityETH(
MYT, parseUnits('10000', 18), 0n, 0n, await signer.getAddress(), deadline,
{ value: parseUnits('5', 18) }, // native PRANA, wrapped to WPRANA by the router
)).wait();
// Anyone can now swap PRANA <-> MYT on kula.money.
Adding liquidity through the router auto-creates the pair on the Factory. Now it trades on kula.money.
b) Use the CDP-collateral pattern
KulaSwap's CDP vaults let you lock KULA as collateral and borrow mMELEK — a MELEK-denominated, over-collateralized debt note (NOT a stablecoin). Live on kula.money → Borrow. A new collateral type is onboarded by governance (the DAO Timelock), not automatically — so this is the pattern your token can follow, once voted in, not an instant listing.
c) LP it + gauge rewards
LP tokens (your MYT/PRANA position) can be staked in a
LiquidityGauge; the GaugeController directs emissions to gauges by weight
(stake() / earned() / getReward() — see
Deployed contracts). Honest note: read earned()
on-chain — do not assume an APR. MWALI (a reward token) has 0 supply on-chain right now;
PoL emissions are not yet turned on (see how to get each token).
No-code: SCOT side-token → · How to get each token → · The Token Matrix → · Token standards (PRC-20) → · Deployed contracts + ABIs →