// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
/// @title Звёздный поток изобилия (Starflow of Abundance, SFA) v2.0
/// @dev Расширенный ERC20-токен с механизмами управления и безопасности
contract StarflowOfAbundanceV2 is ERC20, Ownable, Pausable {
using SafeMath for uint256;
uint256 public constant MAX_SUPPLY = 1_000_000_000 * 10**18; // 1 млрд токенов
uint8 private _decimals = 18;
// Адреса, исключённые из комиссий
mapping(address => bool) public exemptFromFees;
// Процент комиссии за транзакции (в базисных пунктах, 100 = 1%)
uint16 public feeRate = 500; // 5%
/// @dev Конструктор: задаёт имя, символ и первоначальную эмиссию
constructor() ERC20("Starflow of Abundance", "SFA") {
_mint(msg.sender, MAX_SUPPLY);
exemptFromFees[msg.sender] = true;
}
/// @dev Возвращает количество десятичных знаков
function decimals() public view override returns (uint8) {
return _decimals;
}
/// @dev Устанавливает ставку комиссии (только владелец)
function setFeeRate(uint16 newRate) public onlyOwner {
require(newRate <= 10000, "Fee rate cannot exceed 100%");
feeRate = newRate;
}
/// @dev Добавляет/удаляет адреса из списка без комиссии
function setExemptFromFees(address account, bool exempt) public onlyOwner {
exemptFromFees[account] = exempt;
}
/// @dev Переводит токены с комиссией
function transfer(address recipient, uint256 amount) public override whenNotPaused returns (bool) {
uint256 fee = 0;
if (!exemptFromFees[msg.sender]) {
fee = amount.mul(feeRate).div(10000);
amount = amount.sub(fee);
_transfer(msg.sender, address(this), fee); // Комиссия идёт в казначейство
}
_transfer(msg.sender, recipient, amount);
return true;
}
/// @dev Переводит токены от одного адреса к другому с комиссией
function transferFrom(address sender, address recipient, uint256 amount) public override whenNotPaused returns (bool) {
uint256 currentAllowance = allowance(sender, msg.sender);
require(currentAllowance >= amount, "ERC20: insufficient allowance");
uint256 fee = 0;
if (!exemptFromFees[sender]) {
fee = amount.mul(feeRate).div(10000);
amount = amount.sub(fee);
_transfer(sender, address(this), fee);
}
_spendAllowance(sender, msg.sender, amount);
_transfer(sender, recipient, amount);
return true;
}
/// @dev Позволяет владельцу сжечь часть токенов
function burn(uint256 amount) public onlyOwner {
_burn(msg.sender, amount);
}
/// @dev Позволяет владельцу перевести токены без комиссии
function emergencyWithdraw(address to, uint256 amount) public onlyOwner {
_transfer(msg.sender, to, amount);
}
/// @dev Приостанавливает все переводы (только владелец)
function pause() public onlyOwner {
_pause();
}
/// @dev Возобновляет все переводы (только владелец)
function unpause() public onlyOwner {
_unpause();
}
}(pause).
unpause).
setFeeRate() — изменение ставки комиссии.
setExemptFromFees()
whenNotPaused
SafeMath
Переопределения transfer и transferFrom с учётом комиссии.
function withdrawFees(address to) public onlyOwner {
uint256 balance = balanceOf(address(this));
_transfer(address(this), to, balance);
}
Hardhat: npx hardhat test.
Покрытие кода: npx hardhat coverage.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
/// @title Звёздный поток изобилия (Starflow of Abundance, SFA) v2.0
/// @dev Расширенный ERC20-токен с механизмами управления и безопасности
contract StarflowOfAbundanceV2 is ERC20, Ownable, Pausable {
using SafeMath for uint256;
}(pause).
unpause).
setFeeRate() — изменение ставки комиссии.
setExemptFromFees()
whenNotPaused
SafeMath
Переопределения transfer и transferFrom с учётом комиссии.
function withdrawFees(address to) public onlyOwner {
uint256 balance = balanceOf(address(this));
_transfer(address(this), to, balance);
}
Hardhat: npx hardhat test.
Покрытие кода: npx hardhat coverage.