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)
- Deploy an escrow with M0 (
100 USDC).
- Fund with
100 USDC.
- 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)
- Deploy and fund the escrow.
- 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
- Deploy, fund, and dispute M0.
- 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):
- Call
update changing admin to a different address.
- 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.
- Deploy escrow without funding (balance =
0).
- Call
update changing approvers from [wallet_A] to [wallet_B].
- Attempt to fund passing the escrow with
approvers: [wallet_A] (old data) — must fail with EscrowPropertiesMismatch.
- Fund passing the escrow with
approvers: [wallet_B] (new data) — must succeed.
- Attempt to approve M0 with
wallet_A — must fail (no longer an approver).
- 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
- Deploy with M0 (
100 USDC), fund, approve, and release. Balance = 0.
- Call
manage-milestones to add M1 (50 USDC). Do not fund yet.
- With balance at
0, call update changing release_signers to [wallet_B].
- Fund M1 using the updated escrow data.
- Approve M1.
- Attempt to release M1 with
wallet_A (original release_signer) — must fail.
- 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.
Type: Edge Case Test
Priority: High
Area: Multi-Release V2 —
updateendpointAPI Access
Background
The contract blocks any property change in the following situations:
EscrowPropertiesMismatchEscrowOpenedForDisputeResolutionadmin— always returnsAdminAddressCannotBeChangedplatform— always returnsPlatformAddressCannotBeChangedThe only moment when
updatecan effectively modify properties is when the contract balance is exactly0.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
updateactually has an effect.Prerequisites
Scenarios
Scenario A: Update blocked while escrow holds funds (must fail)
100 USDC).100 USDC.updatechanging any field (description, roles, platform_fee).Expected:
EscrowPropertiesMismatcherror.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)
updatesending 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
updatewith any valid payload, including identical data.Expected:
EscrowOpenedForDisputeResolutionerror.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):updatechangingadminto a different address.updatechangingplatformto a different address.Expected:
AdminAddressCannotBeChangedandPlatformAddressCannotBeChangedrespectively.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
updatecan effectively change roles.0).updatechangingapproversfrom[wallet_A]to[wallet_B].approvers: [wallet_A](old data) — must fail withEscrowPropertiesMismatch.approvers: [wallet_B](new data) — must succeed.wallet_A— must fail (no longer an approver).wallet_Band complete the lifecycle.Question: Does the fund validation correctly detect the mismatch with old data? Is
wallet_Afully excluded after the update?Scenario F: Update roles between cycles, with balance = 0 between releases
100 USDC), fund, approve, and release. Balance =0.manage-milestonesto add M1 (50 USDC). Do not fund yet.0, callupdatechangingrelease_signersto[wallet_B].wallet_A(original release_signer) — must fail.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:
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.