@@ -4,72 +4,147 @@ pragma solidity >=0.8.30;
44
55contract ERC20Facet {
66
7- // ERC-6093: Custom errors for ERC-20
7+ /// @notice Thrown when an account has insufficient balance for a transfer or burn.
8+ /// @param _sender Address attempting the transfer.
9+ /// @param _balance Current balance of the sender.
10+ /// @param _needed Amount required to complete the operation.
811 error ERC20InsufficientBalance (address _sender , uint256 _balance , uint256 _needed );
12+
13+ /// @notice Thrown when the sender address is invalid (e.g., zero address).
14+ /// @param _sender Invalid sender address.
915 error ERC20InvalidSender (address _sender );
16+
17+ /// @notice Thrown when the receiver address is invalid (e.g., zero address).
18+ /// @param _receiver Invalid receiver address.
1019 error ERC20InvalidReceiver (address _receiver );
20+
21+ /// @notice Thrown when a spender tries to use more than the approved allowance.
22+ /// @param _spender Address attempting to spend.
23+ /// @param _allowance Current allowance for the spender.
24+ /// @param _needed Amount required to complete the operation.
1125 error ERC20InsufficientAllowance (address _spender , uint256 _allowance , uint256 _needed );
26+
27+ /// @notice Thrown when the approver address is invalid (e.g., zero address).
28+ /// @param _approver Invalid approver address.
1229 error ERC20InvalidApprover (address _approver );
30+
31+ /// @notice Thrown when the spender address is invalid (e.g., zero address).
32+ /// @param _spender Invalid spender address.
1333 error ERC20InvalidSpender (address _spender );
14-
34+
35+
36+ /// @notice Emitted when an approval is made for a spender by an owner.
37+ /// @param _owner The address granting the allowance.
38+ /// @param _spender The address receiving the allowance.
39+ /// @param _value The amount approved.
1540 event Approval (address indexed _owner , address indexed _spender , uint256 _value );
41+
42+ /// @notice Emitted when tokens are transferred between two addresses.
43+ /// @param _from Address sending the tokens.
44+ /// @param _to Address receiving the tokens.
45+ /// @param _value Amount of tokens transferred.
1646 event Transfer (address indexed _from , address indexed _to , uint256 _value );
1747
18- // Struct storage position defined by keccak256 hash
19- // of diamond storage identifier
48+ /// @dev Storage position determined by the keccak256 hash of the diamond storage identifier.
2049 bytes32 constant STORAGE_POSITION = keccak256 ("compose.erc20 " );
2150
22- // Storage defined using the ERC-8042 standard
23- // @custom:storage-location erc8042:compose.erc20
51+ /**
52+ * @dev ERC-8042 compliant storage struct for ERC20 token data.
53+ * @custom:storage-location erc8042:compose.erc20
54+ */
2455 struct ERC20Storage {
2556 string name;
2657 string symbol;
2758 uint8 decimals;
2859 uint256 totalSupply;
2960 mapping (address owner = > uint256 balance ) balanceOf;
30- mapping (address owner = > mapping (address spender = > uint256 allowance )) allowances;
61+ mapping (address owner = > mapping (address spender = > uint256 allowance )) allowances;
3162 }
3263
64+ /**
65+ * @notice Returns the ERC20 storage struct from the predefined diamond storage slot.
66+ * @dev Uses inline assembly to set the storage slot reference.
67+ * @return s The ERC20 storage struct reference.
68+ */
3369 function getStorage () internal pure returns (ERC20Storage storage s ) {
3470 bytes32 position = STORAGE_POSITION;
3571 assembly {
3672 s.slot := position
3773 }
3874 }
39-
75+
76+ /**
77+ * @notice Returns the name of the token.
78+ * @return The token name.
79+ */
4080 function name () external view returns (string memory ) {
4181 return getStorage ().name;
4282 }
4383
84+ /**
85+ * @notice Returns the symbol of the token.
86+ * @return The token symbol.
87+ */
4488 function symbol () external view returns (string memory ) {
4589 return getStorage ().symbol;
4690 }
4791
92+ /**
93+ * @notice Returns the number of decimals used for token precision.
94+ * @return The number of decimals.
95+ */
4896 function decimals () external view returns (uint8 ) {
4997 return getStorage ().decimals;
5098 }
5199
100+ /**
101+ * @notice Returns the total supply of tokens.
102+ * @return The total token supply.
103+ */
52104 function totalSupply () external view returns (uint256 ) {
53105 return getStorage ().totalSupply;
54106 }
55107
108+ /**
109+ * @notice Returns the balance of a specific account.
110+ * @param _account The address of the account.
111+ * @return The account balance.
112+ */
56113 function balanceOf (address _account ) external view returns (uint256 ) {
57114 return getStorage ().balanceOf[_account];
58115 }
59116
117+ /**
118+ * @notice Returns the remaining number of tokens that a spender is allowed to spend on behalf of an owner.
119+ * @param _owner The address of the token owner.
120+ * @param _spender The address of the spender.
121+ * @return The remaining allowance.
122+ */
60123 function allowance (address _owner , address _spender ) external view returns (uint256 ) {
61124 return getStorage ().allowances[_owner][_spender];
62125 }
63126
127+ /**
128+ * @notice Approves a spender to transfer up to a certain amount of tokens on behalf of the caller.
129+ * @dev Emits an {Approval} event.
130+ * @param _spender The address approved to spend tokens.
131+ * @param _value The number of tokens to approve.
132+ */
64133 function approve (address _spender , uint256 _value ) external {
65134 ERC20Storage storage s = getStorage ();
66135 if (_spender == address (0 )) {
67136 revert ERC20InvalidSpender (address (0 ));
68137 }
69138 s.allowances[msg .sender ][_spender] = _value;
70- emit Approval (msg .sender , _spender, _value);
139+ emit Approval (msg .sender , _spender, _value);
71140 }
72141
142+ /**
143+ * @notice Transfers tokens to another address.
144+ * @dev Emits a {Transfer} event.
145+ * @param _to The address to receive the tokens.
146+ * @param _value The amount of tokens to transfer.
147+ */
73148 function transfer (address _to , uint256 _value ) external {
74149 ERC20Storage storage s = getStorage ();
75150 if (_to == address (0 )) {
@@ -86,6 +161,13 @@ contract ERC20Facet {
86161 emit Transfer (msg .sender , _to, _value);
87162 }
88163
164+ /**
165+ * @notice Transfers tokens on behalf of another account, provided sufficient allowance exists.
166+ * @dev Emits a {Transfer} event and decreases the spender's allowance.
167+ * @param _from The address to transfer tokens from.
168+ * @param _to The address to transfer tokens to.
169+ * @param _value The amount of tokens to transfer.
170+ */
89171 function transferFrom (address _from , address _to , uint256 _value ) external {
90172 ERC20Storage storage s = getStorage ();
91173 if (_from == address (0 )) {
@@ -108,8 +190,13 @@ contract ERC20Facet {
108190 s.balanceOf[_to] += _value;
109191 }
110192 emit Transfer (_from, _to, _value);
111- }
112-
193+ }
194+
195+ /**
196+ * @notice Burns (destroys) a specific amount of tokens from the caller's balance.
197+ * @dev Emits a {Transfer} event to the zero address.
198+ * @param _value The amount of tokens to burn.
199+ */
113200 function burn (uint256 _value ) external {
114201 ERC20Storage storage s = getStorage ();
115202 uint256 balance = s.balanceOf[msg .sender ];
@@ -122,6 +209,12 @@ contract ERC20Facet {
122209 emit Transfer (msg .sender , address (0 ), _value);
123210 }
124211
212+ /**
213+ * @notice Burns tokens from another account, deducting from the caller's allowance.
214+ * @dev Emits a {Transfer} event to the zero address.
215+ * @param _account The address whose tokens will be burned.
216+ * @param _value The amount of tokens to burn.
217+ */
125218 function burnFrom (address _account , uint256 _value ) external {
126219 ERC20Storage storage s = getStorage ();
127220 uint256 currentAllowance = s.allowances[_account][msg .sender ];
@@ -135,8 +228,7 @@ contract ERC20Facet {
135228 unchecked {
136229 s.allowances[_account][msg .sender ] = currentAllowance - _value;
137230 s.balanceOf[_account] = balance - _value;
138- }
231+ }
139232 emit Transfer (msg .sender , address (0 ), _value);
140233 }
141-
142234}
0 commit comments