The Contract ERC721Bridgable cannot receive native token paid in for royalties.
Vulnerability Detail
The ERC721Bridgable::claimRoyalties function transfers native token or any token sent to the contract as royalties. But the contract does not have the functionality to accept native token.
POC
Add to the ./test/RiftTest.t.sol
function test_CannotRecieveEthOnL2() public {
// Set the royalty information for the L1 contract
l1NFT.setDefaultRoyalty(address(this), 1000);
// Create an ERC721 that implements ERC2981 for royalties
_bridgeNft(address(this), address(l1NFT), 0);
// Get our 'L2' address
Test721 l2NFT = Test721(riftBelow.l2AddressForL1Collection(address(l1NFT), false));
//Add some native token to ALICE to buy the nft
deal(ALICE, 10 ether);
deal(address(USDC), ALICE, 1000 ether);
uint256 startEthBalance0 = payable(address(this)).balance;
//ALice buys the Nft from the contract in the L2
l2NFT.transferFrom(address(this), ALICE, 0);
//retrieve royalty information for the L1 contract
(address reciever, uint256 royaltyAmount) = l1NFT.royaltyInfo(0, 3 ether);
vm.startPrank(ALICE);
//Alice pays 3 ether for the NFT, the royalty paid to the l2Nft contract is removed
(bool success,) = address(this).call{value: 3 ether - royaltyAmount}("");
require(success);
assertEq(reciever, address(this));
assertEq(address(this).balance, startEthBalance0 + 3 ether - royaltyAmount);
//The royalty is sent to the l2NFT contract but it reverts because the l2Nft contract cannot recieve token
(bool success1,) = address(l2NFT).call{value: royaltyAmount}("");
require(success1);
vm.stopPrank();
// Set up our tokens array to try and claim native ETH
address[] memory tokens = new address[](1);
tokens[0] = address(0);
// Capture the starting ETH of this caller
uint256 startEthBalance = payable(address(this)).balance;
// Make a claim call to an external recipient address
riftAbove.claimRoyalties(address(l1NFT), address(this), tokens, 0);
// Confirm that tokens have been sent to ALICE and not the caller
assertEq(payable(address(this)).balance, startEthBalance + royaltyAmount, "Invalid caller ETH");
assertEq(payable(ALICE).balance, 7 ether, "Invalid ALICE ETH");
}
Impact
Native token cannot be sent to the contract to be used in paying royalties.
heeze
Medium
Contract cannot receive native token
Summary
The Contract
ERC721Bridgable
cannot receive native token paid in for royalties.Vulnerability Detail
The
ERC721Bridgable::claimRoyalties
function transfers native token or any token sent to the contract as royalties. But the contract does not have the functionality to accept native token.POC Add to the ./test/RiftTest.t.sol
Impact
Native token cannot be sent to the contract to be used in paying royalties.
Code Snippet
In https://github.com/sherlock-audit/2024-08-flayer/blob/main/moongate/src/libs/ERC721Bridgable.sol#L157 the functionality for transferring native token from the
ERC721Bridgable
contract to the royalties owner/reciever on the L1 is implementedTool used
Manual Review
Recommendation
Add a receive or fallback function to the
ERC721Bridgable
contract