-
Notifications
You must be signed in to change notification settings - Fork 1
[FLOW-11] Use single mapping for tracking YieldVault user ownership
#42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
YieldVault user ownershipYieldVault user ownership
Pull Request ReviewSummaryThis PR removes the redundant ✅ Strengths
🔍 Code Quality ReviewImplementation Changes (cadence/contracts/FlowYieldVaultsEVM.cdc:1622-1642)Before: access(all) view fun getYieldVaultIdsForEVMAddress(_ evmAddress: String): [UInt64] {
return self.yieldVaultsByEVMAddress[evmAddress] ?? []
}After: access(all) view fun getYieldVaultIdsForEVMAddress(_ evmAddress: String): [UInt64] {
if \!self.yieldVaultOwnershipLookup.containsKey(evmAddress) {
return []
}
return self.yieldVaultOwnershipLookup[evmAddress]\!.keys
}Analysis:
Ownership Check Refactor (cadence/contracts/FlowYieldVaultsEVM.cdc:1636-1642)Before: access(all) view fun doesEVMAddressOwnYieldVault(evmAddress: String, yieldVaultId: UInt64): Bool {
if let ownershipMap = self.yieldVaultOwnershipLookup[evmAddress] {
return ownershipMap[yieldVaultId] ?? false
}
return false
}After: access(all) view fun doesEVMAddressOwnYieldVault(evmAddress: String, yieldVaultId: UInt64): Bool {
if \!self.yieldVaultOwnershipLookup.containsKey(evmAddress) {
return false
}
return self.yieldVaultOwnershipLookup[evmAddress]\!.containsKey(yieldVaultId)
}Analysis:
🔒 Security & Correctness✅ Cross-VM Synchronization IntactThe Solidity side (
|
| Operation | Before | After | Improvement |
|---|---|---|---|
| Create vault | O(1) array append + O(1) dict insert | O(1) dict insert only | ✅ Faster |
| Close vault | O(n) firstIndex + O(n) remove + O(1) dict remove |
O(1) dict remove only | ✅ Much faster for users with many vaults |
| Get vault IDs | O(1) array read | O(n) dict key extraction | |
| Check ownership | O(1) dict lookup | O(1) dict lookup | ➡️ Same |
The tradeoff (slower getYieldVaultIdsForEVMAddress for view queries) is acceptable because:
- View queries don't cost gas/computation credits
- Close operations (cadence/contracts/FlowYieldVaultsEVM.cdc:840) happen frequently and did cost real resources
- Most users won't have enough vaults for O(n) key extraction to be noticeable
✅ Best Practices Adherence
- ✅ Follows "single source of truth" principle
- ✅ Maintains backward-compatible public API
- ✅ Removes dead code (cadence/contracts/FlowYieldVaultsEVM.cdc:160, 785-791, 843-845)
- ✅ Updates inline documentation (cadence/contracts/FlowYieldVaultsEVM.cdc:723)
📝 Recommendations
1. Document Ordering Change (Minor)
Update the docstring for getYieldVaultIdsForEVMAddress:
/// @notice Gets all YieldVault Ids owned by an EVM address
/// @param evmAddress The EVM address string to query
/// @return Array of YieldVault Ids owned by the address (order not guaranteed)2. Consider Migration Note (Optional)
If this is deployed to an existing network with state, document that existing yieldVaultsByEVMAddress data will be abandoned (it's already redundant with yieldVaultOwnershipLookup, so no data loss).
3. Run Full Test Suite
Before merging, ensure:
./local/run_cadence_tests.sh
cd solidity && forge test🎯 Final Assessment
Status: ✅ APPROVE with minor suggestions
This is a well-executed optimization that addresses the performance issue identified in #26. The code is cleaner, more maintainable, and eliminates the O(n) removal issue for power users. The only consideration is documenting the ordering change, which is a non-breaking API modification.
Risk Level: Low
- No breaking changes to external APIs
- No security implications
- Maintains cross-VM synchronization correctness
- Well-isolated change affecting only Cadence contract state management
Great work! 🚀
Code ReviewThis PR addresses issue #26 by removing the redundant ✅ Strengths
🔍 Code QualityFlowYieldVaultsEVM.cdc:1624-1630 - The refactored access(all) view fun getYieldVaultIdsForEVMAddress(_ evmAddress: String): [UInt64] {
if !self.yieldVaultOwnershipLookup.containsKey(evmAddress) {
return []
}
return self.yieldVaultOwnershipLookup[evmAddress]!.keys
}✅ Clean implementation with proper nil-checking FlowYieldVaultsEVM.cdc:1636-1642 - The refactored access(all) view fun doesEVMAddressOwnYieldVault(evmAddress: String, yieldVaultId: UInt64): Bool {
if !self.yieldVaultOwnershipLookup.containsKey(evmAddress) {
return false
}
return self.yieldVaultOwnershipLookup[evmAddress]!.containsKey(yieldVaultId)
}✅ Improved from using FlowYieldVaultsEVM.cdc:843 - Vault closure cleanup: FlowYieldVaultsEVM.yieldVaultOwnershipLookup[evmAddr]!.remove(key: request.yieldVaultId)✅ Now O(1) instead of O(n) - directly addresses the security finding
|
YieldVault user ownershipYieldVault user ownership
Code Review - PR #42: Use single mapping for tracking YieldVault user ownershipOverviewThis PR successfully removes the redundant ✅ Strengths
|
PR Review: Use single mapping for tracking YieldVault user ownershipSummaryThis PR removes the redundant Code Quality ✅Strengths:
Observations:
Potential Issues
|
a60092f to
caa7c1d
Compare
Code Review for PR #42: Use single mapping for tracking YieldVault user ownershipSummaryThis PR successfully consolidates the dual ownership tracking system ( ✅ Strengths1. Storage Optimization
2. Consistent O(1) Operations
3. Comprehensive Documentation Updates
4. Backward Compatibility
|
Closes: #26