Skip to content

Commit

Permalink
Allow reserve until tokenId to be updated
Browse files Browse the repository at this point in the history
  • Loading branch information
neokry committed Nov 1, 2023
1 parent 0418136 commit 1f2214b
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/token/IToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ interface IToken is IUUPS, IERC721Votes, TokenTypesV1, TokenTypesV2 {
/// @dev Reverts if the token is not reserved
error TOKEN_NOT_RESERVED();

/// @dev Reverts if the token reserve is being decreased
error CANNOT_DECREASE_RESERVE();

/// @dev Reverts if the token reserve cannot be changed
error CANNOT_CHANGE_RESERVE();

/// ///
/// FUNCTIONS ///
/// ///
Expand Down
17 changes: 17 additions & 0 deletions src/token/Token.sol
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,23 @@ contract Token is IToken, VersionedContract, UUPS, Ownable, ReentrancyGuard, ERC
return minter[_minter];
}

function setReservedUntilTokenId(uint256 newReservedUntilTokenId) external onlyOwner {
// Cannot change the reserve after any non reserved tokens have been minted
// Added to prevent making any tokens inaccessible
if (settings.mintCount > 0) {
revert CANNOT_CHANGE_RESERVE();
}

// Cannot decrease the reserve if any tokens have been minted
// Added to prevent collisions with tokens being auctioned / vested
if (settings.totalSupply > 0 && reservedUntilTokenId > newReservedUntilTokenId) {
revert CANNOT_DECREASE_RESERVE();
}

// Set the new reserve
reservedUntilTokenId = newReservedUntilTokenId;
}

/// @notice Set a new metadata renderer
/// @param newRenderer new renderer address to use
function setMetadataRenderer(IBaseMetadata newRenderer) external {
Expand Down
73 changes: 73 additions & 0 deletions test/Token.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -931,4 +931,77 @@ contract TokenTest is NounsBuilderTest, TokenTypesV1 {
token.ownerOf(i);
}
}

function test_SetReservedUntilTokenId(uint256 _startingReserve, uint256 _newReserve) public {
deployAltMock(_startingReserve);

vm.prank(founder);
token.setReservedUntilTokenId(_newReserve);
}

function test_SetReservedUntilTokenIdAfterMint(uint256 _startingReserve, uint256 _newReserve) public {
vm.assume(_startingReserve > 0 && _newReserve > _startingReserve);
deployAltMock(_startingReserve);

TokenTypesV2.MinterParams[] memory minters = new TokenTypesV2.MinterParams[](1);
TokenTypesV2.MinterParams memory p1 = TokenTypesV2.MinterParams({ minter: founder, allowed: true });
minters[0] = p1;

vm.prank(address(founder));
token.updateMinters(minters);

vm.prank(founder);
token.mintFromReserveTo(founder, 0);

vm.prank(founder);
token.setReservedUntilTokenId(_newReserve);
}

function testRevert_CannotSetReserveAfterDAOIsLaunched(uint256 _startingReserve, uint256 _newReserve) public {
deployAltMock(_startingReserve);

vm.prank(founder);
auction.unpause();

vm.prank(token.owner());
vm.expectRevert(abi.encodeWithSignature("CANNOT_CHANGE_RESERVE()"));
token.setReservedUntilTokenId(_newReserve);
}

function testRevert_CannotSetReserveAfterVestedMint(uint256 _startingReserve, uint256 _newReserve) public {
deployAltMock(_startingReserve);

TokenTypesV2.MinterParams[] memory minters = new TokenTypesV2.MinterParams[](1);
TokenTypesV2.MinterParams memory p1 = TokenTypesV2.MinterParams({ minter: founder, allowed: true });
minters[0] = p1;

vm.prank(address(founder));
token.updateMinters(minters);

vm.prank(founder);
token.mint();

vm.prank(token.owner());
vm.expectRevert(abi.encodeWithSignature("CANNOT_CHANGE_RESERVE()"));
token.setReservedUntilTokenId(_newReserve);
}

function testRevert_CannotReduceReserveAfterMint(uint256 _startingReserve, uint256 _newReserve) public {
vm.assume(_startingReserve > 0 && _startingReserve > _newReserve);
deployAltMock(_startingReserve);

TokenTypesV2.MinterParams[] memory minters = new TokenTypesV2.MinterParams[](1);
TokenTypesV2.MinterParams memory p1 = TokenTypesV2.MinterParams({ minter: founder, allowed: true });
minters[0] = p1;

vm.prank(address(founder));
token.updateMinters(minters);

vm.prank(founder);
token.mintFromReserveTo(founder, 0);

vm.prank(token.owner());
vm.expectRevert(abi.encodeWithSignature("CANNOT_DECREASE_RESERVE()"));
token.setReservedUntilTokenId(_newReserve);
}
}

0 comments on commit 1f2214b

Please sign in to comment.