Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Invalid

[H-6] Denial of Service (DoS) in `InheritanceManager::buyOutEstateNFT` due to NFT Creation via `InheritanceManager::contractInteractions()`

Description:

The contractInteractions() function allows arbitrary external contract calls, which can be used to create NFTs without properly assigning a value or asset to pay. If an NFT is created this way, it lacks a defined value and asset, leading to a permanent lock where beneficiaries try to use InheritanceManager::buyOutEstateNFT to adquired the NFT and they cannot, effectively causing a DoS issue.

function contractInteractions(
address _target,
bytes calldata _payload,
uint256 _value,
bool _storeTarget
) external nonReentrant onlyOwner {
(bool success, bytes memory data) = _target.call{value: _value}(_payload);
require(success, "interaction failed");
if (_storeTarget) {
interactions[_target] = data;
}
}
function createEstate(string memory description) external onlyInheritanceManager returns (uint256 itemID) {
uint256 ID = _incrementCounter();
_mint(msg.sender, ID);
_setTokenURI(ID, description);
return ID;
}

Impact:

High Severity

Likelihood: High – The issue arises when an NFT is created via contractInteractions(), bypassing the expected value and asset assignment.

DoS Attack Vector: Since buyOutEstateNFT() requires a defined value and asset, the NFT remains locked forever, making it impossible for beneficiaries to purchase it.

The function buyOutEstateNFT() will always revert when attempting to process a payment for an NFT with no assigned asset.

Proof of Concept:

function test_audit_createNft_from_contractInteractions_function() public {
bytes memory call = abi.encodeWithSignature(
"createEstate(string)",
"pepe"
);
vm.deal(address(im), 10e18);
vm.startPrank(owner);
im.contractInteractions(address(nft), call, 0, false);
console.log(im.getNftValue(1)); // ❌ This value will be zero
console.log(nft.ownerOf(1));
im.addBeneficiery(address(user1));
im.addBeneficiery(address(user2));
im.addBeneficiery(address(user3));
im.addBeneficiery(address(user4));
uint256 deadLine2 = im.getDeadline();
console.log(deadLine2);
vm.warp(deadLine2 + 90 days);
vm.stopPrank();
vm.startPrank(user2);
im.inherit();
usdc.mint(address(user1), 10e6);
usdc.approve(address(im), type(uint256).max);
im.buyOutEstateNFT(1); // 🔴 This call **will revert** due to missing asset
vm.stopPrank();
}

Logs:

InheritanceManager::buyOutEstateNFT(1)
0x0000000000000000000000000000000000000000::transferFrom(user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802], InheritanceManager: [0x88F59F8826af5e695B13cA934d6c7999875A9EeA], 0)
[Stop]
[Revert] SafeERC20FailedOperation(0x0000000000000000000000000000000000000000)

Recommended Mitigation:

Ensure that is not possible to create a NFT without value and asset properties through the contractInteractions() calling directly the NFT Factory. Or modifed the createEstate() function to give those properties from here.

Updates

Lead Judging Commences

0xtimefliez Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!