fix(token-wrapper): key Allowance storage by (owner, spender, token_id) to support multi-asset allowances (#85) - #99
Closed
s6pa1rta3n-lab wants to merge 1 commit into
Closed
Conversation
…d) to prevent cross-asset overwrites
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 & Root Cause
Fixes #85.
Root Cause
In
contracts/token-wrapper/src/lib.rs,DataKey::Allowancewas previously keyed only by(Address, Address)representing(owner, spender). Thetoken_idparameter was not included in storage key definition, nor was it passed toapproveorallowance. Consequently, when an owner calledapprovefor the same spender across a second token asset, the new allowance record completely replaced and destroyed the existing allowance for the first token.Fix
DataKey::Allowancestorage enum toAllowance(Address, Address, Address)representing(owner, spender, token_id).TokenWrapper::approveto accepttoken_id: Addressas the third parameter (owner, spender, token_id, amount, expiry_ledger) and emit(owner, spender, token_id, amount, expiry_ledger)in theapprovedevent.TokenWrapper::allowanceto accepttoken_id: Address(owner, spender, token_id).TokenWrapper::transfer_fromto construct storage key using(from, spender, token_id).token-wrapperand added unit tests proving independent multi-asset allowances for the same(owner, spender)pair.Migration & Compatibility Decision
Decision: Pre-existing
(owner, spender)-keyed allowances are intentionally invalidated by the schema change and are treated as non-existent (returning default zero allowance upon query). Integrators must re-issueapprovecalls for each specific asset.Rationale:
DataKey::Allowance(owner, spender)with valueAllowance { amount, expiry_ledger }. Neither the key nor value record tracked whichtoken_idthe allowance was originally intended for.token_idwas never persisted in state, there is no unambiguous on-chain mechanism to map legacy allowance records to a particular token address without relying on off-chain indexing or arbitrary assumptions.approveinvocations guarantees security and correctness.Definition of Done Checklist
DataKey::Allowanceincludestoken_id;approve,allowance,transfer_fromall take/use it. (Addressed incontracts/token-wrapper/src/lib.rs)(owner, spender)pair are now independent (approving one doesn't touch the other). (Addedtest_approving_second_token_does_not_destroy_first_tokens_allowanceandtest_allowances_for_different_tokens_are_independent)test_approve_overwrites_previous_allowance, etc.) updated to reflect same-token overwrite is still the correct behavior — only cross-token overwrite was the bug. (Updated test suite and docstrings incontracts/token-wrapper/src/lib.rs)(owner, spender)-keyed allowances written out explicitly in the PR description. (Detailed above in Migration & Compatibility Decision section)cargo test --workspaceoutput pasted. (Pasted below)Test Suite Output (
cargo test --workspace)Payout Routing
0xF46C9F6d70C50BF81ef3588AB523a90a594a2F89GCL6OXAMLD75BMTINA6EMRUDWK5THQUSHMYNLSNBCJAPZJHNYJTUNIBC