账户
0x7e...d7ea
0x7E...D7Ea

0x7E...D7Ea

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.28+commit.7893614a
语言
Solidity
合同源代码
文件 1 的 1:ADRIANToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/* ===== Library: ECDSA (versión mínima) ===== */
library ECDSA {
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        if (signature.length != 65) revert("ECDSA: longitud invalida");
        bytes32 r;
        bytes32 s;
        uint8 v;
        assembly {
            r := mload(add(signature, 32))
            s := mload(add(signature, 64))
            v := byte(0, mload(add(signature, 96)))
        }
        require(uint256(s) <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "ECDSA: valor s invalido");
        require(v == 27 || v == 28, "ECDSA: valor v invalido");
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: firma invalida");
        return signer;
    }
}

/* ===== Contract: Context ===== */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

/* ===== Contract: Ownable ===== */
abstract contract Ownable is Context {
    address private _owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    constructor() {
        _transferOwnership(_msgSender());
    }
    
    function owner() public view virtual returns (address) {
        return _owner;
    }
    
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not owner");
        _;
    }
    
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }
    
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is zero address");
        _transferOwnership(newOwner);
    }
    
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

/* ===== Contract: ERC20 (versión mínima) ===== */
contract ERC20 is Context {
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    
    uint256 private _totalSupply;
    string private _name;
    string private _symbol;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    
    constructor(string memory name_, string memory symbol_) {
        _name   = name_;
        _symbol = symbol_;
    }
    
    function name() public view returns (string memory) { 
        return _name; 
    }
    
    function symbol() public view returns (string memory) { 
        return _symbol; 
    }
    
    function decimals() public pure returns (uint8) { 
        return 18; 
    }
    
    function totalSupply() public view returns (uint256) { 
        return _totalSupply; 
    }
    
    function balanceOf(address account) public view returns (uint256) { 
        return _balances[account]; 
    }
    
    function transfer(address to, uint256 amount) public virtual returns (bool) {
        _transfer(_msgSender(), to, amount);
        return true;
    }
    
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }
    
    function approve(address spender, uint256 amount) public virtual returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }
    
    function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[from][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _transfer(from, to, amount);
        _approve(from, _msgSender(), currentAllowance - amount);
        return true;
    }
    
    function _transfer(address from, address to, uint256 amount) internal virtual {
        require(from != address(0), "ERC20: transfer from zero address");
        require(to != address(0), "ERC20: transfer to zero address");
        _beforeTokenTransfer(from, to, amount);
        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;
        emit Transfer(from, to, amount);
    }
    
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to zero address");
        _beforeTokenTransfer(address(0), account, amount);
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }
    
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from zero address");
        _beforeTokenTransfer(account, address(0), amount);
        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;
        emit Transfer(account, address(0), amount);
    }
    
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from zero address");
        require(spender != address(0), "ERC20: approve to zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
    
    // Hook que se llama antes de cualquier transferencia, mint o burn.
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

/* ===== Contract: EIP712 ===== */
abstract contract EIP712 {
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;
    
    constructor(string memory name, string memory version) {
        _HASHED_NAME    = keccak256(bytes(name));
        _HASHED_VERSION = keccak256(bytes(version));
        _TYPE_HASH      = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
    }
    
    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }
    
    function _domainSeparatorV4() internal view returns (bytes32) {
        return block.chainid == _CACHED_CHAIN_ID ? _CACHED_DOMAIN_SEPARATOR : _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
    }
    
    function _hashTypedDataV4(bytes32 structHash) internal view returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash));
    }
}

/* ===== Contract: ERC20Permit ===== */
abstract contract ERC20Permit is ERC20, EIP712 {
    mapping(address => uint256) public nonces;
    // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
    bytes32 public constant PERMIT_TYPEHASH = 0x6a761202d1a982bec02486d3d0f4394af28b31a1a1f7dfaa680c15c02d7c5f8c;
    
    constructor(string memory name) EIP712(name, "1") { }
    
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(block.timestamp <= deadline, "ERC20Permit: deadline expirada");
        bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline));
        bytes32 hash = _hashTypedDataV4(structHash);
        address signer = ECDSA.recover(hash, abi.encodePacked(r, s, v));
        require(signer == owner, "ERC20Permit: firma invalida");
        _approve(owner, spender, value);
    }
}

/* ===== Contract: ERC20Snapshot (versión básica) ===== */
abstract contract ERC20Snapshot is ERC20 {
    struct Snapshot {
        uint256 id;
        uint256 value;
    }
    
    mapping(address => Snapshot[]) private _accountSnapshots;
    Snapshot[] private _totalSupplySnapshots;
    uint256 internal _currentSnapshotId;
    
    event SnapshotCreated(uint256 id);
    
    // Cambiado a "public" para permitir llamadas internas con super.snapshot()
    function snapshot() public virtual returns (uint256) {
        _currentSnapshotId++;
        _updateTotalSupplySnapshot();
        emit SnapshotCreated(_currentSnapshotId);
        return _currentSnapshotId;
    }
    
    function balanceOfAt(address account, uint256 snapshotId) external view returns (uint256) {
        return _valueAt(snapshotId, _accountSnapshots[account]);
    }
    
    function totalSupplyAt(uint256 snapshotId) external view returns (uint256) {
        return _valueAt(snapshotId, _totalSupplySnapshots);
    }
    
    function _valueAt(uint256 snapshotId, Snapshot[] storage snapshots) private view returns (uint256) {
        uint256 len = snapshots.length;
        if (len == 0) return 0;
        uint256 lower = 0;
        uint256 upper = len;
        while (lower < upper) {
            uint256 mid = (lower + upper) / 2;
            if (snapshots[mid].id <= snapshotId) {
                lower = mid + 1;
            } else {
                upper = mid;
            }
        }
        if (lower == 0) return 0;
        else return snapshots[lower - 1].value;
    }
    
    function _updateAccountSnapshot(address account, uint256 newBalance) internal {
        Snapshot[] storage snapshots = _accountSnapshots[account];
        uint256 len = snapshots.length;
        if (len == 0 || snapshots[len - 1].id < _currentSnapshotId) {
            snapshots.push(Snapshot(_currentSnapshotId, newBalance));
        } else {
            snapshots[len - 1].value = newBalance;
        }
    }
    
    function _updateTotalSupplySnapshot() internal {
        uint256 newTotalSupply = totalSupply();
        uint256 len = _totalSupplySnapshots.length;
        if (len == 0 || _totalSupplySnapshots[len - 1].id < _currentSnapshotId) {
            _totalSupplySnapshots.push(Snapshot(_currentSnapshotId, newTotalSupply));
        } else {
            _totalSupplySnapshots[len - 1].value = newTotalSupply;
        }
    }
    
    // Hook llamado en cada transferencia, mint o burn.
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);
        if (from == address(0)) {
            // mint
            _updateTotalSupplySnapshot();
            if (to != address(0)) {
                _updateAccountSnapshot(to, balanceOf(to) + amount);
            }
        } else if (to == address(0)) {
            // burn
            _updateAccountSnapshot(from, balanceOf(from) - amount);
            _updateTotalSupplySnapshot();
        } else {
            if (from != address(0)) {
                _updateAccountSnapshot(from, balanceOf(from) - amount);
            }
            if (to != address(0)) {
                _updateAccountSnapshot(to, balanceOf(to) + amount);
            }
        }
    }
}

/* ===== Contract: ADRIANToken ===== */
contract ADRIANToken is ERC20Snapshot, ERC20Permit, Ownable {
    // Constant para basis points (10,000 = 100%)
    uint256 public constant BASIS_POINTS = 10000;

    // Fees en basis points
    uint256 public taxFee;     // Ej: 50 equivale a 0.5%
    uint256 public creatorFee; // Ej: 50 equivale a 0.5%
    uint256 public burnFee;    // Ej: 50 equivale a 0.5%

    // Direcciones para recibir fees
    address public taxAddress;
    address public creatorAddress;
    
    // Mapping para exención de fees
    mapping(address => bool) public isFeeExempt;
    
    // Variables para staking
    mapping(address => uint256) public stakedBalance;
    mapping(address => uint256) public stakingStart;
    uint256 public rewardRate; // tasa de recompensa por segundo (escala 1e18)
    
    event TaxFeeUpdated(uint256 newTaxFee);
    event CreatorFeeUpdated(uint256 newCreatorFee);
    event BurnFeeUpdated(uint256 newBurnFee);
    event TaxAddressUpdated(address newTaxAddress);
    event CreatorAddressUpdated(address newCreatorAddress);
    event FeeExemptionUpdated(address indexed account, bool isExempt);
    event Staked(address indexed staker, uint256 amount);
    event WithdrawnStake(address indexed staker, uint256 amount, uint256 reward);
    event RewardRateUpdated(uint256 newRewardRate);
    event GalleryAction(address indexed from, address indexed to, uint256 amount, string action);
    
    constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply,
        uint256 _taxFee,      // En basis points (ej. 50 para 0.5%)
        uint256 _creatorFee,  // En basis points
        uint256 _burnFee,     // En basis points
        address _taxAddress,
        address _creatorAddress,
        uint256 _rewardRate   // Ej: 1e16 equivale a 0.01 por segundo
    )
        ERC20(name, symbol)
        ERC20Permit(name)
    {
        require(initialSupply > 0, "Initial supply > 0");
        // La suma de fees no debe exceder BASIS_POINTS (100%)
        require(_taxFee + _creatorFee + _burnFee <= BASIS_POINTS, "Suma de fees > 100%");
        
        taxFee = _taxFee;
        creatorFee = _creatorFee;
        burnFee = _burnFee;
        taxAddress = _taxAddress;
        creatorAddress = _creatorAddress;
        rewardRate = _rewardRate;
        
        // Eximir de fees: owner, taxAddress, creatorAddress y el contrato (para staking interno)
        isFeeExempt[_msgSender()] = true;
        isFeeExempt[_taxAddress] = true;
        isFeeExempt[_creatorAddress] = true;
        isFeeExempt[address(this)] = true;
        
        _mint(_msgSender(), initialSupply);
    }
    
    // Override de _transfer para aplicar fees: TAX, CREATOR y BURN
    function _transfer(address sender, address recipient, uint256 amount) internal virtual override {
        uint256 feeTotal = 0;
        uint256 taxAmount = 0;
        uint256 creatorAmount = 0;
        uint256 burnAmount = 0;
        
        if (!isFeeExempt[sender]) {
            if (taxFee > 0) {
                taxAmount = (amount * taxFee) / BASIS_POINTS;
                super._transfer(sender, taxAddress, taxAmount);
                feeTotal += taxAmount;
            }
            if (creatorFee > 0) {
                creatorAmount = (amount * creatorFee) / BASIS_POINTS;
                super._transfer(sender, creatorAddress, creatorAmount);
                feeTotal += creatorAmount;
            }
            if (burnFee > 0) {
                burnAmount = (amount * burnFee) / BASIS_POINTS;
                _burn(sender, burnAmount);
                feeTotal += burnAmount;
            }
        }
        super._transfer(sender, recipient, amount - feeTotal);
    }
    
    // Funciones para actualizar fees y direcciones
    function updateTaxFee(uint256 _newTaxFee) external onlyOwner {
        require(_newTaxFee + creatorFee + burnFee <= BASIS_POINTS, "Suma de fees > 100%");
        taxFee = _newTaxFee;
        emit TaxFeeUpdated(_newTaxFee);
    }
    
    function updateCreatorFee(uint256 _newCreatorFee) external onlyOwner {
        require(taxFee + _newCreatorFee + burnFee <= BASIS_POINTS, "Suma de fees > 100%");
        creatorFee = _newCreatorFee;
        emit CreatorFeeUpdated(_newCreatorFee);
    }
    
    function updateBurnFee(uint256 _newBurnFee) external onlyOwner {
        require(taxFee + creatorFee + _newBurnFee <= BASIS_POINTS, "Suma de fees > 100%");
        burnFee = _newBurnFee;
        emit BurnFeeUpdated(_newBurnFee);
    }
    
    function updateTaxAddress(address _newTaxAddress) external onlyOwner {
        taxAddress = _newTaxAddress;
        isFeeExempt[_newTaxAddress] = true;
        emit TaxAddressUpdated(_newTaxAddress);
    }
    
    function updateCreatorAddress(address _newCreatorAddress) external onlyOwner {
        creatorAddress = _newCreatorAddress;
        isFeeExempt[_newCreatorAddress] = true;
        emit CreatorAddressUpdated(_newCreatorAddress);
    }
    
    function setFeeExemption(address account, bool exempt) external onlyOwner {
        isFeeExempt[account] = exempt;
        emit FeeExemptionUpdated(account, exempt);
    }
    
    // Función snapshot protegida por onlyOwner
    function snapshot() public override onlyOwner returns (uint256) {
        return super.snapshot();
    }
    
    // Funciones de staking
    
    // Permite al usuario bloquear (stake) tokens. Se transfieren al contrato (sin fees por exención)
    function stake(uint256 amount) external {
        require(amount > 0, "Stake amount must be > 0");
        super._transfer(_msgSender(), address(this), amount);
        stakedBalance[_msgSender()] += amount;
        if (stakingStart[_msgSender()] == 0) {
            stakingStart[_msgSender()] = block.timestamp;
        }
        emit Staked(_msgSender(), amount);
    }
    
    // Calcula la recompensa acumulada para un staker en función del tiempo transcurrido
    function calculateReward(address staker) public view returns (uint256) {
        uint256 timeElapsed = block.timestamp - stakingStart[staker];
        return (stakedBalance[staker] * rewardRate * timeElapsed) / 1e18;
    }
    
    // Permite retirar el stake y reclamar la recompensa acumulada
    function withdrawStake() external {
        uint256 staked = stakedBalance[_msgSender()];
        require(staked > 0, "No staked tokens");
        uint256 reward = calculateReward(_msgSender());
        stakedBalance[_msgSender()] = 0;
        stakingStart[_msgSender()] = 0;
        super._transfer(address(this), _msgSender(), staked + reward);
        emit WithdrawnStake(_msgSender(), staked, reward);
    }
    
    // Permite actualizar la tasa de recompensa
    function updateRewardRate(uint256 _newRewardRate) external onlyOwner {
        rewardRate = _newRewardRate;
        emit RewardRateUpdated(_newRewardRate);
    }
    
    // Función extra para futuras integraciones (por ejemplo, ADRIAN GALLERY)
    function galleryAction(string calldata actionDescription) external {
        emit GalleryAction(_msgSender(), address(0), 0, actionDescription);
    }
    
    // Override de _beforeTokenTransfer para integrar la lógica de snapshot
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Snapshot) {
        ERC20Snapshot._beforeTokenTransfer(from, to, amount);
    }
}
设置
{
  "compilationTarget": {
    "ADRIANToken.sol": "ADRIANToken"
  },
  "evmVersion": "cancun",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"uint256","name":"_taxFee","type":"uint256"},{"internalType":"uint256","name":"_creatorFee","type":"uint256"},{"internalType":"uint256","name":"_burnFee","type":"uint256"},{"internalType":"address","name":"_taxAddress","type":"address"},{"internalType":"address","name":"_creatorAddress","type":"address"},{"internalType":"uint256","name":"_rewardRate","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newBurnFee","type":"uint256"}],"name":"BurnFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newCreatorAddress","type":"address"}],"name":"CreatorAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCreatorFee","type":"uint256"}],"name":"CreatorFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExempt","type":"bool"}],"name":"FeeExemptionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"action","type":"string"}],"name":"GalleryAction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRewardRate","type":"uint256"}],"name":"RewardRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"SnapshotCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newTaxAddress","type":"address"}],"name":"TaxAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTaxFee","type":"uint256"}],"name":"TaxFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"WithdrawnStake","type":"event"},{"inputs":[],"name":"BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"calculateReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creatorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creatorFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"actionDescription","type":"string"}],"name":"galleryAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isFeeExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"exempt","type":"bool"}],"name":"setFeeExemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newBurnFee","type":"uint256"}],"name":"updateBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCreatorAddress","type":"address"}],"name":"updateCreatorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCreatorFee","type":"uint256"}],"name":"updateCreatorFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRewardRate","type":"uint256"}],"name":"updateRewardRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTaxAddress","type":"address"}],"name":"updateTaxAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTaxFee","type":"uint256"}],"name":"updateTaxFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"}]