Skip to content

[TEST-02] Update Escrow: Real Limits of the Endpoint #86

Description

@armandocodecr

Type: Edge Case Test
Priority: High
Area: Multi-Release V2 — update endpoint


API Access

API credentials (API key and Testnet base URL) will be shared privately once this issue is assigned to you.
If you are interested in working on this test, leave a comment and we will assign it to you.


Background

The contract blocks any property change in the following situations:

  • While the escrow holds funds — returns EscrowPropertiesMismatch
  • While a dispute is active — returns EscrowOpenedForDisputeResolution
  • Changing admin — always returns AdminAddressCannotBeChanged
  • Changing platform — always returns PlatformAddressCannotBeChanged

The only moment when update can effectively modify properties is when the contract balance is exactly 0.

These scenarios test the real boundaries of that restriction: what errors are returned, whether the equality check behaves correctly, and which are the valid flows where update actually has an effect.


Prerequisites

  • Testnet API access (provided upon assignment)
  • Separate wallets for: admin, original approver (wallet_A), new approver (wallet_B), original release_signer, new release_signer, funder

Scenarios


Scenario A: Update blocked while escrow holds funds (must fail)

  1. Deploy an escrow with M0 (100 USDC).
  2. Fund with 100 USDC.
  3. Attempt to call update changing any field (description, roles, platform_fee).

Expected: EscrowPropertiesMismatch error.
Question: Is the error the same regardless of which field is changed, or does it vary?


Scenario B: Update with identical payload while escrow holds funds (no-op)

  1. Deploy and fund the escrow.
  2. Call update sending exactly the same values that are already stored — no changes at all.

Expected: Should pass validation since there is no mismatch.
Question: Does it work as a no-op or does it fail anyway? Are there any fields whose equality check behaves unexpectedly — for example, does a role list with the same addresses in a different order produce a mismatch?


Scenario C: Update blocked while a dispute is active

  1. Deploy, fund, and dispute M0.
  2. Attempt to call update with any valid payload, including identical data.

Expected: EscrowOpenedForDisputeResolution error.
Question: Does the dispute error take precedence over the funds error? Is it returned before the contract even checks whether the data changed?


Scenario D: Attempt to change admin or platform (must always fail)

With balance at 0 (freshly deployed, not yet funded):

  1. Call update changing admin to a different address.
  2. Call update changing platform to a different address.

Expected: AdminAddressCannotBeChanged and PlatformAddressCannotBeChanged respectively.
Question: Are the errors descriptive and distinguishable? Are they returned even when the balance is 0?


Scenario E: Update when balance = 0, then fund with the updated data

This is the only flow where update can effectively change roles.

  1. Deploy escrow without funding (balance = 0).
  2. Call update changing approvers from [wallet_A] to [wallet_B].
  3. Attempt to fund passing the escrow with approvers: [wallet_A] (old data) — must fail with EscrowPropertiesMismatch.
  4. Fund passing the escrow with approvers: [wallet_B] (new data) — must succeed.
  5. Attempt to approve M0 with wallet_A — must fail (no longer an approver).
  6. Approve M0 with wallet_B and complete the lifecycle.

Question: Does the fund validation correctly detect the mismatch with old data? Is wallet_A fully excluded after the update?


Scenario F: Update roles between cycles, with balance = 0 between releases

  1. Deploy with M0 (100 USDC), fund, approve, and release. Balance = 0.
  2. Call manage-milestones to add M1 (50 USDC). Do not fund yet.
  3. With balance at 0, call update changing release_signers to [wallet_B].
  4. Fund M1 using the updated escrow data.
  5. Approve M1.
  6. Attempt to release M1 with wallet_A (original release_signer) — must fail.
  7. Release M1 with wallet_B (new release_signer) — must succeed.

Question: Does the update between cycles work without any leftover state from the previous iteration? Do the new roles apply starting from the next funding call?


Results Report

After completing the tests, post a comment on this issue using the following format for each scenario:

Scenario [letter]:
- Steps executed:
- Expected result:
- Actual result:
- Error received (if applicable): [code + full message]
- Unexpected behavior? [yes/no — describe if yes]
- Relevant transaction hashes:
- Final escrow state (GET /:contractId):
- Result: Pass / Fail
- Bug description (if applicable):

Include the full response body of any call that fails with a different error than the one indicated, or that succeeds when it should have failed.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaign

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions