Description:
Smart contract deployed on Ethereum with Factory, Oracle features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
/**
* @title AggregatorV3Interface
* @notice Chainlink Price Feed Interface
*/
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
/**
* @title CMTDE Token Contract - Minimal Working Version
* @dev Simplified version that will deploy successfully
*/
contract CMTDE {
// State variables
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
uint256 private _goldReserves;
address public owner;
bool public paused = false;
// Security parameters - FIXED BOUNDS
uint256 public constant MAX_MINT_PER_TX = 1000000 * 10**18; // 1M tokens max per tx
uint256 public constant MAX_DAILY_MINT = 10000000 * 10**18; // 10M tokens per day
uint256 public constant PRICE_STALENESS_THRESHOLD = 3600; // 1 hour
uint256 public constant MIN_GOLD_PRICE = 50 * 10**8; // $50 minimum (very safe)
uint256 public constant MAX_GOLD_PRICE = 10000 * 10**8; // $10000 maximum
// Purchase parameters
uint256 public constant MAX_PURCHASE_PER_TX = 500000 * 10**18; // 500K tokens max per purchase
uint256 public constant MAX_DAILY_PURCHASE = 5000000 * 10**18; // 5M tokens per day
uint256 public constant MIN_PURCHASE_ETH = 0.001 ether; // Minimum 0.001 ETH purchase
uint256 public constant MAX_PURCHASE_ETH = 100 ether; // Maximum 100 ETH purchase
uint256 public dailyMintAmount;
uint256 public lastMintResetTime;
uint256 public dailyPurchaseAmount;
uint256 public lastPurchaseResetTime;
// Purchase settings
bool public purchaseEnabled = true;
uint256 public priceMarkup = 105; // 5% markup over gold price (105/100 = 1.05)
// Oracle setup
AggregatorV3Interface internal goldPriceFeed;
AggregatorV3Interface internal backupPriceFeed;
uint256 private constant PRICE_DECIMALS = 8;
uint256 private constant TOKEN_DECIMALS = 18;
// Token metadata
string private _name = "CMTDE Token";
string private _symbol = "CMTDE";
uint8 private _decimals = 18;
// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Mint(address indexed to, uint256 value);
event Burn(address indexed from, uint256 value);
event Paused();
event Unpaused();
event PriceFeedUpdated(address newPriceFeed);
event BackupPriceFeedSet(address backupFeed);
event EmergencyWithdraw(uint256 amount);
event GoldReserveAudited(uint256 reserves, address auditor);
event TokensPurchased(address indexed buyer, uint256 ethAmount, uint256 tokenAmount, uint256 tokenPrice);
event PurchaseSettingsUpdated(bool enabled, uint256 markup);
event ETHWithdrawn(address indexed to, uint256 amount);
// Modifiers
modifier onlyOwner() {
require(msg.sender == owner, "Only owner");
_;
}
modifier whenNotPaused() {
require(!paused, "Contract is paused");
_;
}
modifier validAddress(address addr) {
require(addr != address(0), "Invalid address");
_;
}
modifier whenPurchaseEnabled() {
require(purchaseEnabled, "Token purchases are disabled");
_;
}
// SIMPLIFIED CONSTRUCTOR - NO PRICE VALIDATION
constructor(address _goldPriceFeed, address _backupPriceFeed) {
owner = msg.sender;
goldPriceFeed = AggregatorV3Interface(_goldPriceFeed);
backupPriceFeed = AggregatorV3Interface(_backupPriceFeed);
lastMintResetTime = block.timestamp;
lastPurchaseResetTime = block.timestamp;
// SAFE Initial Supply - 20 Billion tokens with safe calculation
uint256 initialSupply = 20 * 1000000000 * 10**18; // 20B tokens - safe calculation
_totalSupply = initialSupply;
_balances[owner] = _totalSupply;
emit Transfer(address(0), owner, _totalSupply);
}
// Enhanced Oracle Functions with Security Checks
function getLatestGoldPrice() public view returns (uint256) {
return _getValidatedPrice(goldPriceFeed);
}
function _getValidatedPrice(AggregatorV3Interface priceFeed) internal view returns (uint256) {
(, int price, , uint256 timeStamp, ) = priceFeed.latestRoundData();
// Comprehensive validation
require(timeStamp > 0, "Round not complete");
require(block.timestamp - timeStamp <= PRICE_STALENESS_THRESHOLD, "Price data too old");
require(price > 0, "Invalid price");
uint256 uPrice = uint256(price);
require(uPrice >= MIN_GOLD_PRICE && uPrice <= MAX_GOLD_PRICE, "Price out of bounds");
return uPrice;
}
function getGoldPriceWithFallback() public view returns (uint256) {
try this.getLatestGoldPrice() returns (uint256 price) {
return price;
} catch {
// Fallback to backup price feed
return _getValidatedPrice(backupPriceFeed);
}
}
function getTokenPurchasePrice() public view returns (uint256) {
uint256 goldPrice = getGoldPriceWithFallback();
uint256 basePrice = (goldPrice + 50) / 100; // +50 for rounding
return (basePrice * priceMarkup) / 100; // Apply markup
}
function getCurrentTokenValue() public view returns (uint256) {
uint256 goldPrice = getGoldPriceWithFallback();
// Use safer division with rounding
return (goldPrice + 50) / 100; // +50 for rounding
}
// Secure Minting with Rate Limits
function secureMint(address to, uint256 amount) public onlyOwner validAddress(to) whenNotPaused {
require(amount > 0 && amount <= MAX_MINT_PER_TX, "Invalid mint amount");
// Reset daily counter if needed
if (block.timestamp - lastMintResetTime >= 86400) {
dailyMintAmount = 0;
lastMintResetTime = block.timestamp;
}
require(dailyMintAmount + amount <= MAX_DAILY_MINT, "Daily mint limit exceeded");
_balances[to] += amount;
_totalSupply += amount;
dailyMintAmount += amount;
emit Mint(to, amount);
emit Transfer(address(0), to, amount);
}
// Token Purchase Functions
function buyTokens() public payable whenNotPaused whenPurchaseEnabled {
require(msg.value >= MIN_PURCHASE_ETH && msg.value <= MAX_PURCHASE_ETH, "Invalid ETH amount");
// Reset daily counter if needed
if (block.timestamp - lastPurchaseResetTime >= 86400) {
dailyPurchaseAmount = 0;
lastPurchaseResetTime = block.timestamp;
}
uint256 tokenPrice = getTokenPurchasePrice();
require(tokenPrice > 0, "Invalid token price");
// Calculate tokens to be purchased (ETH has 18 decimals, price has 8 decimals from Chainlink)
uint256 tokensAmount = (msg.value * 10**PRICE_DECIMALS) / tokenPrice;
require(tokensAmount > 0, "Token amount too small");
require(tokensAmount <= MAX_PURCHASE_PER_TX, "Exceeds max purchase per transaction");
require(dailyPurchaseAmount + tokensAmount <= MAX_DAILY_PURCHASE, "Exceeds daily purchase limit");
// Update daily purchase tracking
dailyPurchaseAmount += tokensAmount;
// Mint tokens to buyer
_balances[msg.sender] += tokensAmount;
_totalSupply += tokensAmount;
emit TokensPurchased(msg.sender, msg.value, tokensAmount, tokenPrice);
emit Transfer(address(0), msg.sender, tokensAmount);
}
// Emergency Functions
function pause() public onlyOwner {
paused = true;
emit Paused();
}
function unpause() public onlyOwner {
paused = false;
emit Unpaused();
}
function emergencyWithdraw() public onlyOwner {
uint256 balance = address(this).balance;
payable(owner).transfer(balance);
emit EmergencyWithdraw(balance);
}
// ETH Management Functions
function withdrawETH(uint256 amount) public onlyOwner {
require(amount <= address(this).balance, "Insufficient contract balance");
payable(owner).transfer(amount);
emit ETHWithdrawn(owner, amount);
}
function withdrawAllETH() public onlyOwner {
uint256 balance = address(this).balance;
require(balance > 0, "No ETH to withdraw");
payable(owner).transfer(balance);
emit ETHWithdrawn(owner, balance);
}
function getETHBalance() public view returns (uint256) {
return address(this).balance;
}
// Purchase Settings Management
function setPurchaseEnabled(bool _enabled) public onlyOwner {
purchaseEnabled = _enabled;
emit PurchaseSettingsUpdated(_enabled, priceMarkup);
}
function setPriceMarkup(uint256 _markup) public onlyOwner {
require(_markup >= 100 && _markup <= 200, "Markup must be between 100-200% (100-200)");
priceMarkup = _markup;
emit PurchaseSettingsUpdated(purchaseEnabled, _markup);
}
// Secure Reserve Management
function auditGoldReserves(uint256 auditedAmount) public onlyOwner {
_goldReserves = auditedAmount;
emit GoldReserveAudited(auditedAmount, msg.sender);
}
// Price Feed Management
function setBackupPriceFeed(address newBackupFeed) public onlyOwner validAddress(newBackupFeed) {
backupPriceFeed = AggregatorV3Interface(newBackupFeed);
emit BackupPriceFeedSet(newBackupFeed);
}
// Standard ERC20 Functions
function name() public view returns (string memory) { return _name; }
function symbol() public view returns (string memory) { return _symbol; }
function decimals() public view returns (uint8) { return _decimals; }
function totalSupply() public view returns (uint256) { return _totalSupply; }
function balanceOf(address account) public view returns (uint256) { return _balances[account]; }
function goldReserves() public view returns (uint256) { return _goldReserves; }
function transfer(address to, uint256 amount) public validAddress(to) whenNotPaused returns (bool) {
require(_balances[msg.sender] >= amount, "Insufficient balance");
_balances[msg.sender] -= amount;
_balances[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
}
Submitted on: 2025-09-26 11:15:33
Comments
Log in to comment.
No comments yet.