Skip to main content

Smart Contract Reference

📋 Overview​

This page provides a comprehensive reference for all Ethereal Offering smart contracts, including addresses, ABIs, and key functions. For full source code, see our GitHub repository.

🔗 Contract Addresses​

Ethereum Mainnet​

ContractAddressVerified
PSILO Token0x... (TBD)✅
MDAO Token0x... (TBD)✅
ETHO Token0x... (TBD)✅
PSD Stablecoin0x... (TBD)✅
DM Token0x... (TBD)✅
POB NFT0x... (TBD)✅
SHROOM NFT0x... (TBD)✅
Sacred Altar0x... (TBD)✅
AMM Router0x... (TBD)✅
Staking Contract0x... (TBD)✅
DAO Governance0x... (TBD)✅
Multi-sig Treasury0x... (TBD)✅

Ethereum Sepolia Testnet​

ContractAddressVerified
PSILO Token0x1234...abcd✅
MDAO Token0x2345...bcde✅
ETHO Token0x3456...cdef✅
Sacred Altar0x4567...def0✅
AMM Router0x5678...ef01✅

Note: Testnet contracts are for development and testing only. Use mainnet contracts for production.

📜 Contract Interfaces​

PSILO Token (ERC-20)​

Key Functions:

// Standard ERC-20
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);

// Crowdsale
function buy() external payable;
function getCurrentPrice() external view returns (uint256);
function getCurrentPhase() external view returns (uint8);

// Vesting
function getVestedAmount(address account) external view returns (uint256);
function getLockedAmount(address account) external view returns (uint256);
function claim() external;

Example Usage:

// Connect to contract
const psilo = new ethers.Contract(PSILO_ADDRESS, PSILO_ABI, signer);

// Check balance
const balance = await psilo.balanceOf(userAddress);
console.log(`Balance: ${ethers.utils.formatEther(balance)} PSILO`);

// Buy PSILO in crowdsale
const price = await psilo.getCurrentPrice();
const amount = ethers.utils.parseEther("1.0"); // 1 ETH
await psilo.buy({ value: amount });

// Claim vested tokens
await psilo.claim();

MDAO Token (ERC-20)​

Key Functions:

// Standard ERC-20
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);

// Voting Power
function getVotingPower(address account) external view returns (uint256);
function delegate(address delegatee) external;
function getDelegates(address account) external view returns (address);

// Time Multiplier
function getTimeMultiplier(address account) external view returns (uint256);
function getHoldDuration(address account) external view returns (uint256);

Example Usage:

const mdao = new ethers.Contract(MDAO_ADDRESS, MDAO_ABI, signer);

// Check voting power
const votingPower = await mdao.getVotingPower(userAddress);
console.log(`Voting Power: ${ethers.utils.formatEther(votingPower)}`);

// Delegate to another address
await mdao.delegate(delegateAddress);

// Check time multiplier
const multiplier = await mdao.getTimeMultiplier(userAddress);
console.log(`Time Multiplier: ${multiplier / 100}x`);

Sacred Altar​

Key Functions:

// Make Offering
function makeOffering(
uint256 ethoAmount,
bytes32 intentionHash
) external payable returns (uint256 pobId);

// View Stats
function getTotalBurned() external view returns (uint256);
function getUserBurned(address user) external view returns (uint256);
function getUserStreak(address user) external view returns (uint256);
function getOfferingCount(address user) external view returns (uint256);

// Calculate Rewards
function calculateMDAOReward(uint256 ethoAmount) external view returns (uint256);
function getTier(uint256 ethoAmount) external pure returns (uint8);

Example Usage:

const altar = new ethers.Contract(ALTAR_ADDRESS, ALTAR_ABI, signer);
const etho = new ethers.Contract(ETHO_ADDRESS, ETHO_ABI, signer);

// Approve ETHO spending
const burnAmount = ethers.utils.parseEther("100"); // 100 ETHO
await etho.approve(ALTAR_ADDRESS, burnAmount);

// Make offering
const intention = ethers.utils.formatBytes32String("Gratitude");
const donation = ethers.utils.parseEther("0.01"); // 0.01 ETH donation
const tx = await altar.makeOffering(burnAmount, intention, { value: donation });
const receipt = await tx.wait();

// Get POB NFT ID from event
const event = receipt.events.find(e => e.event === 'OfferingMade');
const pobId = event.args.pobId;
console.log(`Received POB NFT #${pobId}`);

AMM Router​

Key Functions:

// Swap Tokens
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);

// Add Liquidity
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);

// Remove Liquidity
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);

// Get Amounts
function getAmountsOut(uint256 amountIn, address[] calldata path)
external view returns (uint256[] memory amounts);

Example Usage:

const router = new ethers.Contract(ROUTER_ADDRESS, ROUTER_ABI, signer);

// Swap ETHO for PSD
const amountIn = ethers.utils.parseEther("100"); // 100 ETHO
const path = [ETHO_ADDRESS, PSD_ADDRESS];
const amountsOut = await router.getAmountsOut(amountIn, path);
const amountOutMin = amountsOut[1].mul(95).div(100); // 5% slippage
const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 minutes

// Approve ETHO
await etho.approve(ROUTER_ADDRESS, amountIn);

// Execute swap
await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
path,
userAddress,
deadline
);

Mushroom NFT (SHROOM)​

Key Functions:

// Breeding
function breed(uint256 parent1Id, uint256 parent2Id) external returns (uint256 offspringId);
function canBreed(uint256 mushroomId) external view returns (bool);
function getBreedingFee(uint256 parent1Id, uint256 parent2Id) external view returns (uint256);

// Genetics
function getGenetics(uint256 mushroomId) external view returns (Genetics memory);
function getRarity(uint256 mushroomId) external view returns (uint8);

// Harvesting
function harvest(uint256 mushroomId) external returns (uint256 dmReward);
function isMatured(uint256 mushroomId) external view returns (bool);

// Marketplace
function listForSale(uint256 mushroomId, uint256 price) external;
function buy(uint256 mushroomId) external payable;
function cancelListing(uint256 mushroomId) external;

Example Usage:

const shroom = new ethers.Contract(SHROOM_ADDRESS, SHROOM_ABI, signer);
const dm = new ethers.Contract(DM_ADDRESS, DM_ABI, signer);

// Check if mushrooms can breed
const canBreed1 = await shroom.canBreed(1);
const canBreed2 = await shroom.canBreed(2);

if (canBreed1 && canBreed2) {
// Get breeding fee
const fee = await shroom.getBreedingFee(1, 2);

// Approve DM spending
await dm.approve(SHROOM_ADDRESS, fee);

// Breed mushrooms
const tx = await shroom.breed(1, 2);
const receipt = await tx.wait();

// Get offspring ID
const event = receipt.events.find(e => e.event === 'Bred');
const offspringId = event.args.offspringId;
console.log(`New mushroom #${offspringId} born!`);
}

DAO Governance​

Key Functions:

// Proposals
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) external returns (uint256 proposalId);

function getProposal(uint256 proposalId) external view returns (Proposal memory);
function getProposalState(uint256 proposalId) external view returns (ProposalState);

// Voting
function castVote(uint256 proposalId, uint8 support) external;
function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external;

// Execution
function queue(uint256 proposalId) external;
function execute(uint256 proposalId) external;

// Parameters
function votingDelay() external view returns (uint256);
function votingPeriod() external view returns (uint256);
function proposalThreshold() external view returns (uint256);
function quorum(uint256 blockNumber) external view returns (uint256);

Example Usage:

const governance = new ethers.Contract(GOVERNANCE_ADDRESS, GOVERNANCE_ABI, signer);

// Create proposal
const targets = [TREASURY_ADDRESS];
const values = [0];
const calldatas = [
treasury.interface.encodeFunctionData("transfer", [
recipientAddress,
ethers.utils.parseEther("1000") // 1000 PSILO
])
];
const description = "Grant 1000 PSILO to developer";

const proposalId = await governance.propose(targets, values, calldatas, description);

// Vote on proposal
await governance.castVoteWithReason(proposalId, 1, "Great work!"); // 1 = For

// Check proposal state
const state = await governance.getProposalState(proposalId);
// 0 = Pending, 1 = Active, 2 = Canceled, 3 = Defeated, 4 = Succeeded, 5 = Queued, 6 = Expired, 7 = Executed

🔐 Security Considerations​

Best Practices​

When Interacting with Contracts:

  1. Verify Contract Addresses - Always double-check addresses
  2. Check Allowances - Review token approvals before signing
  3. Use Slippage Protection - Set reasonable slippage limits
  4. Set Deadlines - Use short deadlines for time-sensitive transactions
  5. Test on Testnet - Try on Sepolia before mainnet
  6. Read Events - Check transaction receipts for events
  7. Handle Errors - Implement proper error handling

Example Error Handling:

try {
const tx = await altar.makeOffering(burnAmount, intention, { value: donation });
await tx.wait();
console.log("Offering successful!");
} catch (error) {
if (error.code === 'INSUFFICIENT_FUNDS') {
console.error("Not enough ETH for gas");
} else if (error.message.includes("ERC20: insufficient allowance")) {
console.error("Need to approve ETHO spending first");
} else {
console.error("Transaction failed:", error.message);
}
}

Common Pitfalls​

⚠️ Avoid these mistakes:

  1. Not approving tokens - Must approve before spending
  2. Insufficient gas - Set appropriate gas limits
  3. Expired deadlines - Use future timestamps
  4. Wrong network - Ensure correct chain (mainnet vs testnet)
  5. Hardcoded addresses - Use environment variables
  6. Ignoring events - Events contain important data
  7. No error handling - Always catch errors

📚 Additional Resources​

Documentation​

Tools​

Support​

"Code is law, but compassion is the constitution. Build with care, test thoroughly, and always prioritize user safety." 🍄✨