Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion script/DeployBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract DeployBase {
*/
function deploy(address registrar_, address migrationAdmin_) public virtual returns (address implementation_, address proxy_) {
implementation_ = address(new MToken(registrar_, migrationAdmin_));
proxy_ = address(new ERC1967Proxy(implementation_, abi.encodeCall(MToken.initialize, ())));
proxy_ = address(new ERC1967Proxy(implementation_, abi.encodeCall(MToken.initialize, ("M by M0", "M"))));
}

function _getExpectedMTokenImplementation(
Expand Down
42 changes: 37 additions & 5 deletions src/MToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pragma solidity 0.8.26;
import { ERC20Extended } from "../lib/common/src/ERC20Extended.sol";
import { UIntMath } from "../lib/common/src/libs/UIntMath.sol";
import { Migratable } from "../lib/common/src/Migratable.sol";
import { Bytes32String } from "../lib/common/src/libs/Bytes32String.sol";

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

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

abstract contract MTokenStorageLayout {
/// @custom:storage-location erc7201:m0.storage.MToken
struct MTokenStorage {
bytes32 name;
bytes32 symbol;
}

// keccak256(abi.encode(uint256(keccak256("m0.storage.MToken")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant _M_TOKEN_STORAGE_SLOT = 0x93466981a55ce4da70da67506024f05bd15faf7fdab908fab669c24c9fb04d00;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the hash been updated?
I get 0xeb521740570240fc3b71275bd090460409d92adf7cec95ba2df10066ee73c700 when calling the code above.


function _getMTokenStorage() internal pure returns (MTokenStorage storage $) {
assembly {
$.slot := _M_TOKEN_STORAGE_SLOT
}
}
}

/**
* @title MToken
* @author M^0 Labs
* @author M0 Labs
* @notice ERC20 M Token living on other chains.
*/
contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable, MTokenStorageLayout {
/* ============ Structs ============ */

/**
Expand Down Expand Up @@ -70,9 +88,9 @@ contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
* @param registrar_ The address of the Registrar contract.
* @param migrationAdmin_ The address of a migration admin.
*/
constructor(address registrar_, address migrationAdmin_) ContinuousIndexing() ERC20Extended("M by M^0", "M", 6) {
constructor(address registrar_, address migrationAdmin_) ContinuousIndexing() ERC20Extended("M by M0", "M", 6) {
_disableInitializers();

if ((registrar = registrar_) == address(0)) revert ZeroRegistrar();
if ((portal = RegistrarReader.getPortal(registrar_)) == address(0)) revert ZeroPortal();
if ((migrationAdmin = migrationAdmin_) == address(0)) revert ZeroMigrationAdmin();
Expand All @@ -81,8 +99,13 @@ contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
/* ============ Initializer ============ */

/// @inheritdoc IMToken
function initialize() external initializer {
function initialize(string memory name_, string memory symbol_) external initializer {
_initialize();

MTokenStorage storage $ = _getMTokenStorage();

$.name = Bytes32String.toBytes32(name_);
$.symbol = Bytes32String.toBytes32(symbol_);
}

/* ============ Interactive Functions ============ */
Expand Down Expand Up @@ -138,6 +161,15 @@ contract MToken is IMToken, ContinuousIndexing, ERC20Extended, Migratable {
}

/* ============ View/Pure Functions ============ */
/// @inheritdoc IERC20
function name() external view override(IERC20, ERC20Extended) returns (string memory name_) {
return Bytes32String.toString(_getMTokenStorage().name);
}

/// @inheritdoc IERC20
function symbol() external view override(IERC20, ERC20Extended) returns (string memory symbol_) {
return Bytes32String.toString(_getMTokenStorage().symbol);
}

/// @inheritdoc IMToken
function totalEarningSupply() public view returns (uint240 totalEarningSupply_) {
Expand Down
8 changes: 6 additions & 2 deletions src/interfaces/IMToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ interface IMToken is IContinuousIndexing, IERC20Extended {
*/
function stopEarning(address account) external;

/// @notice Initializes the Proxy's storage.
function initialize() external;
/**
* @notice Initializes the Proxy's storage.
* @param name The name of the token.
* @param symbol The symbol of the token.
*/
function initialize(string memory name, string memory symbol) external;

/**
* @notice Performs an arbitrarily defined migration.
Expand Down
2 changes: 1 addition & 1 deletion test/MToken.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ contract MTokenTests is TestUtils {
_registrar.setPortal(_portal);

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

_mToken.setLatestIndex(_expectedCurrentIndex = 1_100000068703);
}
Expand Down
2 changes: 1 addition & 1 deletion test/Migrate.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract MigrationTests is Test {
);

_implementation = new MToken(_registrar, _migrationAdmin);
_mToken = MToken(address(new ERC1967Proxy(address(_implementation), abi.encodeCall(IMToken.initialize, ()))));
_mToken = MToken(address(new ERC1967Proxy(address(_implementation), abi.encodeCall(IMToken.initialize, ("M by M0", "M")))));
}

function test_migration() external {
Expand Down
Loading