From 1a6414a3d3db8c965b62bd1b4ca6f29452b5a5bc Mon Sep 17 00:00:00 2001 From: Ladebeze66 Date: Tue, 20 Oct 2026 14:53:40 +0200 Subject: [PATCH] verificationdemook --- docs/pedagogie/parcours-etape-par-etape.md | 4 +- tokenizerRendu/README.md | 27 +- tokenizerRendu/code/test/FGC42Forge.ts | 4 +- .../deployment/BSCSCAN_VERIFICATION.md | 48 ++ tokenizerRendu/deployment/FGC42Forge_flat.sol | 740 ++++++++++++++++++ tokenizerRendu/deployment/README.md | 7 + tokenizerRendu/deployment/addresses.json | 7 +- tokenizerRendu/documentation/README.md | 126 ++- 8 files changed, 940 insertions(+), 23 deletions(-) create mode 100644 tokenizerRendu/deployment/BSCSCAN_VERIFICATION.md create mode 100644 tokenizerRendu/deployment/FGC42Forge_flat.sol diff --git a/docs/pedagogie/parcours-etape-par-etape.md b/docs/pedagogie/parcours-etape-par-etape.md index 66ee7bd..0b80abd 100644 --- a/docs/pedagogie/parcours-etape-par-etape.md +++ b/docs/pedagogie/parcours-etape-par-etape.md @@ -19,8 +19,8 @@ | **1** | [etapes/etape-01-cadrage-wallet-testnet.md](etapes/etape-01-cadrage-wallet-testnet.md) | Décisions token + BSC testnet + tBNB | ✅ **Validée** (0,1 tBNB Telegram) | | **2** | [etapes/etape-02-init-hardhat.md](etapes/etape-02-init-hardhat.md) | Init Hardhat dans `tokenizerRendu/code/` | ✅ | | **3** | *(contrat + tests)* | `FGC42Forge.sol` + tests Mocha | ✅ | -| **4** | [etapes/etape-04-deploy-testnet.md](etapes/etape-04-deploy-testnet.md) | Dossier `deployment/` + deploy + BscScan | 🔄 **En cours** | -| **5** | *(à venir)* | `documentation/` utilisateur + README école (choix, adresse) | ⏳ | +| **4** | [etapes/etape-04-deploy-testnet.md](etapes/etape-04-deploy-testnet.md) | Dossier `deployment/` + deploy + BscScan | ✅ | +| **5** | `tokenizerRendu/documentation/README.md` | Doc utilisateur + choix techniques README | ✅ | | **6** | *(à venir)* | Démo minimale + préparation code review | ⏳ | | **7** | *(à venir)* | Bonus multisig (optionnel) | ⏳ | diff --git a/tokenizerRendu/README.md b/tokenizerRendu/README.md index 4110fc9..bc4e890 100644 --- a/tokenizerRendu/README.md +++ b/tokenizerRendu/README.md @@ -4,13 +4,15 @@ Projet 42 — création et déploiement d’un **token** sur blockchain publique > **Dépôt de rendu école** : ce dossier est la **racine** du dépôt Git Vogosphere. Pas de `docs/` ni de sujet traduit ici. +**Guide utilisateur (wallet, transfers, sécurité) :** [`documentation/README.md`](documentation/README.md) + ## État du projet | Élément | Statut | |---------|--------| | Smart contract (`code/`) | **FGC42Forge** + tests Hardhat | | Déploiement (`deployment/`) | **Testnet** — voir [`deployment/addresses.json`](deployment/addresses.json) | -| Documentation utilisateur (`documentation/`) | À compléter | +| Documentation utilisateur (`documentation/`) | **Rédigée** — [`documentation/README.md`](documentation/README.md) | ## Token @@ -20,19 +22,26 @@ Projet 42 — création et déploiement d’un **token** sur blockchain publique | **Symbole** | `FG42` | | **Standard** | **BEP-20** (BNB Smart Chain) — contrat Solidity via OpenZeppelin **`ERC20`** (même interface EVM ; BscScan affiche BEP-20 après deploy) | | **Réseau** | BNB Smart Chain **Testnet**, chainId `97` | +| **Supply** | 1 000 000 FG42 (18 décimales) — émission **unique** au deploy, **pas de mint** public ensuite | | **Adresse du contrat** | `0x0c76df26A1149fDc22C8f994975705271b070fF4` | -| **Explorer** | https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4 | +| **Explorer (contrat)** | https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4 | +| **Explorer (token)** | https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4 | | **Deployer** | `0xB6bE1878BfaF1FFC8503E752b1D733Ad7b93603c` (`FGC_account`) | +| **Source vérifiée (BscScan)** | Oui — détails : [`deployment/BSCSCAN_VERIFICATION.md`](deployment/BSCSCAN_VERIFICATION.md) | -## Choix techniques (à rédiger pour la soutenance) +## Choix techniques -Explique **pourquoi** tu as fait ces choix (le sujet l’exige) : +Résumé pour la soutenance (le sujet demande d’expliquer **pourquoi**) : -1. **Chaîne** : … -2. **Langage / outils** (Solidity, Hardhat, Remix, etc.) : … -3. **Bibliothèques** (ex. OpenZeppelin) : … -4. **Modèle économique** (supply, mint, decimals) : … -5. **Sécurité** (ownership, privilèges, ce qui est interdit) : … +1. **Chaîne — BNB Smart Chain Testnet (97)** : blockchain publique EVM alignée avec le partenaire BNB du sujet ; gas en **tBNB** via faucet ; preuve sur **BscScan** testnet sans argent réel. + +2. **Langage / outils — Solidity + Hardhat 3** : langage attendu pour les smart contracts BSC ; Hardhat pour compiler, tester (Mocha/ethers) et déployer (Ignition) de façon reproductible dans `code/` et `deployment/`. + +3. **Bibliothèques — OpenZeppelin `ERC20` + `Ownable`** : implémentation éprouvée du standard fongible ; sur BSC le jeton est qualifié **BEP-20** à l’explorer. Pas de réécriture manuelle de `transfer` / `balanceOf`. + +4. **Modèle économique** : **1 000 000** FG42, **18** décimales ; toute la supply mintée **une fois** au déployeur dans le constructeur ; **aucune** fonction `mint` publique → offre non diluable. + +5. **Sécurité** : compte de test dédié ; secrets dans `.env` local uniquement ; `owner` pour l’admin OpenZeppelin sans création de jetons supplémentaires ; pas de burn. Détail utilisateur : [`documentation/README.md`](documentation/README.md#4-sécurité-et-gouvernance). ## Structure du dépôt diff --git a/tokenizerRendu/code/test/FGC42Forge.ts b/tokenizerRendu/code/test/FGC42Forge.ts index 78db0bb..9c1b35f 100644 --- a/tokenizerRendu/code/test/FGC42Forge.ts +++ b/tokenizerRendu/code/test/FGC42Forge.ts @@ -1,5 +1,5 @@ -import { expect } from "chai"; -import { network } from "hardhat"; +import { expect } from "chai"; // pour les assertions +import { network } from "hardhat"; // pour les tests const { ethers } = await network.create(); diff --git a/tokenizerRendu/deployment/BSCSCAN_VERIFICATION.md b/tokenizerRendu/deployment/BSCSCAN_VERIFICATION.md new file mode 100644 index 0000000..bfe3cd6 --- /dev/null +++ b/tokenizerRendu/deployment/BSCSCAN_VERIFICATION.md @@ -0,0 +1,48 @@ +# Vérification du contrat sur BscScan (testnet) + +Fiche **correction / soutenance** : paramètres utilisés pour publier le source et prouver que le bytecode on-chain correspond au dépôt. + +## Statut + +| Champ | Valeur | +|-------|--------| +| **Vérifié** | Oui (2026-10-20) | +| **Contrat** | `FGC42Forge` | +| **Adresse** | `0x0c76df26A1149fDc22C8f994975705271b070fF4` | +| **Réseau** | BNB Smart Chain Testnet (chainId `97`) | + +## Transaction de création (deploy) + +| Champ | Valeur | +|-------|--------| +| **Tx hash** | `0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072` | +| **Lien** | https://testnet.bscscan.com/tx/0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072 | +| **Bloc** | `137872368` | +| **Deployer** | `0xB6bE1878BfaF1FFC8503E752b1D733Ad7b93603c` | + +## Paramètres BscScan « Verify & Publish » (succès) + +| Paramètre | Valeur retenue | +|-----------|----------------| +| **Méthode** | Solidity (**Single file**) | +| **Fichier source collé** | [`FGC42Forge_flat.sol`](FGC42Forge_flat.sol) (généré via `npx hardhat flatten contracts/FGC42Forge.sol`) | +| **Nom du contrat** | `FGC42Forge` | +| **Compilateur (liste BscScan)** | `v0.8.24+commit.89d56535` *(valeur affichée par BscScan après vérif réussie)* | +| **Optimisation** | **Activée** (`Yes` / `1`) | +| **Optimizer runs** | `200` | +| **Licence** | MIT | +| **Arguments du constructeur** | *(vide)* | + +> **Note dev :** le projet compile en local avec **Solidity 0.8.34** (Hardhat 3). Pour la vérification, BscScan a accepté la combinaison **single file aplati + optimizer 200**. En cas de nouvelle tentative, aligner **optimization Yes / 200** ; si échec « bytecode mismatch », essayer **Standard JSON Input** depuis `code/ignition/deployments/chain-97/build-info/solc-0_8_34-….json`. + +## Liens à montrer en évaluation + +- Contrat vérifié : https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4#code +- Token FG42 : https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4 + +## Régénérer le fichier aplati + +```bash +cd tokenizerRendu/code +npx hardhat flatten contracts/FGC42Forge.sol > ../deployment/FGC42Forge_flat.sol +``` diff --git a/tokenizerRendu/deployment/FGC42Forge_flat.sol b/tokenizerRendu/deployment/FGC42Forge_flat.sol new file mode 100644 index 0000000..ca24efd --- /dev/null +++ b/tokenizerRendu/deployment/FGC42Forge_flat.sol @@ -0,0 +1,740 @@ +// Sources flattened with hardhat v3.20.0 https://hardhat.org + +// SPDX-License-Identifier: MIT + +// File npm/@openzeppelin/contracts@5.6.1/utils/Context.sol + +// Original license: SPDX_License_Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } + + function _contextSuffixLength() internal view virtual returns (uint256) { + return 0; + } +} + + +// File npm/@openzeppelin/contracts@5.6.1/access/Ownable.sol + +// Original license: SPDX_License_Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * The initial owner is set to the address provided by the deployer. This can + * later be changed with {transferOwnership}. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +abstract contract Ownable is Context { + address private _owner; + + /** + * @dev The caller account is not authorized to perform an operation. + */ + error OwnableUnauthorizedAccount(address account); + + /** + * @dev The owner is not a valid owner account. (eg. `address(0)`) + */ + error OwnableInvalidOwner(address owner); + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the address provided by the deployer as the initial owner. + */ + constructor(address initialOwner) { + if (initialOwner == address(0)) { + revert OwnableInvalidOwner(address(0)); + } + _transferOwnership(initialOwner); + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + _checkOwner(); + _; + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view virtual returns (address) { + return _owner; + } + + /** + * @dev Throws if the sender is not the owner. + */ + function _checkOwner() internal view virtual { + if (owner() != _msgSender()) { + revert OwnableUnauthorizedAccount(_msgSender()); + } + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby disabling any functionality that is only available to the owner. + */ + function renounceOwnership() public virtual onlyOwner { + _transferOwnership(address(0)); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public virtual onlyOwner { + if (newOwner == address(0)) { + revert OwnableInvalidOwner(address(0)); + } + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Internal function without access restriction. + */ + function _transferOwnership(address newOwner) internal virtual { + address oldOwner = _owner; + _owner = newOwner; + emit OwnershipTransferred(oldOwner, newOwner); + } +} + + +// File npm/@openzeppelin/contracts@5.6.1/interfaces/draft-IERC6093.sol + +// Original license: SPDX_License_Identifier: MIT +// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol) + +pragma solidity >=0.8.4; + +/** + * @dev Standard ERC-20 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. + */ +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} + +/** + * @dev Standard ERC-721 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. + */ +interface IERC721Errors { + /** + * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-721. + * Used in balance queries. + * @param owner Address of the current owner of a token. + */ + error ERC721InvalidOwner(address owner); + + /** + * @dev Indicates a `tokenId` whose `owner` is the zero address. + * @param tokenId Identifier number of a token. + */ + error ERC721NonexistentToken(uint256 tokenId); + + /** + * @dev Indicates an error related to the ownership over a particular token. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param tokenId Identifier number of a token. + * @param owner Address of the current owner of a token. + */ + error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC721InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC721InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param tokenId Identifier number of a token. + */ + error ERC721InsufficientApproval(address operator, uint256 tokenId); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC721InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC721InvalidOperator(address operator); +} + +/** + * @dev Standard ERC-1155 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. + */ +interface IERC1155Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + * @param tokenId Identifier number of a token. + */ + error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC1155InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC1155InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param owner Address of the current owner of a token. + */ + error ERC1155MissingApprovalForAll(address operator, address owner); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC1155InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC1155InvalidOperator(address operator); + + /** + * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. + * Used in batch transfers. + * @param idsLength Length of the array of token identifiers + * @param valuesLength Length of the array of token amounts + */ + error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); +} + + +// File npm/@openzeppelin/contracts@5.6.1/token/ERC20/IERC20.sol + +// Original license: SPDX_License_Identifier: MIT +// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol) + +pragma solidity >=0.4.16; + +/** + * @dev Interface of the ERC-20 standard as defined in the ERC. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Returns the value of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the value of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves a `value` amount of tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 value) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets a `value` amount of tokens as the allowance of `spender` over the + * caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 value) external returns (bool); + + /** + * @dev Moves a `value` amount of tokens from `from` to `to` using the + * allowance mechanism. `value` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 value) external returns (bool); +} + + +// File npm/@openzeppelin/contracts@5.6.1/token/ERC20/extensions/IERC20Metadata.sol + +// Original license: SPDX_License_Identifier: MIT +// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol) + +pragma solidity >=0.6.2; + +/** + * @dev Interface for the optional metadata functions from the ERC-20 standard. + */ +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} + + +// File npm/@openzeppelin/contracts@5.6.1/token/ERC20/ERC20.sol + +// Original license: SPDX_License_Identifier: MIT +// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/ERC20.sol) + +pragma solidity ^0.8.20; + + + + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * + * TIP: For a detailed writeup see our guide + * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * The default value of {decimals} is 18. To change this, you should override + * this function so it returns a different value. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC-20 + * applications. + */ +abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { + mapping(address account => uint256) private _balances; + + mapping(address account => mapping(address spender => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * Both values are immutable: they can only be set once during construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the default value returned by this function, unless + * it's overridden. + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual returns (uint8) { + return 18; + } + + /// @inheritdoc IERC20 + function totalSupply() public view virtual returns (uint256) { + return _totalSupply; + } + + /// @inheritdoc IERC20 + function balanceOf(address account) public view virtual returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `value`. + */ + function transfer(address to, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, value); + return true; + } + + /// @inheritdoc IERC20 + function allowance(address owner, address spender) public view virtual returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, value); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Skips emitting an {Approval} event indicating an allowance update. This is not + * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `value`. + * - the caller must have allowance for ``from``'s tokens of at least + * `value`. + */ + function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { + address spender = _msgSender(); + _spendAllowance(from, spender, value); + _transfer(from, to, value); + return true; + } + + /** + * @dev Moves a `value` amount of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _transfer(address from, address to, uint256 value) internal { + if (from == address(0)) { + revert ERC20InvalidSender(address(0)); + } + if (to == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(from, to, value); + } + + /** + * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` + * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding + * this function. + * + * Emits a {Transfer} event. + */ + function _update(address from, address to, uint256 value) internal virtual { + if (from == address(0)) { + // Overflow check required: The rest of the code assumes that totalSupply never overflows + _totalSupply += value; + } else { + uint256 fromBalance = _balances[from]; + if (fromBalance < value) { + revert ERC20InsufficientBalance(from, fromBalance, value); + } + unchecked { + // Overflow not possible: value <= fromBalance <= totalSupply. + _balances[from] = fromBalance - value; + } + } + + if (to == address(0)) { + unchecked { + // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. + _totalSupply -= value; + } + } else { + unchecked { + // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. + _balances[to] += value; + } + } + + emit Transfer(from, to, value); + } + + /** + * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). + * Relies on the `_update` mechanism + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _mint(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(address(0), account, value); + } + + /** + * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. + * Relies on the `_update` mechanism. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead + */ + function _burn(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidSender(address(0)); + } + _update(account, address(0), value); + } + + /** + * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + * + * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. + */ + function _approve(address owner, address spender, uint256 value) internal { + _approve(owner, spender, value, true); + } + + /** + * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. + * + * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by + * `_spendAllowance` during the `transferFrom` operation sets the flag to false. This saves gas by not emitting any + * `Approval` event during `transferFrom` operations. + * + * Anyone who wishes to continue emitting `Approval` events on the `transferFrom` operation can force the flag to + * true using the following override: + * + * ```solidity + * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { + * super._approve(owner, spender, value, true); + * } + * ``` + * + * Requirements are the same as {_approve}. + */ + function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { + if (owner == address(0)) { + revert ERC20InvalidApprover(address(0)); + } + if (spender == address(0)) { + revert ERC20InvalidSpender(address(0)); + } + _allowances[owner][spender] = value; + if (emitEvent) { + emit Approval(owner, spender, value); + } + } + + /** + * @dev Updates `owner`'s allowance for `spender` based on spent `value`. + * + * Does not update the allowance value in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Does not emit an {Approval} event. + */ + function _spendAllowance(address owner, address spender, uint256 value) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance < type(uint256).max) { + if (currentAllowance < value) { + revert ERC20InsufficientAllowance(spender, currentAllowance, value); + } + unchecked { + _approve(owner, spender, currentAllowance - value, false); + } + } + } +} + + +// File contracts/FGC42Forge.sol + +// Original license: SPDX_License_Identifier: MIT +pragma solidity ^0.8.34; + + +/// @title FGC42Forge — jeton fongible pour BNB Smart Chain Testnet +/// @notice Standard **BEP-20** (exigé sur BSC) : même interface que l’ERC-20 sur l’EVM. +/// On importe OpenZeppelin `ERC20` ; après déploiement sur BSC, BscScan affiche un token BEP-20. +/// Phrase soutenance : « BEP-20 sur la chaîne, implémenté via ERC20 OpenZeppelin. » +contract FGC42Forge is ERC20, Ownable { + uint256 private constant INITIAL_SUPPLY = 1_000_000 * (10 ** 18); + + constructor() ERC20("FGC42Forge", "FG42") Ownable(msg.sender) { + _mint(msg.sender, INITIAL_SUPPLY); + } +} + diff --git a/tokenizerRendu/deployment/README.md b/tokenizerRendu/deployment/README.md index 13e5609..43a5631 100644 --- a/tokenizerRendu/deployment/README.md +++ b/tokenizerRendu/deployment/README.md @@ -40,3 +40,10 @@ Hardhat peut afficher une estimation de gas et demander une confirmation. ## Module Ignition Source : [`code/ignition/modules/FGC42Forge.ts`](../code/ignition/modules/FGC42Forge.ts) + +## Vérification BscScan + +Contrat **vérifié** sur testnet. Paramètres et liens pour la soutenance : + +→ [`BSCSCAN_VERIFICATION.md`](BSCSCAN_VERIFICATION.md) +→ Source aplati : [`FGC42Forge_flat.sol`](FGC42Forge_flat.sol) diff --git a/tokenizerRendu/deployment/addresses.json b/tokenizerRendu/deployment/addresses.json index adea8f4..ad67bc8 100644 --- a/tokenizerRendu/deployment/addresses.json +++ b/tokenizerRendu/deployment/addresses.json @@ -7,5 +7,10 @@ "address": "0x0c76df26A1149fDc22C8f994975705271b070fF4", "deployedAt": "2026-10-20", "deployer": "0xB6bE1878BfaF1FFC8503E752b1D733Ad7b93603c", - "explorer": "https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4" + "explorer": "https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4", + "creationTx": "0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072", + "creationBlock": 137872368, + "bscscanVerified": true, + "bscscanVerifiedAt": "2026-10-20", + "bscscanVerificationDoc": "deployment/BSCSCAN_VERIFICATION.md" } diff --git a/tokenizerRendu/documentation/README.md b/tokenizerRendu/documentation/README.md index 003fcc3..dba7a25 100644 --- a/tokenizerRendu/documentation/README.md +++ b/tokenizerRendu/documentation/README.md @@ -1,13 +1,121 @@ -# Documentation du token +# Documentation utilisateur — FGC42Forge (FG42) -Ce dossier est évalué en soutenance : il doit permettre de **comprendre** le token et de **l’utiliser** (wallet, transferts, rôle du token). +Ce document permet de **comprendre** le token et de **l’utiliser** (wallet, transferts) sans lire le code Solidity. -## Contenu à rédiger +> Documentation **évaluateur** : distincte du dossier `code/` (développement) et du dépôt de travail perso `docs/`. -1. **Présentation** — à quoi sert ce token (même dans un cadre pédagogique). -2. **Réseau et adresse** — lien vers l’explorer. -3. **Guide d’utilisation** — ajouter le token dans un wallet, effectuer un transfert. -4. **Sécurité et gouvernance** — owner, mint, limites connues. -5. **(Optionnel)** `WHITEPAPER.md` — vision et fonctionnalités sur 1–2 pages. +--- -Ce fichier est distinct de la documentation **dev** du dépôt perso (`docs/` à la racine du dépôt de travail). +## 1. Présentation + +**FGC42Forge** est un jeton **BEP-20** déployé sur **BNB Smart Chain Testnet** dans le cadre du projet 42 *Tokenizer*. + +| Élément | Valeur | +|---------|--------| +| **Nom** | FGC42Forge | +| **Symbole** | FG42 | +| **Standard** | BEP-20 (interface équivalente à l’ERC-20 sur l’EVM) | +| **Décimales** | 18 | +| **Offre totale** | 1 000 000 FG42 | + +**Rôle :** token de démonstration (tests, déploiement, wallet, explorateur de blocs). + +**Valeur :** aucune valeur monétaire réelle ; réseau de **test** uniquement. Le gas se paie en **tBNB**. + +**Offre et création de jetons :** les 1 000 000 FG42 ont été émis **une seule fois** lors du déploiement du contrat. Il n’existe **aucune fonction publique** pour en créer davantage après coup (*pas de mint*). Seuls les **transferts** entre comptes déplacent des FG42 déjà existants ; l’offre totale on-chain ne augmente pas. + +*FGC* : initiales du créateur du projet · **42** : contrainte du sujet · *Forge* : métaphore de la création du jeton au moment du deploy. + +--- + +## 2. Réseau et adresse + +| Paramètre | Valeur | +|-----------|--------| +| **Réseau** | BNB Smart Chain **Testnet** | +| **Chain ID** | `97` | +| **Monnaie gas** | tBNB | +| **Adresse du contrat** | `0x0c76df26A1149fDc22C8f994975705271b070fF4` | + +**Liens utiles :** + +- Page **contrat** : https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4 +- Page **token** (supply, holders, transfers) : https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4 + +Données structurées du déploiement : [`../deployment/addresses.json`](../deployment/addresses.json). + +### Contrat vérifié sur BscScan + +Le **code source** est publié sur l’explorateur (onglet **Contract** → code lisible). Utile en correction pour prouver que le déployé correspond au dépôt Git. + +| Élément | Détail | +|---------|--------| +| **Statut** | Vérifié (2026-10-20) | +| **Tx de création** | [`0xb6a0…4072`](https://testnet.bscscan.com/tx/0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072) | +| **Fiche technique complète** | [`../deployment/BSCSCAN_VERIFICATION.md`](../deployment/BSCSCAN_VERIFICATION.md) (compilateur, optimizer, fichier aplati) | + +### Configurer MetaMask (réseau) + +Si le réseau n’est pas déjà présent : + +| Champ | Valeur | +|-------|--------| +| Nom du réseau | BNB Smart Chain Testnet | +| RPC URL | `https://data-seed-prebsc-1-s1.binance.org:8545/` | +| Chain ID | `97` | +| Symbole | tBNB | +| Explorateur | `https://testnet.bscscan.com` | + +Obtenir du **tBNB** : faucet BNB Chain testnet ou canaux officiels (Telegram @bnbchain_official_bot, etc.). + +--- + +## 3. Guide d’utilisation + +### 3.1 Importer FG42 dans MetaMask + +1. Ouvrir MetaMask sur le réseau **BNB Smart Chain Testnet**. +2. Menu **Tokens** → **Importer des tokens** (*Import tokens*). +3. Coller l’**adresse du contrat** : + `0x0c76df26A1149fDc22C8f994975705271b070fF4` +4. Le symbole **FG42** et les **18** décimales se remplissent en général automatiquement → confirmer. + +Le compte qui a **déployé** le contrat détient initialement **1 000 000 FG42** (visible après import). Les autres comptes affichent **0** jusqu’à réception d’un transfer. + +### 3.2 Consulter le token sur BscScan + +1. Ouvrir la [page token](https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4). +2. Vérifier **Max Total Supply** : 1 000 000 FG42. +3. Onglet **Transfers** : historique des mouvements BEP-20. + +### 3.3 Effectuer un transfert (MetaMask) + +**Prérequis :** le compte émetteur possède des FG42 et un peu de **tBNB** pour le gas. + +1. MetaMask → actif **FG42** → **Envoyer** (*Send*). +2. Adresse du destinataire (autre compte test). +3. Montant (ex. `100` FG42) → confirmer la transaction. +4. Vérifier sur BscScan (onglet Transfers du token) et dans le wallet du destinataire (importer le token si besoin). + +**Note :** un transfer **ne crée pas** de nouveaux FG42 ; il déplace une partie de l’offre existante. + +--- + +## 4. Sécurité et gouvernance + +| Sujet | Comportement de FGC42Forge | +|-------|----------------------------| +| **Testnet** | Jeton fictif ; ne pas utiliser de fonds mainnet sur les comptes de démo. | +| **Supply** | Fixe à **1 000 000 FG42** après le deploy. | +| **Mint** | Aucune fonction publique pour augmenter l’offre. | +| **Burn** | Non implémenté dans ce contrat. | +| **Owner** | Le contrat utilise **OpenZeppelin `Ownable`** : une adresse `owner()` (le déployeur au lancement) peut gérer le rôle admin (ex. `transferOwnership`), mais **sans** pouvoir mint des FG42 supplémentaires via ce contrat. | +| **Clés privées** | Ne jamais partager seed phrase ni clé privée ; ne pas les committer dans Git. | + +Pour le modèle technique (Hardhat, OpenZeppelin, choix BSC), voir le [README racine](../README.md#choix-techniques). + +--- + +## 5. Whitepaper (optionnel) + +Un document `WHITEPAPER.md` peut compléter cette page (vision, limites, public cible). Non requis si cette documentation reste complète.