Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// @title Silver Pure Reserve (SLVX)
/// @notice Token ERC20 representando 1 onza troy de plata pura (999), con supply inicial de 6 mil millones.
/// Incluye freeze, burn, mint, transfer ownership en 2 pasos, nonReentrancy, EIP-2612 permit.
contract SilverPureReserve {
string public constant name = "Silver Pure Reserve";
string public constant symbol = "SLVX";
uint8 public constant decimals = 18;
uint256 public totalSupply;
uint256 public constant INITIAL_SUPPLY = 6_000_000_000 * 1e18;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
mapping(address => bool) public frozen;
address public owner;
address public pendingOwner;
address public compliance;
uint256 private _entered;
// EIP-2612 permit
mapping(address => uint256) public nonces;
bytes32 public DOMAIN_SEPARATOR;
bytes32 public constant PERMIT_TYPEHASH = keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
);
// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event ComplianceTransferred(address indexed previousCompliance, address indexed newCompliance);
event AddressFrozen(address indexed account, bool frozen);
event Mint(address indexed to, uint256 amount);
event Burn(address indexed from, uint256 amount);
// Modifiers
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
modifier onlyCompliance() {
require(msg.sender == compliance, "Not compliance");
_;
}
modifier notFrozen(address account) {
require(!frozen[account], "Address frozen");
_;
}
modifier nonReentrant() {
require(_entered == 0, "ReentrancyGuard: reentrant call");
_entered = 1;
_;
_entered = 0;
}
constructor() {
owner = msg.sender;
compliance = msg.sender;
totalSupply = INITIAL_SUPPLY;
balanceOf[msg.sender] = INITIAL_SUPPLY;
emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
uint256 chainId;
assembly {
chainId := chainid()
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes("1")),
chainId,
address(this)
)
);
}
// ===== ERC-20 Standard =====
function transfer(address to, uint256 value) external notFrozen(msg.sender) notFrozen(to) returns (bool) {
require(to != address(0), "Zero address");
require(balanceOf[msg.sender] >= value, "Insufficient balance");
unchecked {
balanceOf[msg.sender] -= value;
balanceOf[to] += value;
}
emit Transfer(msg.sender, to, value);
return true;
}
function approve(address spender, uint256 value) external notFrozen(msg.sender) notFrozen(spender) returns (bool) {
require(spender != address(0), "Zero address");
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value)
external
notFrozen(msg.sender)
notFrozen(from)
notFrozen(to)
nonReentrant
returns (bool)
{
require(to != address(0), "Zero address");
require(balanceOf[from] >= value, "Insufficient balance");
require(allowance[from][msg.sender] >= value, "Allowance exceeded");
unchecked {
allowance[from][msg.sender] -= value;
balanceOf[from] -= value;
balanceOf[to] += value;
}
emit Transfer(from, to, value);
return true;
}
function increaseAllowance(address spender, uint256 addedValue)
external
notFrozen(msg.sender)
notFrozen(spender)
returns (bool)
{
require(spender != address(0), "Zero address");
allowance[msg.sender][spender] += addedValue;
emit Approval(msg.sender, spender, allowance[msg.sender][spender]);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue)
external
notFrozen(msg.sender)
notFrozen(spender)
returns (bool)
{
require(spender != address(0), "Zero address");
uint256 current = allowance[msg.sender][spender];
allowance[msg.sender][spender] = subtractedValue >= current ? 0 : current - subtractedValue;
emit Approval(msg.sender, spender, allowance[msg.sender][spender]);
return true;
}
// ===== Mint / Burn =====
function mint(address to, uint256 amount) external onlyOwner nonReentrant {
require(to != address(0), "Zero address");
totalSupply += amount;
balanceOf[to] += amount;
emit Mint(to, amount);
emit Transfer(address(0), to, amount);
}
function burn(address from, uint256 amount) external onlyOwner nonReentrant {
require(from != address(0), "Zero address");
require(balanceOf[from] >= amount, "Insufficient balance");
unchecked {
balanceOf[from] -= amount;
totalSupply -= amount;
}
emit Burn(from, amount);
emit Transfer(from, address(0), amount);
}
function burnFrom(address from, uint256 amount) external notFrozen(msg.sender) notFrozen(from) nonReentrant {
require(from != address(0), "Zero address");
require(balanceOf[from] >= amount, "Insufficient balance");
require(allowance[from][msg.sender] >= amount, "Allowance exceeded");
unchecked {
allowance[from][msg.sender] -= amount;
balanceOf[from] -= amount;
totalSupply -= amount;
}
emit Burn(from, amount);
emit Transfer(from, address(0), amount);
}
// ===== Freeze Accounts =====
function setFrozen(address account, bool isFrozen) external onlyCompliance {
frozen[account] = isFrozen;
emit AddressFrozen(account, isFrozen);
}
// ===== Ownership Control =====
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "Zero address");
pendingOwner = newOwner;
emit OwnershipTransferStarted(owner, newOwner);
}
function acceptOwnership() external {
require(msg.sender == pendingOwner, "Not pending owner");
emit OwnershipTransferred(owner, pendingOwner);
owner = pendingOwner;
pendingOwner = address(0);
}
function setCompliance(address newCompliance) external onlyOwner {
require(newCompliance != address(0), "Zero address");
emit ComplianceTransferred(compliance, newCompliance);
compliance = newCompliance;
}
// ===== EIP-2612 Permit =====
function permit(
address owner_,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
require(deadline >= block.timestamp, "Permit expired");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(
PERMIT_TYPEHASH,
owner_,
spender,
value,
nonces[owner_]++,
deadline
))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress == owner_, "Invalid signature");
allowance[owner_][spender] = value;
emit Approval(owner_, spender, value);
}
}
Submitted on: 2025-10-23 17:09:17
Comments
Log in to comment.
No comments yet.