Omniscia Nuklai Audit
AcceptManuallyVerifier Manual Review Findings
AcceptManuallyVerifier Manual Review Findings
AMV-01M: Insecure Utilization of Fragment NFT
Type | Severity | Location |
---|---|---|
Logical Fault | AcceptManuallyVerifier.sol:L28-L30, L36-L38, L73-L75, L77, L91-L93, L95, L108-L110, L114 |
Description:
All referenced statements utilize the fragmentNFT
the caller specifies and utilize its getter functions to assess the address at which an IVerifierManager::resolve
call should be performed at.
This evaluation path is insecure as it is possible for a user to submit a malicious fragmentNFT
that passes the relevant access-control checks for the AcceptManuallyVerifier::onlyVerifierManager
/ AcceptManuallyVerifier::onlyDatasetOwner
and ultimately yields a valid IVerifierManager
where the VerifierManager::resolve
call is made to.
As the VerifierManager::resolve
function will evaluate the IFragmentNFT
to perform a call to via the dataset
and datasetId
entries it contains, a malicious contract can be utilized to trick a "manual" acceptance of a fragment ID.
Impact:
THe AcceptManuallyVerifier
can be completely bypassed by a carefully crafted IFragmentNFT
and IDatasetNFT
compliant malicious contract.
Example:
82/**83 * @notice Resolves a single contribution proposal84 * @dev Only callable by the Dataset owner.85 * Emits a {FragmentResolved} event.86 * @param fragmentNFT The address of the FragmentNFT contract instance87 * @param id The ID of the pending Fragment associated with the contribution proposal88 * @param accept Flag to indicate acceptance (`true`) or rejection (`true`)89 */90function resolve(address fragmentNFT, uint256 id, bool accept) external onlyDatasetOwner(fragmentNFT) {91 VerifierManager vm = VerifierManager(92 IDatasetNFT(IFragmentNFT(fragmentNFT).dataset()).verifierManager(IFragmentNFT(fragmentNFT).datasetId())93 );94 _pendingFragments[fragmentNFT].remove(id);95 vm.resolve(id, accept);96 emit FragmentResolved(fragmentNFT, id, accept);97}
Recommendation:
We advise the code to re-evaluate its approach, configuring the relevant addresses it is meant to invoke in an AcceptManuallyVerifier::constructor
, ensuring that the input fragmentNFT
is validated as a correct implementation by querying the IDatasetNFT::fragmentNFT
getter function with the relevant datasetId
.
Alleviation (fb50b5c39665f7df086b2de1fdbf93ba2d836bf9):
The AcceptManuallyVerifier
contract was updated to implement a constructor
that specifies the dataset
the verifier is valid for. All relevant statements have thus been updated to use the contract-configured dataset
value rather than the fragmentNFT
yielded one, permitting proper validation of the input fragmentNFT
and relevant configuration by correctly utilizing the constructor
specified dataset
contract.