Skip to content
AlexArhipovPublic

About

42 School Tokenizer project - Token42 (T42), a BEP-20 token on BNB Smart Chain Testnet

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Tokenizer — Avivien42 (AVI42)

An ERC-20 / BEP-20 token built for the 42 School Tokenizer project, deployed and verified on the Ethereum Sepolia public test network.

Token name Avivien42
Ticker AVI42
Decimals 18
Total supply 1,000 AVI42 — fixed, minted once at deployment
Minting none — the contract has no mint function
Standard ERC-20, plus getOwner() so the same source is also BEP-20 conformant
Network Ethereum Sepolia (chain id 11155111)
Contract address 0xc03b51037d62FDD8196265Ce0c4911B4C45DA91b
Block explorer Etherscan — source verified ✅
Also verified on Blockscout and Sourcify
Deployment tx 0x94413a72…cf335ff1

Repository layout

.
├── README.md          # this file — the choices made and why
├── code/              # the smart contract source
├── deployment/        # deployment script, the log of the actual deployment,
│                      # and ops/ - one script per token operation
├── documentation/     # user guide + whitepaper
└── test/              # automated test suite (18 tests)

Choices and the reasons behind them

Why Ethereum Sepolia

The subject leaves the chain free — it asks only that the standard of the chosen chain be respected, and names "ERC20 for ETH or BEP-20 for BSC" as its two examples. Both were viable here, and the contract is written so that it satisfies either.

Sepolia was chosen for three reasons:

  • No real money, and reliably so. The subject forbids spending real funds, so the deployment has to run on a faucet-funded account. BNB Chain's testnet faucet now requires a minimum balance of real BNB on mainnet and was empty when this project was deployed; Sepolia's faucets dispense freely. A test network you cannot actually transact on is not a usable target — including on the day of the defense, when the token has to be demonstrated live.
  • The reference EVM chain. Sepolia is Ethereum's own test network, maintained by the Ethereum foundation and used by most of the ecosystem. Solidity, Hardhat, OpenZeppelin, MetaMask and Etherscan are all built for it first.
  • Three independent verifications. The source is published and matched against the deployed bytecode on Etherscan, Blockscout and Sourcify. Anyone can check the contract on the explorer of their choice rather than trusting a single one.

The same source also runs on BNB Smart Chain. BEP-20 is the ERC-20 interface with one addition, getOwner(), which this contract implements — see code/Avivien42.sol. hardhat.config.js keeps the BSC Testnet network configured, so deploying there is the same command with a different --network flag and no change to a single line of Solidity. That portability is the actual content of the claim "BEP-20 is ERC-20", and it is the reason the choice of chain is a deployment detail rather than a design decision.

Why Solidity

Solidity is the language the EVM ecosystem is actually written in. Every audited library, every tutorial and every verification tool assumes it. Picking anything else (Vyper, Yul) would mean giving up OpenZeppelin and the explorers' Solidity verifiers for no benefit at this scale.

Why Hardhat

Hardhat was chosen over Truffle and Remix because:

  • Truffle is discontinued (ConsenSys sunset it in 2023), so building on it means building on an unmaintained tool.
  • Remix is a browser IDE. It is excellent for a quick experiment, but the project requires a git repository with reproducible, reviewable scripts. Remix does not give you a committed deployment script or a test suite.
  • Hardhat gives an in-process EVM for fast tests, a scriptable deployment flow, and hardhat-verify, which verified this contract on Etherscan, Blockscout and Sourcify with a single command.

Foundry would have been a reasonable alternative; Hardhat was preferred because the project's tooling (Node.js, npm) was already present and its JavaScript scripts are easier to read during a peer review than Solidity test contracts.

Why OpenZeppelin instead of writing ERC-20 by hand

This is the single most important decision in the project.

Writing the ERC-20 interface from scratch is about 60 lines of code, and it is also where the overwhelming majority of historical token bugs live: wrong return values, missing events, unchecked arithmetic, broken allowance accounting. OpenZeppelin's implementation is audited, is used by a large share of tokens in production, and is what any reviewer already knows how to read.

Reusing a reviewed implementation and spending the saved effort on the parts that are actually specific to this token (the supply policy, the privilege model) is the safer engineering trade-off. The contract is still fully understood and documented — see code/Avivien42.sol.

Why 1,000 tokens, and why the supply is fixed

The subject says nothing at all about the supply — it only requires "42" in the name, which the token name already carries. Both numbers below are therefore project decisions and are defended as such.

Fixed rather than mintable. An owner-callable mint() would mean that every holder's share can be diluted at any moment by a single address. The cap that usually accompanies it only bounds the dilution; it does not remove it, and it still asks holders to trust that the key behind that address is neither malicious nor stolen. Removing the function removes the question: the supply written in the source is the supply that will exist forever. That guarantee is verifiable by anybody reading the verified source on BscScan, and it does not depend on anyone's good behaviour.

The cost of the decision is accepted knowingly: if more tokens are ever needed, there is no way to issue them — a new contract would have to be deployed. For a token whose supply policy is "there is no supply policy, it is a constant", that is the point rather than a limitation.

1,000 rather than millions. Large round supplies in this space are mostly theatre: the number is chosen so that a single token looks cheap. This token has no price and no market, so there is nothing to stage. 1,000 is a quantity a human can hold in their head, and it makes the arithmetic during the defense readable — burn 42 tokens and totalSupply visibly goes to 958.

Note that a small count costs no precision: with 18 decimals the smallest transferable unit is 10⁻¹⁸ of a token, so 1,000 tokens still divide into 10²¹ pieces.

Security decisions

The subject asks to think about "ownership and privileges". The conclusion reached here is that the safest set of privileges is the empty one:

Decision Reason
Fixed supply, minted once in the constructor There is no mint function anywhere in the contract, so nobody — not the owner, not the deployer — can ever create another token. Holders do not have to trust a promise not to inflate their share: inflation is impossible by construction.
No privileged functions at all The contract contains no onlyOwner entry point. There is no mint, no pause, no blacklist and no forced transfer. A stolen owner key gives an attacker no power whatsoever over the token.
The owner role exists only as BEP-20 getOwner() BEP-20 extends ERC-20 with getOwner(), which identifies who issued the token. Being that on-chain label is the entire purpose of the role here.
Ownable2Step instead of Ownable Handing the issuer label to a mistyped address would misattribute the token permanently. The two-step handover makes that impossible: the new owner has to accept the role from their own account.
burn written directly, without ERC20Burnable The OpenZeppelin extension also ships burnFrom, which lets an approved spender destroy somebody else's tokens. This token has no integration that needs it, so only burn is exposed: the burner is always msg.sender, and destroying tokens you do not hold is not merely forbidden but impossible.
Owner passed to the constructor Rather than hardcoding msg.sender, the initial owner is an explicit argument, so the deployer key and the owner role do not have to be the same account.
Secrets never committed The private key lives in a git-ignored .env (or in Hardhat's encrypted keystore). Only .env.example is tracked.

Why a fixed 18 decimals

18 is the ERC-20/BEP-20 de-facto standard and what wallets, explorers and DEXs assume by default. Deviating from it is a well-known source of integration bugs, so decimals() is left at the OpenZeppelin default.

Quick start

npm install                  # install dependencies
npx hardhat build            # compile the contract
npx hardhat test             # run the 18-test suite

Deploying and verifying:

cp .env.example .env         # then fill in a throwaway private key and an Etherscan key
npx hardhat run deployment/deploy.js --network sepolia
npx hardhat verify --network sepolia <CONTRACT_ADDRESS> <OWNER_ADDRESS>

Swap --network sepolia for --network bscTestnet to deploy the identical source to BNB Smart Chain Testnet instead; both networks are configured in hardhat.config.js.

Full step-by-step instructions — including getting free test ETH, verifying the source and adding the token to MetaMask — are in documentation/README.md.

Documentation

About

42 School Tokenizer project - Token42 (T42), a BEP-20 token on BNB Smart Chain Testnet

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages