docs: document and accept the cross-contract double-funding gap (#52) - #67
Merged
chonilius merged 8 commits intoAug 17, 2026
Merged
Conversation
The section explained the independence tradeoff for compute_split duplication but was silent on a bigger consequence of the same design: escrow and milestones share no registry and never call each other, so nothing on-chain stops the same issue_id from being funded via both instruments at once.
…eFi#52 A fourth contract that both fund and allocate would call to claim an issue_id closes the double-funding gap on-chain, but reintroduces the cross-contract coupling this design otherwise deliberately avoids.
…ergeFi#52 A common DataKey convention is lower-coupling than a registry contract, but a shared type alone doesn't close the gap — two independently-deployed contracts still can't see each other's state without either a cross-contract call or a shared storage instance, either of which reintroduces the coupling this option was meant to avoid.
…geFi#52 mergefi-backend already watches every fund/allocate call as the system of record for GitHub state, giving it a natural, already- required view of which issue_ids are committed — closing the gap there needs no new contract or cross-contract coupling.
Accept the gap on-chain and push mitigation to mergefi-backend, which already watches every fund/allocate call. Stated explicitly as a conscious, accepted limitation of the independent-contracts design rather than a silent gap, per issue MergeFi#52's requirements.
Points at the README's new "Cross-contract double-funding" write-up so the accepted limitation is discoverable from the code, not only from the README.
…allocate() Points at the README's new "Cross-contract double-funding" write-up so the accepted limitation is discoverable from the code, not only from the README.
…geFi#52) Names the rejected on-chain registry option as the fallback path if backend-layer mitigation ever turns out to be insufficient, so the decision recorded in "Why three contracts instead of one" isn't treated as permanently closed.
|
@prodbycorne is attempting to deploy a commit to the chonilius' projects Team on Vercel. A member of the Team first needs to authorize it. |
4 tasks
Contributor
|
clean codes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
escrowandmilestonesshare no registry and never call each other, so nothing on-chain stops the sameissue_idfrom being funded viaescrow::fundand simultaneously allocated a budget viamilestones::allocatefor some release milestone — both can independently reachrelease/release_issueand pay out in full for what is, off-chain, one piece of work being compensated twice.Per the issue's own requirements, this evaluates the architectural options explicitly and makes an informed, documented decision rather than leaving the gap implicit:
DataKeyconvention — lower coupling, but doesn't actually close the gap by itself without a cross-contract call or shared storage instance (rejected).mergefi-backendalready watches everyfund/allocatecall as the system of record for GitHub state, so it's the natural place to refuse a second commitment for an already-committedissue_id(chosen).Changes:
escrow::fundandmilestones::allocatepointing back to that README section.No contract logic changes — this is a documentation-only decision, consistent with the acceptance criteria's "if the gap is accepted... the README explicitly names this as a known, accepted limitation" path.
Closes #52
Test plan
cargo fmt --check— cleancargo clippy --workspace --all-targets -- -D warnings— cleancargo test --workspace— 45 tests pass, no regressionscargo build --target wasm32v1-none --release— succeeds