Skip to content

Collection to canvas mapping does not work for canvas one#

Medium Risk

There are multiple instances where canvas ID is being read from collectionToCanvas mapping. We can see that the only time this relation is set is in approveCanvas function in Core.sol and that it is set only for canvases that don't have isOne = true. That means, that for 1/1 canvases, ID must be retrieved another way. This makes sense, because all the 1/1 canvases are part of the same collection/contract. But in URI.sol there are 3 instances where that is ignored. This can result in wrong traits being included in the tokenURI for 1/1 canvases.

  1. Line 87 - getRefUri
  2. Line 244 - getSelectedTraits
  3. Line 411 - getTraitsAndParams

This is how canvas ID is retrieved in the above cases:

uint256 canvasId = ds.collectionToCanvas[collectionAddress];

This is how canvas ID is retrieved the right way in tokenURI function:

uint256 canvasId;
if (collectionAddress == ds.contractInfo.canvasOneAddress) canvasId = ds.canvasOne[tokenId];
else if (collectionAddress == ds.contractInfo.canvasOneCuratedAddress) canvasId = ds.canvasOneCurated[tokenId];
else canvasId = ds.collectionToCanvas[collectionAddress];

Recommendation#

Since you are already getting canvas ID the right way in tokenURI function and all the other functions are only called within it, just pass the canvas ID as an argument. This way the right ID will be used and also gas consumption will be lower, since there will be less reading from storage.