Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: high
Invalid

Arbitrary External Call in callExternalContract of MembershipERC1155

Issue:

The callExternalContract function allows an account with OWP_FACTORY_ROLE to execute arbitrary external calls, creating a significant security risk if this role is compromised. This issue is similar to the previously identified EXTERNAL_CALLER risk in MembershipFactory.

Location:

  • File: MembershipERC1155.sol

  • Function: callExternalContract

function callExternalContract(address contractAddress, bytes memory data) external payable onlyRole(OWP_FACTORY_ROLE) returns (bytes memory) {
(bool success, bytes memory returndata) = contractAddress.call{value: msg.value}(data);
require(success, "External call failed");
return returndata;
}

Exploit Code:

A malicious user with the OWP_FACTORY_ROLE could exploit callExternalContract to drain tokens from the MembershipERC1155 contract or perform unauthorized actions.

// Arbitrary call to transfer tokens
address targetERC20 = /* address of target ERC20 */;
bytes memory data = abi.encodeWithSignature("transfer(address,uint256)", msg.sender, 1000 ether);
membershipERC1155.callExternalContract(targetERC20, data);

Impact:

This could allow an attacker to drain funds or perform unauthorized operations, representing a high-security risk.

Tools Used

Manual review.

Recommendation:

Restrict callExternalContract to a set of whitelisted contracts or functions:

function callExternalContract(address contractAddress, bytes memory data) external payable onlyRole(OWP_FACTORY_ROLE) returns (bytes memory) {
require(isWhitelistedContract(contractAddress), "Unauthorized contract");
bytes4 selector = bytes4(data);
require(isAllowedFunction(selector), "Function not allowed");
(bool success, bytes memory returndata) = contractAddress.call{value: msg.value}(data);
require(success, "External call failed");
return returndata;
}
// Whitelist specific contracts or functions
function isWhitelistedContract(address contractAddress) internal view returns (bool) {
// Implement whitelist check logic
}
function isAllowedFunction(bytes4 selector) internal view returns (bool) {
// Implement function selector check
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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