Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutable name and symbol (Opt 1) #8

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 26 additions & 0 deletions src/MetaMorpho.sol
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it ok to only allow strings of size < 32 ?

Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,32 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph

/* ONLY OWNER FUNCTIONS */

/// @inheritdoc IMetaMorphoBase
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// @inheritdoc IMetaMorphoBase
/// @inheritdoc IMetaMorphoBase
/// @dev The new name should have a size smaller than 32 bytes.

Note that we can't add this comment to the interface, because this is the interface of OZ in this case

function setName(string calldata newName) external onlyOwner {
uint256 length = bytes(newName).length;
if (length > 31) revert ErrorsLib.StringTooLong();

uint256 slot = ConstantsLib.NAME_SLOT;
bytes32 value = bytes32(bytes(newName));

assembly {
sstore(slot, or(value, mul(length, 2)))
}
}

/// @inheritdoc IMetaMorphoBase
function setSymbol(string calldata newSymbol) external onlyOwner {
uint256 length = bytes(newSymbol).length;
if (length > 31) revert ErrorsLib.StringTooLong();

uint256 slot = ConstantsLib.SYMBOL_SLOT;
bytes32 value = bytes32(bytes(newSymbol));

assembly {
sstore(slot, or(value, mul(length, 2)))
}
}

/// @inheritdoc IMetaMorphoBase
function setCurator(address newCurator) external onlyOwner {
if (newCurator == curator) revert ErrorsLib.AlreadySet();
Expand Down
6 changes: 6 additions & 0 deletions src/interfaces/IMetaMorpho.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ interface IMetaMorphoBase {
/// @dev Does not revert if there is no pending market removal.
function revokePendingMarketRemoval(Id id) external;

/// @notice Changes the name of the vault.
function setName(string memory newName) external;

/// @notice Changes the symbol of the vault.
function setSymbol(string memory newSymbol) external;

/// @notice Submits a `newGuardian`.
/// @notice Warning: a malicious guardian could disrupt the vault's operation, and would have the power to revoke
/// any pending guardian.
Expand Down
6 changes: 6 additions & 0 deletions src/libraries/ConstantsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ library ConstantsLib {

/// @dev The maximum fee the vault can have (50%).
uint256 internal constant MAX_FEE = 0.5e18;

/// @dev Storage slot of the name.
uint256 internal constant NAME_SLOT = 3;

/// @dev Storage slot of the symbol.
uint256 internal constant SYMBOL_SLOT = 4;
}
3 changes: 3 additions & 0 deletions src/libraries/ErrorsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,7 @@ library ErrorsLib {

/// @notice Thrown when all caps have been reached.
error AllCapsReached();

/// @notice Thrown when trying to set a string that is too long.
error StringTooLong();
}
48 changes: 48 additions & 0 deletions test/forge/DeploymentTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,54 @@ pragma solidity ^0.8.0;
import "./helpers/IntegrationTest.sol";

contract DeploymentTest is IntegrationTest {
function testSetName(string memory name) public {
vm.assume(bytes(name).length <= 31);

vm.prank(OWNER);
vault.setName(name);

assertEq(vault.name(), name);
}

function testSetNameNotOwner(string memory name) public {
vm.assume(bytes(name).length <= 31);

vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
vault.setName(name);
}

function testSetNameTooLong(string memory name) public {
vm.assume(bytes(name).length > 31);

vm.expectRevert(ErrorsLib.StringTooLong.selector);
vm.prank(OWNER);
vault.setName(name);
}

function testSetSymbolNotOwner(string memory name) public {
vm.assume(bytes(name).length <= 31);

vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
vault.setName(name);
}

function testSetSymbolTooLong(string memory symbol) public {
vm.assume(bytes(symbol).length > 31);

vm.expectRevert(ErrorsLib.StringTooLong.selector);
vm.prank(OWNER);
vault.setName(symbol);
}

function testSetSymbol(string memory symbol) public {
vm.assume(bytes(symbol).length <= 31);

vm.prank(OWNER);
vault.setSymbol(symbol);

assertEq(vault.symbol(), symbol);
}

function testDeployMetaMorphoAddresssZero() public {
vm.expectRevert(ErrorsLib.ZeroAddress.selector);
createMetaMorpho(OWNER, address(0), ConstantsLib.MIN_TIMELOCK, address(loanToken), "MetaMorpho Vault", "MMV");
Expand Down
Loading