logos-messaging-rlnv2-contract/test/TestStableToken.sol

102 lines
3.4 KiB
Solidity
Raw Normal View History

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.19 <0.9.0;
import { BaseScript } from "../script/Base.s.sol";
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
chore: fuzz test expansion (#40) * test: register invalid * test: multiple registers * fix: increase max rejects * test: erasure with fullErase idCommitments * fix: reduce cyclomatic complexity * fix: reduce complexity one step less * fix: run tests in parallel * fix: undo run tests in parallel - default already * test: invalid extension with extreme values * fix: line length * test: set MaxTotalRateLimit * test: set ActiveDuration * test: Merkle inserts * test: Merkle erasures * test: GetRateCommitmentsRange * test: GetMerkleProof * fix: optimized MerkleInsert MerkleErasures * fix: update gas snapshot * test: malicious upgrade drains funds * fix: formatting * test: show success when unauthorized upgrade after malicious * test: offchain proof post lazy erase - multi-user erase reuse race * fix: line length * fix: remove offchain lazy erase test - rate limit still applies * fix: remove fuzz tests from CI run * fix: formatting * fix: formatting coverage * test: timestamp manipulation * fix: rename tests * test: front running for registration * fix: unused variables * test: register during spam conditions * fix: delete failing tests - test_MaliciousUpgradeDrainsFunds - testFrontrunning_RegistrationRevertsForVictim - testFrontrunning_SetFillingSpam * fix: delete MaliciousImplementation * fix: formatting with a new Foundry version * test: testEraseAndReuse with Echidna * fix: remove limit check * fix: remove test_MultiUserEraseReuseRace - test_TimestampManipulationRaces * fix: skip Echidna contract during forge test * test: Echidna contract with invariants - registerMembership - attemptExtensionRace - attemptErasureRace * fix: tune config file * fix: run and cleanup scripts for echidna * test: Echidna test replay * fix: Solidity version * fix: test_attemptExtensionRace_WakuRLN * fix: invalid commitment in test_attemptExtensionRace_WakuRLN * fix: invalid commitments in test_attemptErasureRace_WakuRLN * fix: line length * fix: skip all Echidna tests in CI * test: register invalid * test: multiple registers * fix: increase max rejects * test: erasure with fullErase idCommitments * fix: reduce cyclomatic complexity * fix: reduce complexity one step less * test: invalid extension with extreme values * fix: line length * test: set MaxTotalRateLimit * test: set ActiveDuration * test: Merkle inserts * test: Merkle erasures * test: GetRateCommitmentsRange * test: GetMerkleProof * fix: optimized MerkleInsert MerkleErasures * fix: update gas snapshot * fix: formatting * fix: remove tests with high overlap * fix: remove all tests originally meant for fuzzing * fix: rename merged Echidna tests * fix: formatting * test: fuzzing for essential invariants * test: EchidnaTest contract * fix: remove unnecessary imports * fix: remove unnecessary helpers * fix: remove bounds from invariants * fix: change test mode to property * fix: update run script * fix: max_test_rejects back to the original value * fix: remove unused local variables
2025-11-07 09:20:49 +08:00
import {
ERC20PermitUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
error AccountNotMinter();
error AccountAlreadyMinter();
error AccountNotInMinterList();
error InsufficientETH();
error ExceedsMaxSupply();
error InvalidMaxSupply(uint256 supplied);
contract TestStableToken is
Initializable,
ERC20Upgradeable,
ERC20PermitUpgradeable,
OwnableUpgradeable,
UUPSUpgradeable
{
mapping(address => bool) public isMinter;
uint256 public maxSupply;
uint256 public constant MIN_MINT_WEI = 1 ether;
event MinterAdded(address indexed account);
event MinterRemoved(address indexed account);
event ETHBurned(uint256 amount, address indexed minter, address indexed to, uint256 tokensMinted);
event MaxSupplySet(uint256 oldMaxSupply, uint256 newMaxSupply);
modifier onlyOwnerOrMinter() {
if (msg.sender != owner() && !isMinter[msg.sender]) revert("AccountNotMinter");
_;
}
constructor() {
_disableInitializers();
}
function initialize(uint256 _maxSupply) public initializer {
__ERC20_init("TestStableToken", "TST");
__ERC20Permit_init("TestStableToken");
__Ownable_init();
__UUPSUpgradeable_init();
if (_maxSupply == 0) revert InvalidMaxSupply(_maxSupply);
maxSupply = _maxSupply;
}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner { }
function addMinter(address account) external onlyOwner {
if (isMinter[account]) revert AccountAlreadyMinter();
isMinter[account] = true;
emit MinterAdded(account);
}
function removeMinter(address account) external onlyOwner {
if (!isMinter[account]) revert AccountNotInMinterList();
isMinter[account] = false;
emit MinterRemoved(account);
}
function mint(address to, uint256 amount) external onlyOwnerOrMinter {
if (totalSupply() + amount > maxSupply) revert ExceedsMaxSupply();
_mint(to, amount);
}
function mintWithETH(address to) external payable {
if (msg.value < MIN_MINT_WEI) revert InsufficientETH();
if (totalSupply() + msg.value > maxSupply) revert ExceedsMaxSupply();
// Burn ETH by sending to zero address
payable(address(0)).transfer(msg.value);
_mint(to, msg.value);
emit ETHBurned(msg.value, msg.sender, to, msg.value);
}
function setMaxSupply(uint256 _maxSupply) external onlyOwner {
if (_maxSupply < totalSupply()) revert ExceedsMaxSupply();
uint256 oldMaxSupply = maxSupply;
maxSupply = _maxSupply;
emit MaxSupplySet(oldMaxSupply, _maxSupply);
}
}
contract TestStableTokenFactory is BaseScript {
function run() public broadcast returns (address) {
return address(new TestStableToken());
}
}