NFTBridge
60,000 USDC
View results
Submission Details
Severity: low
Invalid

Use ByteArray::new() explicitly

Summary

erc721_metadata() uses the wrong Cairo type when returning a value from a match expression.

Vulnerability Details

erc721_metadata() returns Option<ERC721Metadata>, Option, so it can use it in a match expression in every call to erc721_metadata(). ERC721Metadata consists of 4 ByteArray fields:

#[derive(Drop)]
struct ERC721Metadata {
name: ByteArray,
symbol: ByteArray,
base_uri: ByteArray,
uris: Span<ByteArray>,
}

The function loops through all the token_ids and then tries to get the tokenURI of each one. If the token has it is retrieved via token_uri_from_contract_call(), this returns a ByteArray because these values are then stored in ERC721Metadata.uris, which is a Span<ByteArray>. But if the tokenId does not have a tokenURI, token_uri_from_contract_call() will return Option::None and the match expression will add "" to the ERC721Metadata.uris, which is not of type ByteArray.

When ERC721Metadata is returned, the base_uri is also set to "", which again is not a ByteArray.

fn erc721_metadata(
contract_address: ContractAddress,
token_ids: Option<Span<u256>>
) -> Option<ERC721Metadata> {
let erc721 = IERC721Dispatcher { contract_address };
let uris = match token_ids {
Option::Some(ids) => {
let mut out_uris = array![]; // array ByteArray
let mut i = 0_usize;
loop {
if i == ids.len() {
break ();
}
let token_id = *ids[i];
let token_uri =
match token_uri_from_contract_call(erc721.contract_address, token_id) {
Option::Some(uri) => uri,
Option::None => "",
};
out_uris.append(token_uri);
i += 1;
};
out_uris.span() // Span<ByteArray>
},
Option::None => {
array![].span()
}
};
Option::Some(
ERC721Metadata {
name: erc721.name(),
symbol: erc721.symbol(),
base_uri: "",
uris
}
)
}

Impact

The wrong Cairo type is passed when the code expects a ByteArray.

Tools Used

Manual Review

Recommendations

fn erc721_metadata(
contract_address: ContractAddress,
token_ids: Option<Span<u256>>
) -> Option<ERC721Metadata> {
let erc721 = IERC721Dispatcher { contract_address };
let uris = match token_ids {
Option::Some(ids) => {
let mut out_uris = array![]; // array ByteArray
let mut i = 0_usize;
loop {
if i == ids.len() {
break ();
}
let token_id = *ids[i];
let token_uri =
match token_uri_from_contract_call(erc721.contract_address, token_id) {
Option::Some(uri) => uri,
- Option::None => "",
+ Option::None => ByteArray::new(),
};
out_uris.append(token_uri);
i += 1;
};
out_uris.span() // Span<ByteArray>
},
Option::None => {
array![].span()
}
};
Option::Some(
ERC721Metadata {
name: erc721.name(),
symbol: erc721.symbol(),
- base_uri: "",
+ base_uri: ByteArray::new(),
uris
}
)
}
Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.