-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathERC20BaseModule.sol
More file actions
162 lines (146 loc) · 5.89 KB
/
ERC20BaseModule.sol
File metadata and controls
162 lines (146 loc) · 5.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
/* ==== OpenZeppelin === */
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Technical === */
import {IERC20Allowance} from "../../../interfaces/technical/IERC20Allowance.sol";
import {IERC20BatchBalance} from "../../../interfaces/engine/ISnapshotEngine.sol";
/* ==== Tokenization === */
import {IERC3643ERC20Base} from "../../../interfaces/tokenization/IERC3643Partial.sol";
/**
* @title ERC20Base module
* @dev
*
* Contains ERC-20 base functions and extension
* Inherits from ERC-20
*
*/
abstract contract ERC20BaseModule is ERC20Upgradeable, IERC20Allowance, IERC3643ERC20Base, IERC20BatchBalance{
/* ============ Events ============ */
event Name(string indexed newNameIndexed, string newName);
event Symbol(string indexed newSymbolIndexed, string newSymbol);
/* ============ ERC-7201 ============ */
// keccak256(abi.encode(uint256(keccak256("CMTAT.storage.ERC20BaseModule")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ERC20BaseModuleStorageLocation = 0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00;
/* ==== ERC-7201 State Variables === */
struct ERC20BaseModuleStorage {
uint8 _decimals;
// We don't use ERC20Upgradeable name and private because we can not modify them
string _name;
string _symbol;
}
/* ============ Modifier ============ */
modifier onlyERC20AttributeManager() {
_authorizeERC20AttributeManagement();
_;
}
/* ============ Initializer Function ============ */
/**
* @dev Initializers: Sets the values for decimals.
*
* this value is immutable: it can only be set once during
* construction/initialization.
*/
function __ERC20BaseModule_init_unchained(
uint8 decimals_,
string memory name_,
string memory symbol_
) internal virtual onlyInitializing {
ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
$._decimals = decimals_;
$._symbol = symbol_;
$._name = name_;
}
/*//////////////////////////////////////////////////////////////
PUBLIC/EXTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/* ============ ERC-20 standard ============ */
/* ======== State functions ======= */
/**
* @notice Transfers `value` amount of tokens from address `from` to address `to`
* @custom:devimpl
* Emits a {Spend} event indicating the allowance spent.
* @inheritdoc ERC20Upgradeable
*
*/
function transferFrom(
address from,
address to,
uint256 value
) public virtual override(ERC20Upgradeable) returns (bool) {
bool result = ERC20Upgradeable.transferFrom(from, to, value);
// The result will be normally always true because OpenZeppelin will revert in case of an error
if (result) {
// emit Spend does not necessarily imply an allowance reduction
// This is the case if the allowance is set to uint256.max
emit Spend(from, _msgSender(), value);
}
return result;
}
/* ======== View functions ======= */
/**
*
* @notice Returns the number of decimals used to get its user representation.
* @inheritdoc ERC20Upgradeable
*/
function decimals() public view virtual override(ERC20Upgradeable) returns (uint8) {
ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
return $._decimals;
}
/**
* @notice Returns the name of the token.
*/
function name() public virtual override(ERC20Upgradeable) view returns (string memory) {
ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
return $._name;
}
/**
* @notice Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public virtual override(ERC20Upgradeable) view returns (string memory) {
ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
return $._symbol;
}
/* ============ Custom functions ============ */
/* ======== State Functions ======= */
/**
* @inheritdoc IERC3643ERC20Base
* @dev
*/
function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager {
ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
$._name = name_;
emit Name(name_, name_);
}
/**
* @inheritdoc IERC3643ERC20Base
*/
function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager {
ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
$._symbol = symbol_;
emit Symbol(symbol_, symbol_);
}
/* ======== View functions ======= */
/**
* @inheritdoc IERC20BatchBalance
*/
function batchBalanceOf(address[] calldata addresses) public view virtual override(IERC20BatchBalance) returns(uint256[] memory balances , uint256 totalSupply_) {
balances = new uint256[](addresses.length);
for(uint256 i = 0; i < addresses.length; ++i){
balances[i] = ERC20Upgradeable.balanceOf(addresses[i]);
}
totalSupply_ = ERC20Upgradeable.totalSupply();
}
/*//////////////////////////////////////////////////////////////
INTERNAL/PRIVATE FUNCTIONS
//////////////////////////////////////////////////////////////*/
/* ============ Access Control ============ */
function _authorizeERC20AttributeManagement() internal virtual;
/* ============ ERC-7201 ============ */
function _getERC20BaseModuleStorage() private pure returns (ERC20BaseModuleStorage storage $) {
assembly {
$.slot := ERC20BaseModuleStorageLocation
}
}
}