During pre-launch phase, only owner of contract can mint trays using buy().
Currently, anybody can call the external function buy() and mint trays during pre-launch phase as long as it does not exceed the maximum number of trays that can be minted pre-launch.
/Tray.sol
150: function buy(uint256 _amount) external {
151: uint256 startingTrayId = _nextTokenId();
152: if (prelaunchMinted == type(uint256).max) {
153: // Still in prelaunch phase
154: if (msg.sender != owner) revert OnlyOwnerCanMintPreLaunch();
155: if (startingTrayId + _amount - 1 > PRE_LAUNCH_MINT_CAP) revert MintExceedsPreLaunchAmount();
156: } else {
157: SafeTransferLib.safeTransferFrom(note, msg.sender, revenueAddress, _amount * trayPrice);
158: }
159: for (uint256 i; i < _amount; ++i) {
160: TileData[TILES_PER_TRAY] memory trayTiledata;
161: for (uint256 j; j < TILES_PER_TRAY; ++j) {
162: lastHash = keccak256(abi.encode(lastHash));
163: trayTiledata[j] = _drawing(uint256(lastHash));
164: }
165: tiles[startingTrayId + i] = trayTiledata;
166: }
167: _mint(msg.sender, _amount); // We do not use _safeMint on purpose here to disallow callbacks and save gas
168: }
154: if (msg.sender != owner) revert OnlyOwnerCanMintPreLaunch();
In the function buy, the owner variable is not set and check on buyer can be bypassed even though buyer is not the owner during prelaunch phase.
This means that anybody can call the external function buy and mint trays during pre-launch phase as long as it does not exceed the maximum number of trays that can be minted pre-launch. This is unintended as only the owner is allowed to mint trays during pre-launch.
Tools Used
Manual Review
Recommendation
Consider declaring owner variable and setting owner address in constructor
Lines of code
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol#L150-L168 https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol#L154
Vulnerability details
Impact
During pre-launch phase, only owner of contract can mint trays using
buy()
.Currently, anybody can call the external function
buy()
and mint trays during pre-launch phase as long as it does not exceed the maximum number of trays that can be minted pre-launch.Proof of Concept
Tray.sol#L150-L168 Tray.sol#L154
In the function
buy
, theowner
variable is not set and check on buyer can be bypassed even though buyer is not the owner during prelaunch phase.This means that anybody can call the external function
buy
and mint trays during pre-launch phase as long as it does not exceed the maximum number of trays that can be minted pre-launch. This is unintended as only the owner is allowed to mint trays during pre-launch.Tools Used
Manual Review
Recommendation
Consider declaring
owner
variable and settingowner
address in constructor