ManaToken.t.sol
Обзор
Файл ManaToken.t.sol представляет собой набор модульных тестов на языке Solidity для смарт-контракта ManaToken. Тесты реализованы с использованием библиотеки Forge (через импорт forge-std/Test.sol) и предназначены для проверки корректности работы токена MANA, реализующего функционал ERC20 с дополнительными ролями и возможностью паузы.
Основная цель файла — обеспечить надежность и безопасность ключевых операций токена: создания (mint), сжигания (burn), управления ролями и паузы, а также проверить стандартные функции ERC20. Тесты охватывают как позитивные сценарии, так и отлавливают ошибки и ограничения.
Подробное описание компонентов
Контракт ManaTokenTest
Основной тестовый контракт для ManaToken. Наследуется от Test из forge-std, что предоставляет удобные методы для тестирования.
Свойства
Свойство | Тип | Описание |
|---|---|---|
|
| Экземпляр тестируемого токена |
|
| Адрес владельца (админ с правами) |
|
| Адрес с ролью управления игрой |
|
| Адрес с ролью управления стейкингом |
|
| Адрес с ролью прерывания/возобновления |
|
| Тестовые аккаунты пользователей |
События (для тестирования)
TokensMinted(address indexed to, uint256 amount, address indexed minter)— эмитируется при минте токенов.TokensBurned(address indexed from, uint256 amount, address indexed burner)— эмитируется при сжигании токенов.
Методы
setUp()
Инициализирует тестовую среду:
Создает фиктивные адреса с помощью
makeAddr.Разворачивает контракт
ManaTokenот имениowner.Назначает роли
GAME_MANAGER_ROLE,STAKING_MANAGER_ROLE,PAUSER_ROLEсоответствующим адресам.
Пример использования:
function test_Sample() public {
setUp();
// В этом месте manaToken уже развернут и роли назначены
}
Тесты конструктора
test_Constructor()— проверяет начальные параметры токена (name,symbol,decimals,totalSupply), а также назначенные роли владельцу.test_Constructor_ZeroAddress()— проверяет, что передача нулевого адреса в конструктор вызывает ошибку.
Тесты функции mint (создание токенов)
test_Mint_GameManager(),test_Mint_StakingManager()— проверяют успешный минт токенов ролямиGAME_MANAGER_ROLEиSTAKING_MANAGER_ROLE.test_Mint_UnauthorizedUser()— проверяет, что минт невозможен без нужной роли.test_Mint_ZeroAddress()— проверяет ошибку при попытке минта на нулевой адрес.test_Mint_ZeroAmount()— проверяет ошибку при попытке минта 0 токенов.test_Mint_WhenPaused()— проверяет, что минт невозможен при паузе контракта.
Тесты функции burn (сжигание токенов)
test_Burn_GameManager(),test_Burn_StakingManager()— проверяют успешное сжигание токенов ролями.test_Burn_UnauthorizedUser()— проверяет ошибку при попытке сжигания без роли.test_Burn_ZeroAddress(),test_Burn_ZeroAmount()— проверяют ошибки при нулевых параметрах.test_Burn_InsufficientBalance()— проверяет ошибку при попытке сжечь больше токенов, чем есть.test_Burn_WhenPaused()— проверяет невозможность сжигания при паузе.
Тесты функции burnSelf (сжигание собственных токенов)
test_BurnSelf()— успешное сжигание собственных токенов.test_BurnSelf_ZeroAmount(),test_BurnSelf_InsufficientBalance()— проверяют ошибки.test_BurnSelf_WhenPaused()— проверяет невозможность сжигания при паузе.
Тесты паузы контракта
test_Pause(),test_Unpause()— проверяют корректное срабатывание функций паузы и возобновления.test_Pause_UnauthorizedUser(),test_Unpause_UnauthorizedUser()— проверяют ограничение доступа.test_Transfer_WhenPaused()— проверяет запрет на трансфер токенов при паузе.
Тесты управления ролями
test_HasRole()— проверяет назначение ролей указанным адресам.test_RoleConstants()— проверяет корректность хэшированных констант ролей.
Стандартные тесты ERC20
test_Transfer()— проверяет корректность передачи токенов между пользователями.test_Approve_TransferFrom()— проверяет механизмы одобрения и передачи токенов от имени другого адреса.
Fuzz-тесты (тестирование с рандомными значениями)
testFuzz_Mint(uint256 amount)— проверяет минт с случайным положительным количеством.testFuzz_Burn(uint256 mintAmount, uint256 burnAmount)— проверяет последовательность минта и сжигания с рандомными значениями.testFuzz_Transfer(uint256 mintAmount, uint256 transferAmount)— проверяет трансфер с рандомными значениями.
Особые случаи
test_MultipleRoles()— проверяет, что пользователь с несколькими ролями может выполнять соответствующие действия.test_SupportsInterface()— проверяет поддержку интерфейсаIAccessControl(ERC165).
Важные детали реализации и алгоритмы
Использование ролей на базе OpenZeppelin
AccessControlдля разграничения прав —GAME_MANAGER_ROLE,STAKING_MANAGER_ROLE,PAUSER_ROLE, а такжеDEFAULT_ADMIN_ROLE.Управление процессами минта и бёрна токенов через роли с проверкой прав.
Реализация механизма паузы с помощью
pause()иunpause()блокирует критичные операции при активации.В тестах используется
vm.prank()для эмуляции вызова функций с разных адресов.Проверка ошибок реализована через
vm.expectRevert()с указанием конкретных селекторов ошибок изManaToken.Использование событий для отслеживания операций минта и бёрна.
Fuzz-тесты обеспечивают устойчивость к граничным и случайным значениям.
Взаимодействие с другими частями системы
Тесты напрямую взаимодействуют с контрактом
ManaToken(../src/ManaToken.sol).Используют интерфейс
IAccessControlиз OpenZeppelin для проверки ролей.В тестах задействован Forge Std (
forge-std/Test.sol) для создания окружения и вспомогательных функций.В реальной системе
ManaTokenвероятно интегрирован в игровую логику, стейкинг и управление состоянием через назначенные роли.Тесты обеспечивают гарантию корректной работы токена в различных сценариях, что критично для безопасности и надежности всей системы.
Диаграмма структуры контракта ManaTokenTest
classDiagram
class ManaTokenTest {
+ManaToken manaToken
+address owner
+address gameManager
+address stakingManager
+address pauser
+address user1
+address user2
+function setUp()
+function test_Constructor()
+function test_Constructor_ZeroAddress()
+function test_Mint_GameManager()
+function test_Mint_StakingManager()
+function test_Mint_UnauthorizedUser()
+function test_Mint_ZeroAddress()
+function test_Mint_ZeroAmount()
+function test_Mint_WhenPaused()
+function test_Burn_GameManager()
+function test_Burn_StakingManager()
+function test_Burn_UnauthorizedUser()
+function test_Burn_ZeroAddress()
+function test_Burn_ZeroAmount()
+function test_Burn_InsufficientBalance()
+function test_Burn_WhenPaused()
+function test_BurnSelf()
+function test_BurnSelf_ZeroAmount()
+function test_BurnSelf_InsufficientBalance()
+function test_BurnSelf_WhenPaused()
+function test_Pause()
+function test_Pause_UnauthorizedUser()
+function test_Unpause()
+function test_Unpause_UnauthorizedUser()
+function test_Transfer_WhenPaused()
+function test_HasRole()
+function test_RoleConstants()
+function test_Transfer()
+function test_Approve_TransferFrom()
+function testFuzz_Mint(uint256 amount)
+function testFuzz_Burn(uint256 mintAmount, uint256 burnAmount)
+function testFuzz_Transfer(uint256 mintAmount, uint256 transferAmount)
+function test_MultipleRoles()
+function test_SupportsInterface()
}
ManaTokenTest --> ManaToken : использует
ManaTokenTest ..> IAccessControl : проверяет роли
Итог
Файл ManaToken.t.sol — это комплексный набор тестов, обеспечивающих качество и безопасность контракта ManaToken с расширенным функционалом. Он проверяет корректность работы с ролями, паузой, стандартным ERC20 API, а также устойчивость к ошибочным и граничным ситуациям. Такой подход гарантирует, что ManaToken будет работать надежно в рамках игровой или финансовой экосистемы, где он применяется.