-
Notifications
You must be signed in to change notification settings - Fork 2
Enable Vault Seeding via AssignDeposit #53
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
Conversation
…dress, for execution object. because AssignDeposit intentions do not have a 'from' vaultID
… deposits for AssignDeposit intention
.env.example
Outdated
| PROPOSER_VAULT_ID=1 | ||
|
|
||
| # Feature flag for automatically seeding new vaults with OyaTest Tokens | ||
| #VAULT_SEEDING=true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is VAULT_SEEDING commented out?
src/types/core.ts
Outdated
| token: string | ||
| to: number | ||
| amount: string | ||
| deposit_id?: number // Optional: present when deposit was selected at intention time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that deposit_id can be used at the protocol level—this feels like something individual nodes create as they recognize deposits, but don't mention the deposits in bundles until they're assigned, and different nodes may have different values for this field.
We could make this an optional data field that happens to contain a deposit_id if it would be useful to a particular node and that node knows how to handle it!
But also: This is a proof interface, not the AssignDeposit action itself, so it feels like the deposit_id should be in the data field for the AssignDeposit intention if anywhere.
| * - Selects deposits with sufficient remaining balance | ||
| * - Supports partial deposit assignments (can combine multiple deposits) | ||
| * - Determines submitter vault for nonce tracking: | ||
| * - If inputs have `from` field: uses that vault ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we will ever have a from field for AssignDeposit since the deposits haven't been added to a vault yet? Basically, nonces are not relevant for AssignDeposit intentions. If we have conflicting assignments, we use the one that was included in a bundle first, and ignore the others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More notes on this below: I think from can always be set to 0, the "protocol vault," since this is a special protocol-level action rather than an action in a user's vault.
|
|
||
| // Determine submitter vault for nonce tracking | ||
| // 1. If inputs have `from` field, use that (all inputs must have the same `from` value per validator) | ||
| // 2. If no `from` field, determine from controller by querying vaults |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See note above about how we will never have a from vault for assigning deposits, since unassigned deposits by definition are not yet in a nonce, and will also therefore never have a vault nonce.
| context.logger.info( | ||
| `Controller ${validatedController} does not control any vaults, using from=0 (no nonce update)` | ||
| ) | ||
| submitterVaultId = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can always use 0, the "protocol vault," as the from field, since from is required by the type. This is also a good pattern for the future—anything intentions that involve the higher-level protocol rather than assets in a specific vault could use the 0 as the from field.
Changes since feedback
|
Summary
This PR replaces transfer-based vault seeding with a single-step AssignDeposit approach. New vaults are seeded directly from the proposer’s on-chain deposits, and seeding logic robustly falls back to combining multiple deposits if a selected deposit becomes exhausted.
Changes
Feature flags and types
VAULT_SEEDINGto env schema and documented in.envsection of README and.env.example.EnvironmentConfigto includeVAULT_SEEDING.AssignDepositProofinsrc/types/core.tsfor publish-time proof typing.Seeding: construction, handling, publish-time effects
src/proposer.ts:createAndSubmitSeedingIntention(newVaultId)now builds anAssignDepositintention only ifVAULT_SEEDING=true.inputs.fromandinputs.data; they include{asset, amount, chain_id}only.proposerVaultNonce + 1; fee arrays empty.publishBundle():deposit_idin proof and sufficient remaining, assign and credit balance.deposit_idomitted, combine multiple deposits (findNextDepositWithAnyRemaining) until the full amount is assigned; errors include required vs available.intention.noncefor all non-CreateVault intentions (skipCreateVaultandfrom === 0).src/utils/intentionHandlers/AssignDeposit.ts:execution.from(submitter vault) frominputs.fromif provided; otherwise fromgetVaultsForController.findDepositWithSufficientRemaining; embedsdeposit_idin proof.src/utils/intentionHandlers/CreateVault.ts:createAndSubmitSeedingIntentionin try/catch; vault creation succeeds even if seeding scheduling fails.Deposit utilities
src/utils/deposits.ts:findNextDepositWithAnyRemaining(depositor, token, chain_id)to find the oldest deposit with any remaining.getTotalAvailableDeposits(depositor, token, chain_id)to sum remaining across all deposits.createAssignmentEventTransactional(...)remains the gatekeeper enforcing no over-assignment; setsassigned_atwhen fully assigned.Documentation
VAULT_SEEDING,PROPOSER_VAULT_ID) to the Environment Variables section.Tests
test/integration/deposits.db.test.ts:findNextDepositWithAnyRemainingandgetTotalAvailableDeposits(oldest-first behavior, partial assignment effects, zero when none).test/integration/seeding.assignDeposit.test.ts:Vault Seeding Flow
PROPOSER_ADDRESShas on-chain deposits for all tokens inSEED_CONFIGon the configured chain (default: Sepolia).CreateVault, ifVAULT_SEEDING=true, the node builds anAssignDepositintention withnonce = proposerVaultNonce + 1, noinputs.from/data, and outputs to the new vault; fee arrays are empty.inputs.fromis missing, the submitter vault is inferred from the controller.deposit_idis still sufficient, the assignment is recorded and the destination vault balance credited; otherwise the node falls back to combining multiple deposits until the amount is met or it errors with required vs available.intention.noncefor all non-CreateVault intentions (skippingfrom === 0), ensuring correct ordering and replay protection.