-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
160 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// SPDX-License-Identifier: GPLv3 | ||
pragma solidity ^0.8.21; | ||
|
||
import { ERC20 } from "openzeppelin/token/ERC20/ERC20.sol"; | ||
import { Ownable } from "openzeppelin/access/Ownable.sol"; | ||
|
||
contract NaymToken is ERC20, Ownable { | ||
/** | ||
* @dev The caller account is not authorized to mint. | ||
*/ | ||
error UnauthorizedMinter(address account); | ||
|
||
/** | ||
* @dev The minter can mint new tokens. | ||
*/ | ||
address public minter; | ||
|
||
/** | ||
* @dev Throws if called by any account other than the minter. | ||
*/ | ||
modifier onlyMinter() { | ||
if(_msgSender() != minter) { | ||
revert UnauthorizedMinter(_msgSender()); | ||
} | ||
_; | ||
} | ||
|
||
/** | ||
* @dev Constructor | ||
* @param _owner The address of the initial owner of the contract. | ||
* @param _minter The address of the initial minter of the contract. | ||
*/ | ||
constructor(address _owner, address _minter) ERC20("Naym", "NAYM") Ownable(_owner) { | ||
minter = _minter; | ||
} | ||
|
||
/** | ||
* @dev The owner can set the minter. | ||
* @param _minter The address of the new minter. | ||
*/ | ||
function setMinter(address _minter) public onlyOwner { | ||
minter = _minter; | ||
} | ||
|
||
/** | ||
* @dev The minter can mint new tokens. | ||
* @param _to The address to which the minted tokens will be sent. | ||
* @param _amount The amount of tokens to mint. | ||
*/ | ||
function mint(address _to, uint256 _amount) public onlyMinter { | ||
_mint(_to, _amount); | ||
} | ||
|
||
/** | ||
* @dev Burn one's own tokens. | ||
* @param _amount The amount of tokens to burn. | ||
*/ | ||
function burn(uint256 _amount) public { | ||
_burn(_msgSender(), _amount); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: GPLv3 | ||
pragma solidity ^0.8.21; | ||
|
||
import {Test, console} from "forge-std/Test.sol"; | ||
import { Vm } from "forge-std/Vm.sol"; | ||
|
||
import { NaymToken } from "../src/NaymToken.sol"; | ||
import { Ownable } from "openzeppelin/access/Ownable.sol"; | ||
|
||
contract NaymTokenTest is Test { | ||
NaymToken public t; | ||
|
||
address owner1 = address(0x111); | ||
address owner2 = address(0x789); | ||
address minter1 = address(0x123); | ||
address minter2 = address(0x456); | ||
|
||
function setUp() public { | ||
t = new NaymToken(owner1, minter1); | ||
} | ||
|
||
function test_Init() public { | ||
assertEq(t.name(), "Naym"); | ||
assertEq(t.symbol(), "NAYM"); | ||
assertEq(t.decimals(), 18); | ||
assertEq(t.totalSupply(), 0); | ||
assertEq(t.owner(), owner1); | ||
assertEq(t.minter(), minter1); | ||
} | ||
|
||
function test_ChangeOwner() public { | ||
// pass | ||
vm.prank(owner1); | ||
t.transferOwnership(owner2); | ||
assertEq(t.owner(), owner2); | ||
|
||
// not owner | ||
vm.prank(owner1); | ||
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, owner1)); | ||
t.transferOwnership(owner1); | ||
|
||
// invalid new owner | ||
vm.prank(owner2); | ||
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0))); | ||
t.transferOwnership(address(0)); | ||
} | ||
|
||
function test_SetMinter() public { | ||
// unauthorized | ||
vm.prank(address(0x1234)); | ||
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(0x1234))); | ||
t.setMinter(minter2); | ||
|
||
// authorized | ||
vm.prank(owner1); | ||
t.setMinter(minter2); | ||
assertEq(t.minter(), minter2); | ||
|
||
// can set to null address | ||
vm.prank(owner1); | ||
t.setMinter(address(0)); | ||
assertEq(t.minter(), address(0)); | ||
} | ||
|
||
function test_Mint() public { | ||
// unauthorized | ||
vm.prank(address(0x1234)); | ||
vm.expectRevert(abi.encodeWithSelector(NaymToken.UnauthorizedMinter.selector, address(0x1234))); | ||
t.mint(address(0x1234), 100); | ||
|
||
// authorized | ||
vm.prank(minter1); | ||
t.mint(address(0x1234), 100); | ||
assertEq(t.totalSupply(), 100); | ||
assertEq(t.balanceOf(address(0x1234)), 100); | ||
} | ||
} |