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

ERC20 token can be bridged from L2 to L1 due to missing ERC165 check

Summary

ERC20 tokens can be bridged from L2 → L1 due to missing ERC165 validation.

Vulnerability Details

When Bridge::depositTokens is called it’s verified that the tokens are of type ERC721 and if not bridging is not possible:

TokenUtil.sol

function detectInterface(
address collection
)
internal
view
returns (CollectionType)
{
bool supportsERC721 = ERC165Checker.supportsInterface(
collection,
type(IERC721).interfaceId
);
if (supportsERC721) {
return CollectionType.ERC721;
}
bool supportsERC1155 = ERC165Checker.supportsInterface(
collection,
type(IERC1155).interfaceId
);
if (supportsERC1155) {
return CollectionType.ERC1155;
}
revert UnsupportedTokenStandard();
}

The same check is missing in bridge::deposit_tokens and users can bridge ERC20 tokens and abuse the system. He should only bypass bridge::escrow_deposit_tokens:

fn escrow_deposit_tokens(
ref self: ContractState,
contract_address: ContractAddress,
from: ContractAddress,
token_ids: Span<u256>,
) {
let to = starknet::get_contract_address();
let erc721 = IERC721Dispatcher { contract_address };
let mut i = 0_usize;
loop {
if i == token_ids.len() {
break ();
}
let token_id = *token_ids[i];
erc721.transfer_from(from, to, token_id);
self.escrow.write((contract_address, token_id), from);
i += 1;
};
}

It is possible because transfer_from has the exact same function signature for both ERC20 and ERC721. The same rule applies to both Starknet and Mainnet. Then on L1 transaction is successfully executed and new ERC721 is deployed with tokenIds for the amount that the user has provided.

function withdrawTokens(
uint256[] calldata request
)
external
payable
returns (address)
{
...MORE CODE
if (collectionL1 == address(0x0)) {
if (ctype == CollectionType.ERC721) {
collectionL1 = _deployERC721Bridgeable(
req.name,
req.symbol,
req.collectionL2,
req.hash
);
// update whitelist if needed
_whiteListCollection(collectionL1, true);
} else {
revert NotSupportedYetError();
}
}
return collectionL1;
}

Impact

ERC20s can be bridged from Starknet to Mainnet due to missing the ERC165 check.

Tools Used

Manual Review

Recommendations

Add functionality that calls the supportInterface of the NFT that is going to be bridged.

Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational / Gas

Please, do not suppose impacts, think about the real impact of the bug and check the CodeHawks documentation to confirm: https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity A PoC always helps to understand the real impact possible.

Support

FAQs

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