├── package.json ├── .gitignore ├── hardhat.config.js ├── README.md └── contracts └── Main.sol /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | typechain-types 7 | 8 | # Hardhat files 9 | cache 10 | artifacts 11 | 12 | -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomicfoundation/hardhat-toolbox"); 2 | 3 | /** @type import('hardhat/config').HardhatUserConfig */ 4 | module.exports = { 5 | solidity: "^0.8.9", 6 | }; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Smart contracts custom methods 2 | 3 | 4 | mint 5 | 6 | Parameters: 7 | 8 | uint256 amount: The number of tokens to mint. 9 | 10 | bytes32 _hash: Hash of the message to be signed. 11 | 12 | uint8 _v: Recovery byte of the signature. 13 | 14 | bytes32 _r: First 32 bytes of the signature. 15 | 16 | bytes32 _s: Second 32 bytes of the signature. 17 | 18 | uint256 deadline: Deadline after which the signature is not valid. 19 | 20 | Access Control: Can only be called by the contract owner. 21 | 22 | 23 | Functionality: 24 | 25 | Validates the mint amount, hash, and signature. 26 | 27 | Increments ownerNounce. 28 | 29 | Mints the specified amount of tokens to the sender's address. 30 | 31 | 32 | 33 | 34 | burn 35 | 36 | Parameters: 37 | 38 | uint256 amount: The number of tokens to burn. 39 | 40 | Access Control: Can be called by any token holder. 41 | 42 | -------------------------------------------------------------------------------- /contracts/Main.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.9; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; 5 | import "@openzeppelin/contracts/access/Ownable.sol"; 6 | import "@openzeppelin/contracts/utils/math/SafeMath.sol"; 7 | 8 | contract Diam is Ownable, ERC20Permit { 9 | using SafeMath for uint256; 10 | 11 | uint256 public ownerNounce; 12 | 13 | constructor() ERC20("DIAM", "DIAM") ERC20Permit("DIAM") {} 14 | 15 | //DW03 - zero amount request 16 | //DW091 - Invalid hash 17 | //DW02 - unauthorized 18 | function mint( 19 | uint256 amount, 20 | bytes32 _hash, 21 | uint8 _v, 22 | bytes32 _r, 23 | bytes32 _s, 24 | uint256 deadline 25 | ) external { 26 | require(amount > 0, "DW03"); 27 | require(block.timestamp <= deadline, "DW092"); 28 | require( 29 | keccak256( 30 | abi.encodePacked( 31 | msg.sender, 32 | amount, 33 | ownerNounce, 34 | block.chainid, 35 | deadline, 36 | address(this) 37 | ) 38 | ) == _hash, 39 | "DW091" 40 | ); 41 | 42 | bytes32 messageDigest = keccak256( 43 | abi.encodePacked( 44 | "\x19Ethereum Signed Message:\n32", 45 | keccak256( 46 | abi.encodePacked( 47 | msg.sender, 48 | amount, 49 | ownerNounce, 50 | block.chainid, 51 | deadline, 52 | address(this) 53 | ) 54 | ) 55 | ) 56 | ); 57 | 58 | address signer = ECDSA.recover(messageDigest, _v, _r, _s); 59 | 60 | require(signer == owner(), "DW02"); 61 | 62 | ownerNounce++; 63 | 64 | _mint(_msgSender(), amount); 65 | } 66 | 67 | function burn(uint256 amount) external { 68 | _burn(msg.sender, amount); 69 | } 70 | } 71 | --------------------------------------------------------------------------------