Skip to content

Fix updateRequest in Verifier#422

Merged
daveroga merged 1 commit intomasterfrom
fix/verifier-update-request
Mar 3, 2026
Merged

Fix updateRequest in Verifier#422
daveroga merged 1 commit intomasterfrom
fix/verifier-update-request

Conversation

@daveroga
Copy link
Contributor

@daveroga daveroga commented Mar 2, 2026

No description provided.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 22578413876

Details

  • 1 of 1 (100.0%) changed or added relevant line in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 85.532%

Totals Coverage Status
Change from base Build 22564916612: 0.0%
Covered Lines: 3346
Relevant Lines: 3912

💛 - Coveralls

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the updateRequest function in Verifier.sol, where the stored creator field was incorrectly being overwritten with _msgSender() (the caller, i.e., the contract owner) instead of using the creator address supplied in the request struct. A version bump from 3.4.0 to 3.4.1 is also included.

Changes:

  • Verifier.sol: In _updateRequest, change creator: _msgSender() to creator: request.creator so the creator field is taken from the request calldata.
  • universal-verifier.test.ts: Add assertions verifying that requestStored.creator is correctly set both before and after an updateRequest call.
  • package.json / package-lock.json: Version bumped to 3.4.1.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
contracts/verifiers/Verifier.sol Core fix: _updateRequest now stores request.creator from calldata instead of _msgSender()
test/verifier/universal-verifier.test.ts Test assertions added to verify the creator field before and after updateRequest
contracts/package.json Version bumped from 3.4.0 to 3.4.1
contracts/package-lock.json Version aligned with package.json at 3.4.1 (was previously out of sync at 3.3.0)

Issues found:

  1. Critical bug — state inconsistency between RequestData.creator and _requestOwners: The _updateRequest function updates RequestData.creator in the _requests mapping, but it does not update the _requestOwners mapping maintained by RequestOwnership. After calling updateRequest, getRequest(requestId).creator and getRequestOwner(requestId) will return different addresses. Since onlyOwnerOrRequestOwner (used by setRequestOwner, disableRequest, enableRequest) relies on getRequestOwner(), the original request owner can still exercise those privileges even after the stored creator field has been changed.

  2. Security concern: Using request.creator from calldata allows the contract owner to set the creator field to any arbitrary address, including address(0). This is inconsistent with _setRequest, which always stores _msgSender() — it may be intentional, but it should be validated.

  3. Missing test coverage: The new test does not call getRequestOwner() after the update, so the above divergence between creator and _requestOwners goes undetected.

Files not reviewed (1)
  • contracts/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

validator: request.validator,
params: request.params,
creator: _msgSender()
creator: request.creator
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _updateRequest function stores request.creator directly from caller-supplied calldata, allowing the contract owner to set the creator field to any arbitrary address (including address(0) or unrelated accounts). In contrast, _setRequest always stores _msgSender() as the creator. If the intent is for updateRequest to preserve the original creator, the stored value from s._requests[request.requestId].creator should be used instead. If the intent is to allow the owner to change the creator, consider whether setting it to address(0) should be prevented, and whether the RequestOwnership._requestOwners mapping should also be updated accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines 559 to 570
function _updateRequest(
IVerifier.Request calldata request
) internal checkRequestExistence(request.requestId, true) {
VerifierStorage storage s = _getVerifierStorage();

s._requests[request.requestId] = IVerifier.RequestData({
metadata: request.metadata,
validator: request.validator,
params: request.params,
creator: _msgSender()
creator: request.creator
});
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When _updateRequest changes RequestData.creator, the _requestOwners mapping in RequestOwnership is NOT updated. This creates a state inconsistency: after calling updateRequest, getRequest(requestId).creator and getRequestOwner(requestId) can return different addresses. Since the onlyOwnerOrRequestOwner modifier (used by setRequestOwner, disableRequest, enableRequest) relies on getRequestOwner(), this inconsistency can cause confusing access control outcomes — the original request owner may still be able to manage the request even after the stored creator has changed.

The test at line 490 asserts requestStored.creator == owner.address after an update, but does not verify that getRequestOwner() is also updated, leaving this divergence untested.

Copilot uses AI. Check for mistakes.
Comment on lines 488 to +490
requestStored = await verifier.getRequest(requestId);
expect(requestStored.metadata).to.be.equal("metadata2");
expect(requestStored.creator).to.be.equal(owner.address);
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Check updateRequest" test does not verify that getRequestOwner(requestId) reflects the new creator after calling updateRequest. Since _requestOwners (used by getRequestOwner) is not updated by _updateRequest, getRequestOwner() will continue returning the original request owner (requestOwner.address) even though getRequest().creator now returns owner.address. A test case asserting the expected value of getRequestOwner() after the update would catch this divergence.

Copilot uses AI. Check for mistakes.
@daveroga daveroga merged commit 5356ce5 into master Mar 3, 2026
9 checks passed
@daveroga daveroga deleted the fix/verifier-update-request branch March 3, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants