Skip to content

Commit b779972

Browse files
committed
feat: ability to upgrade name and symbol
1 parent 31426f4 commit b779972

5 files changed

Lines changed: 46 additions & 10 deletions

File tree

script/DeployBase.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ contract DeployBase {
1717
*/
1818
function deploy(address registrar_, address migrationAdmin_) public virtual returns (address implementation_, address proxy_) {
1919
implementation_ = address(new MToken(registrar_, migrationAdmin_));
20-
proxy_ = address(new ERC1967Proxy(implementation_, abi.encodeCall(MToken.initialize, ())));
20+
proxy_ = address(new ERC1967Proxy(implementation_, abi.encodeCall(MToken.initialize, ("M by M0", "M"))));
2121
}
2222

2323
function _getExpectedMTokenImplementation(

src/MToken.sol

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pragma solidity 0.8.26;
55
import { ERC20Extended } from "../lib/common/src/ERC20Extended.sol";
66
import { UIntMath } from "../lib/common/src/libs/UIntMath.sol";
77
import { Migratable } from "../lib/common/src/Migratable.sol";
8+
import { Bytes32String } from "../lib/common/src/libs/Bytes32String.sol";
89

910
import { IERC20 } from "../lib/common/src/interfaces/IERC20.sol";
1011

@@ -16,12 +17,29 @@ import { IMToken } from "./interfaces/IMToken.sol";
1617
import { ContinuousIndexing } from "./abstract/ContinuousIndexing.sol";
1718
import { ContinuousIndexingMath } from "./libs/ContinuousIndexingMath.sol";
1819

20+
abstract contract MTokenStorageLayout {
21+
/// @custom:storage-location erc7201:m0.storage.MToken
22+
struct MTokenStorage {
23+
bytes32 name;
24+
bytes32 symbol;
25+
}
26+
27+
// keccak256(abi.encode(uint256(keccak256("m0.storage.MToken")) - 1)) & ~bytes32(uint256(0xff))
28+
bytes32 private constant _M_TOKEN_STORAGE_SLOT = 0x93466981a55ce4da70da67506024f05bd15faf7fdab908fab669c24c9fb04d00;
29+
30+
function _getMTokenStorage() internal pure returns (MTokenStorage storage $) {
31+
assembly {
32+
$.slot := _M_TOKEN_STORAGE_SLOT
33+
}
34+
}
35+
}
36+
1937
/**
2038
* @title MToken
21-
* @author M^0 Labs
39+
* @author M0 Labs
2240
* @notice ERC20 M Token living on other chains.
2341
*/
24-
contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
42+
contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable, MTokenStorageLayout {
2543
/* ============ Structs ============ */
2644

2745
/**
@@ -70,9 +88,9 @@ contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
7088
* @param registrar_ The address of the Registrar contract.
7189
* @param migrationAdmin_ The address of a migration admin.
7290
*/
73-
constructor(address registrar_, address migrationAdmin_) ContinuousIndexing() ERC20Extended("M by M^0", "M", 6) {
91+
constructor(address registrar_, address migrationAdmin_) ContinuousIndexing() ERC20Extended("M by M0", "M", 6) {
7492
_disableInitializers();
75-
93+
7694
if ((registrar = registrar_) == address(0)) revert ZeroRegistrar();
7795
if ((portal = RegistrarReader.getPortal(registrar_)) == address(0)) revert ZeroPortal();
7896
if ((migrationAdmin = migrationAdmin_) == address(0)) revert ZeroMigrationAdmin();
@@ -81,8 +99,13 @@ contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
8199
/* ============ Initializer ============ */
82100

83101
/// @inheritdoc IMToken
84-
function initialize() external initializer {
102+
function initialize(string memory name_, string memory symbol_) external initializer {
85103
_initialize();
104+
105+
MTokenStorage storage $ = _getMTokenStorage();
106+
107+
$.name = Bytes32String.toBytes32(name_);
108+
$.symbol = Bytes32String.toBytes32(symbol_);
86109
}
87110

88111
/* ============ Interactive Functions ============ */
@@ -138,6 +161,15 @@ contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
138161
}
139162

140163
/* ============ View/Pure Functions ============ */
164+
/// @inheritdoc IERC20
165+
function name() external view override(IERC20, ERC20Extended) returns (string memory name_) {
166+
return Bytes32String.toString(_getMTokenStorage().name);
167+
}
168+
169+
/// @inheritdoc IERC20
170+
function symbol() external view override(IERC20, ERC20Extended) returns (string memory symbol_) {
171+
return Bytes32String.toString(_getMTokenStorage().symbol);
172+
}
141173

142174
/// @inheritdoc IMToken
143175
function totalEarningSupply() public view returns (uint240 totalEarningSupply_) {

src/interfaces/IMToken.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ interface IMToken is IContinuousIndexing, IERC20Extended {
108108
*/
109109
function stopEarning(address account) external;
110110

111-
/// @notice Initializes the Proxy's storage.
112-
function initialize() external;
111+
/**
112+
* @notice Initializes the Proxy's storage.
113+
* @param name The name of the token.
114+
* @param symbol The symbol of the token.
115+
*/
116+
function initialize(string memory name, string memory symbol) external;
113117

114118
/**
115119
* @notice Performs an arbitrarily defined migration.

test/MToken.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ contract MTokenTests is TestUtils {
4444
_registrar.setPortal(_portal);
4545

4646
_implementation = new MTokenHarness(address(_registrar), _migrationAdmin);
47-
_mToken = MTokenHarness(address(new ERC1967Proxy(address(_implementation), abi.encodeCall(IMToken.initialize, ()))));
47+
_mToken = MTokenHarness(address(new ERC1967Proxy(address(_implementation), abi.encodeCall(IMToken.initialize, ("M by M0", "M")))));
4848

4949
_mToken.setLatestIndex(_expectedCurrentIndex = 1_100000068703);
5050
}

test/Migrate.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ contract MigrationTests is Test {
5454
);
5555

5656
_implementation = new MToken(_registrar, _migrationAdmin);
57-
_mToken = MToken(address(new ERC1967Proxy(address(_implementation), abi.encodeCall(IMToken.initialize, ()))));
57+
_mToken = MToken(address(new ERC1967Proxy(address(_implementation), abi.encodeCall(IMToken.initialize, ("M by M0", "M")))));
5858
}
5959

6060
function test_migration() external {

0 commit comments

Comments
 (0)