Skip to content

Commit a138fb9

Browse files
first commit
1 parent c7af2c7 commit a138fb9

16 files changed

Lines changed: 650 additions & 2 deletions

File tree

.gas-snapshot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
IvanTokenTest:testInitialSupply() (gas: 7743)
2+
IvanTokenTest:testMintByOwner() (gas: 44827)
3+
IvanTokenTest:testTransfer() (gas: 45682)
4+
IvanTokenTest:test_RevertWhen_NonOwnerMints() (gas: 13277)

.github/workflows/test.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CI
2+
3+
permissions: {}
4+
5+
on:
6+
push:
7+
pull_request:
8+
workflow_dispatch:
9+
10+
jobs:
11+
check:
12+
name: Foundry project
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
steps:
17+
- uses: actions/checkout@v6
18+
with:
19+
persist-credentials: false
20+
submodules: recursive
21+
22+
- name: Install Foundry
23+
uses: foundry-rs/foundry-toolchain@v1
24+
25+
- name: Show Forge version
26+
run: forge --version
27+
28+
- name: Run Forge fmt
29+
run: forge fmt --check
30+
31+
- name: Run Forge build
32+
run: forge build --sizes
33+
34+
- name: Run Forge tests
35+
run: forge test -vvv

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Compiler files
2+
cache/
3+
out/
4+
5+
# Ignores development broadcast logs
6+
!/broadcast
7+
/broadcast/*/31337/
8+
/broadcast/**/dry-run/
9+
10+
# Docs
11+
docs/
12+
13+
# Dotenv file
14+
.env

README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
2+
# 🚀 Ivan Token (IVN) - ERC20 Implementation
3+
4+
5+
6+
[![Solidity](https://img.shields.io/badge/Solidity-%5E0.8.20-blue)](https://soliditylang.org/)
7+
8+
[![Framework](https://img.shields.io/badge/Framework-Foundry-orange)](https://book.getfoundry.sh/)
9+
10+
[![License](https://img.shields.io/badge/License-MIT-green)](https://opensource.org/licenses/MIT)
11+
12+
[![Coverage](https://img.shields.io/badge/Coverage-100%25-brightgreen)](#-testing)
13+
14+
15+
16+
A professional, production-ready **ERC20** token implementation using the **Foundry** development framework and **OpenZeppelin** standards. This project serves as a showcase of smart contract best practices, including comprehensive testing, gas optimization, and automated deployment scripts.
17+
18+
---
19+
20+
## 🏗 Project Architecture
21+
22+
23+
The project is structured following the Foundry standard layout for maximum efficiency and readability:
24+
25+
26+
27+
- **`src/`**: Core smart contract logic.
28+
29+
- **`test/`**: Unit tests written in Solidity for robust verification.
30+
31+
- **`script/`**: Deployment and interaction scripts.
32+
33+
- **`lib/`**: External dependencies (OpenZeppelin).
34+
35+
36+
37+
---
38+
## 🛠 Tech Stack & Tools
39+
- **Solidity:** ^0.8.20
40+
- **Framework:** [Foundry](https://book.getfoundry.sh/) (Forge & Cast)
41+
- **Library:** [OpenZeppelin Contracts](https://openzeppelin.com/contracts/)
42+
- **Infrastructure:** QuickNode RPC
43+
44+
---
45+
46+
## ✨ Features
47+
48+
49+
50+
- **Standard Compliance:** Fully compatible with the ERC20 standard.
51+
52+
- **Ownable & Secure:** Implements OpenZeppelin's `Ownable` for administrative functions (minting).
53+
54+
- **Advanced Testing:** Utilizes modern Foundry cheatcodes like `vm.prank` and `vm.expectRevert`.
55+
56+
- **Gas Optimized:** Compiled with the `via-ir` pipeline and `paris` EVM version for compatibility and efficiency.
57+
58+
59+
60+
---
61+
62+
63+
64+
## 🚀 Live Deployment (Amoy Testnet)
65+
66+
67+
68+
The contract is successfully deployed and live on the **Polygon Amoy Testnet**.
69+
70+
71+
72+
- **Contract Address:** [`0x0Fc2C3f40f27d27953669a98035156227384Bc6C`](https://amoy.polygonscan.com/address/0x4fef70bb1dbe11B0F1135C8C65f019D02d418073)
73+
74+
- **Network:** Polygon Amoy (Chain ID: 80002)
75+
76+
- **Symbol:** IVN
77+
78+
- **Initial Supply:** 1,000,000 IVN
79+
80+
81+
82+
---
83+
84+
85+
86+
## 🧪 Testing
87+
88+
89+
90+
This project maintains **100% code coverage**. We use strictly Solidity-based testing to ensure contract reliability.
91+
### Key Tests:
92+
1. **Initial Supply Check:** Verifies correct minting on deployment.
93+
2. **Secure Transfers:** Ensures users can send/receive tokens.
94+
3. **Access Control:** Validates that only the `Owner` can mint new tokens.
95+
96+
97+
98+
### Run Tests:
99+
100+
```bash
101+
forge test -vv
102+
```
103+
104+
---
105+
106+
107+
108+
### Coverage Report:
109+
110+
```bash
111+
forge coverage
112+
```
113+
![coverage](./assets/coverage.png)
114+
115+
116+
---
117+
118+
119+
120+
## Installation & Usage
121+
122+
### Prerequisites
123+
124+
- Foundry
125+
```bash
126+
curl -L https://foundry.paradigm.xyz | bash && foundryup
127+
```
128+
129+
130+
131+
---
132+
133+
134+
135+
### Clone & Build
136+
137+
```bash
138+
git clone <your-repo-url>
139+
140+
cd ERC20-Ivan-Token
141+
142+
forge install
143+
144+
forge build
145+
```
146+
---
147+
## 📜 Deployment Script
148+
The deployment is handled via Solidity scripts for idempotency and security.
149+
```bash
150+
script script/DeployIvan.s.sol --rpc-url $AMOY_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify
151+
```
152+
---
153+
## 📜 License
154+
This project is licensed under the **MIT License**.
155+
156+
## Author
157+
### Ali Nasirlou
158+
Github : [`alinasirlou2020`](https://github.com/alinasirlou2020)
159+
Linkedin : [`Ali Nasirlou`](https://www.linkedin.com/in/ali-nasirlou-14b6713b1/)

assets/coverage.png

52.6 KB
Loading

assets/desktop.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[LocalizedFileNames]
2+
Screenshot 2026-02-23 214057.png=@Screenshot 2026-02-23 214057,0
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"transactions": [
3+
{
4+
"hash": "0xc06e987fca6545554ff6b45de49825d4528637a97f715c521c41027a35540606",
5+
"transactionType": "CREATE",
6+
"contractName": "Ivan",
7+
"contractAddress": "0x76d740e6b225cecb930a2218eae9440413eb7d84",
8+
"function": null,
9+
"arguments": [
10+
"0xa103CCB53B200B705485A36F43E6526cAF2df0f5"
11+
],
12+
"transaction": {
13+
"from": "0xa103ccb53b200b705485a36f43e6526caf2df0f5",
14+
"gas": "0xf9f25",
15+
"value": "0x0",
16+
"input": "0x608034620003ba57601f19906001600160401b03601f62000fb6388190038281018616850184811186821017620003bf57859282916040528339602094859181010312620003ba5751936001600160a01b0380861694909390858703620003ba576200006a620003d5565b6004948582526324bb30b760e11b8383015262000086620003d5565b6003938482526224ab2760e91b818301528351868111620003a5578554946001958681811c911680156200039a575b8482101462000385579081868493116200032f575b508390868311600114620002cc57600092620002c0575b505060001982881b1c191690851b1785555b8151958611620002ab5787548481811c91168015620002a0575b828210146200028b5783811162000240575b5080928611600114620001d4575084955090849291600095620001c8575b50501b92600019911b1c19161781555b8215620001b0575060058054610100600160a81b03198116600895861b610100600160a81b031617909155604051931c167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3610bc09081620003f68239f35b602490600060405191631e4fbdf760e01b8352820152fd5b0151935038806200013d565b939295859081168860005285600020956000905b898383106200022557505050106200020a575b50505050811b0181556200014d565b01519060f884600019921b161c1916905538808080620001fb565b858701518955909701969485019488935090810190620001e8565b88600052816000208480890160051c820192848a1062000281575b0160051c019085905b828110620002745750506200011f565b6000815501859062000264565b925081926200025b565b602289634e487b7160e01b6000525260246000fd5b90607f16906200010d565b604188634e487b7160e01b6000525260246000fd5b015190503880620000e1565b908a8894169189600052856000209260005b87828210620003185750508411620002ff575b505050811b018555620000f3565b0151600019838a1b60f8161c19169055388080620002f1565b8385015186558b97909501949384019301620002de565b90915087600052836000208680850160051c8201928686106200037b575b918991869594930160051c01915b8281106200036b575050620000ca565b600081558594508991016200035b565b925081926200034d565b60228b634e487b7160e01b6000525260246000fd5b90607f1690620000b5565b604189634e487b7160e01b6000525260246000fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b03811183821017620003bf5760405256fe6080604081815260048036101561001557600080fd5b600092833560e01c90816306fdde031461074b57508063095ea7b3146106a257806318160ddd1461068357806323b872dd14610646578063313ce5671461062a57806332cb6b0c146106035780633f4ba83a1461059a57806340c10f19146104c957806342966c68146104ab5780635c975abb1461048757806370a0823114610450578063715018a6146103ef57806379cc6790146103b95780638456cb591461035e5780638da5cb5b1461033157806395d89b4114610211578063a9059cbb146101e0578063dd62ed3e146101935763f2fde38b146100f457600080fd5b3461018f57602036600319011261018f5761010d610889565b6101156108ba565b6001600160a01b0381811693909290841561017957505060058054610100600160a81b03198116600893841b610100600160a81b031617909155901c167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101859052602490fd5b8280fd5b5050346101dc57806003193601126101dc57806020926101b1610889565b6101b96108a4565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b5080fd5b5050346101dc57806003193601126101dc5760209061020a610200610889565b60243590336108e9565b5160018152f35b509190346101dc57816003193601126101dc57805190828454600181811c90808316928315610327575b6020938484108114610314578388529081156102f857506001146102a3575b505050829003601f01601f191682019267ffffffffffffffff841183851017610290575082918261028c925282610840565b0390f35b634e487b7160e01b815260418552602490fd5b8787529192508591837f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8385106102e4575050505083010138808061025a565b8054888601830152930192849082016102ce565b60ff1916878501525050151560051b840101905038808061025a565b634e487b7160e01b895260228a52602489fd5b91607f169161023b565b5050346101dc57816003193601126101dc57600554905160089190911c6001600160a01b03168152602090f35b5050346101dc57816003193601126101dc5760207f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589161039c6108ba565b6103a4610b6c565b600160ff19600554161760055551338152a180f35b5050346101dc573660031901126103ec576103e96103d5610889565b602435906103e48233836109cf565b610aa2565b80f35b80fd5b83346103ec57806003193601126103ec576104086108ba565b60058054610100600160a81b03198116909155819060081c6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5050346101dc5760203660031901126101dc5760209181906001600160a01b03610478610889565b16815280845220549051908152f35b5050346101dc57816003193601126101dc5760209060ff6005541690519015158152f35b8382346101dc5760203660031901126101dc576103e9903533610aa2565b50903461018f578060031936011261018f576104e3610889565b90602435916104f06108ba565b600254906b014adf4b7320334b9000000061050b8584610b49565b1161058a576001600160a01b03169384156105735750827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926105598795602094610554610b6c565b610b49565b60025585855284835280852082815401905551908152a380f35b825163ec442f0560e01b8152908101869052602490fd5b8251638a164f6360e01b81528590fd5b503461018f578260031936011261018f576105b36108ba565b6005549060ff8216156105f5575060ff1916600555513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b8251638dfc202b60e01b8152fd5b5050346101dc57816003193601126101dc57602090516b014adf4b7320334b900000008152f35b5050346101dc57816003193601126101dc576020905160128152f35b5050346101dc5760603660031901126101dc5760209061020a610667610889565b61066f6108a4565b6044359161067e8333836109cf565b6108e9565b5050346101dc57816003193601126101dc576020906002549051908152f35b503461018f578160031936011261018f576106bb610889565b602435903315610734576001600160a01b031691821561071d57508083602095338152600187528181208582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b8351634a1406b160e11b8152908101859052602490fd5b835163e602df0560e01b8152808401869052602490fd5b849150833461018f578260031936011261018f5782600354600181811c90808316928315610836575b60209384841081146103145783885290811561081a57506001146107c457505050829003601f01601f191682019267ffffffffffffffff841183851017610290575082918261028c925282610840565b600387529192508591837fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b838510610806575050505083010185808061025a565b8054888601830152930192849082016107f0565b60ff1916878501525050151560051b840101905085808061025a565b91607f1691610774565b6020808252825181830181905290939260005b82811061087557505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610853565b600435906001600160a01b038216820361089f57565b600080fd5b602435906001600160a01b038216820361089f57565b60055460081c6001600160a01b031633036108d157565b60405163118cdaa760e01b8152336004820152602490fd5b916001600160a01b038084169283156109b6571692831561099d5761090c610b6c565b6000908382528160205260408220549083821061096b575091604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101839052606490fd5b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b9160018060a01b038093169160009383855260016020526040938486209183169182875260205284862054926000198410610a0e575b50505050505050565b848410610a7257508015610a5a578115610a4257855260016020528385209085526020520391205538808080808080610a05565b8451634a1406b160e11b815260048101879052602490fd5b845163e602df0560e01b815260048101879052602490fd5b8551637dc7a0d960e11b81526001600160a01b039190911660048201526024810184905260448101859052606490fd5b906001600160a01b0382169081156109b657610abc610b6c565b60009282845283602052604084205490828210610b175750817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101829052606490fd5b91908201809211610b5657565b634e487b7160e01b600052601160045260246000fd5b60ff60055416610b7857565b60405163d93c066560e01b8152600490fdfea2646970667358221220a422e40f91172d21a1da7c614ee368e815c7fec6602d1c9ea4ce1225eb39602464736f6c63430008140033000000000000000000000000a103ccb53b200b705485a36f43e6526caf2df0f5",
17+
"nonce": "0x1",
18+
"chainId": "0x13882"
19+
},
20+
"additionalContracts": [],
21+
"isFixedGasLimit": false
22+
}
23+
],
24+
"receipts": [
25+
{
26+
"status": "0x1",
27+
"cumulativeGasUsed": "0xc0542",
28+
"logs": [
29+
{
30+
"address": "0x76d740e6b225cecb930a2218eae9440413eb7d84",
31+
"topics": [
32+
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
33+
"0x0000000000000000000000000000000000000000000000000000000000000000",
34+
"0x000000000000000000000000a103ccb53b200b705485a36f43e6526caf2df0f5"
35+
],
36+
"data": "0x",
37+
"blockHash": "0x3aab311628a3f9de0e0232076a1411501bb0bb20de9edb7139a11eead5399bf3",
38+
"blockNumber": "0x208b508",
39+
"blockTimestamp": "0x6995880a",
40+
"transactionHash": "0xc06e987fca6545554ff6b45de49825d4528637a97f715c521c41027a35540606",
41+
"transactionIndex": "0x0",
42+
"logIndex": "0x0",
43+
"removed": false
44+
},
45+
{
46+
"address": "0x0000000000000000000000000000000000001010",
47+
"topics": [
48+
"0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63",
49+
"0x0000000000000000000000000000000000000000000000000000000000001010",
50+
"0x000000000000000000000000a103ccb53b200b705485a36f43e6526caf2df0f5",
51+
"0x0000000000000000000000007ee41d8a25641000661b1ef5e6ae8a00400466b0"
52+
],
53+
"data": "0x00000000000000000000000000000000000000000000000005775ff565ef10000000000000000000000000000000000000000000000000000de0b6b3a76b5eb80000000000000000000000000000000000000000000022138d0fa34c36e86838000000000000000000000000000000000000000000000000086956be417c4eb8000000000000000000000000000000000000000000002213928703419cd77838",
54+
"blockHash": "0x3aab311628a3f9de0e0232076a1411501bb0bb20de9edb7139a11eead5399bf3",
55+
"blockNumber": "0x208b508",
56+
"blockTimestamp": "0x6995880a",
57+
"transactionHash": "0xc06e987fca6545554ff6b45de49825d4528637a97f715c521c41027a35540606",
58+
"transactionIndex": "0x0",
59+
"logIndex": "0x1",
60+
"removed": false
61+
}
62+
],
63+
"logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000080000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800001000000000000000100000000000000000000022000000000000000000800000000000000000080000000000000400000000000000000020000000400000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000404000000000100000000020000000000000000000000000001000000000000000000000000000002080100000",
64+
"type": "0x2",
65+
"transactionHash": "0xc06e987fca6545554ff6b45de49825d4528637a97f715c521c41027a35540606",
66+
"transactionIndex": "0x0",
67+
"blockHash": "0x3aab311628a3f9de0e0232076a1411501bb0bb20de9edb7139a11eead5399bf3",
68+
"blockNumber": "0x208b508",
69+
"gasUsed": "0xc0542",
70+
"effectiveGasPrice": "0x746a52883f",
71+
"from": "0xa103ccb53b200b705485a36f43e6526caf2df0f5",
72+
"to": null,
73+
"contractAddress": "0x76d740e6b225cecb930a2218eae9440413eb7d84"
74+
}
75+
],
76+
"libraries": [],
77+
"pending": [],
78+
"returns": {},
79+
"timestamp": 1771407371143,
80+
"chain": 80002,
81+
"commit": null
82+
}

0 commit comments

Comments
 (0)