// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract FractalBitcoinRunes { address public owner; uint256 public totalSupply; struct Rune { string symbol; address runeOwner; uint256 value; uint256 timestamp; bool active; } mapping(string => Rune) public runes; uint256 public totalActiveRunes; event RuneAssigned(string indexed symbol, address indexed runeOwner, uint256 value); event RuneTransferred(string indexed symbol, address indexed oldOwner, address indexed newOwner); event RuneBurned(string indexed symbol, uint256 redistributedValue); modifier onlyOwner() { require(msg.sender == owner, "Not the owner"); _; } constructor() { owner = msg.sender; totalSupply = 1000000 * 1 ether; // Initial supply totalActiveRunes = 0; } // Assign a rune symbol to a user with initial value function assignRune(string memory _symbol, uint256 _value) public onlyOwner { require(runes[_symbol].runeOwner == address(0), "Symbol already taken"); runes[_symbol] = Rune({ symbol: _symbol, runeOwner: msg.sender, value: _value, timestamp: block.timestamp, active: true }); totalActiveRunes += 1; emit RuneAssigned(_symbol, msg.sender, _value); } // Transfer rune ownership function transferRune(string memory _symbol, address _newOwner) public { require(runes[_symbol].runeOwner == msg.sender, "Not the rune owner"); runes[_symbol].runeOwner = _newOwner; emit RuneTransferred(_symbol, msg.sender, _newOwner); } // Burn a rune and redistribute its value to remaining active runes function burnRune(string memory _symbol) public { require(runes[_symbol].runeOwner == msg.sender, "Not the rune owner"); require(runes[_symbol].active, "Rune is not active"); uint256 valueToRedistribute = runes[_symbol].value; runes[_symbol].active = false; totalActiveRunes -= 1; uint256 valuePerRune = valueToRedistribute / totalActiveRunes; for (string memory runeSymbol: getActiveRunes()) { runes[runeSymbol].value += valuePerRune; } emit RuneBurned(_symbol, valueToRedistribute); } // Get list of active runes function getActiveRunes() internal view returns (string[] memory) { string[] memory activeRunes = new string[](totalActiveRunes); uint256 index = 0; for (uint256 i = 0; i < totalSupply; i++) { if (runes[i].active) { activeRunes[index] = runes[i].symbol; index++; } } return activeRunes; } // Check rune value function getRuneValue(string memory _symbol) public view returns (uint256) { return runes[_symbol].value; } // Check rune owner function getRuneOwner(string memory _symbol) public view returns (address) { return runes[_symbol].runeOwner; } }