Skip to content

feat: cover runtime OAV injection, refresh registry, bump to 1.7.0 [eng-3209] - #34

Open
ajag408 wants to merge 3 commits into
mainfrom
eng-3209-erc4626-runtime-oav-injection
Open

feat: cover runtime OAV injection, refresh registry, bump to 1.7.0 [eng-3209]#34
ajag408 wants to merge 3 commits into
mainfrom
eng-3209-erc4626-runtime-oav-injection

Conversation

@ajag408

@ajag408 ajag408 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add regression coverage for context-injected ERC-4626 allocator vaults
  • verify supply, withdraw, and approval runtime injection paths
  • preserve fail-closed behavior for missing context, wrong tokens, and unknown addresses
  • refresh the embedded Shield registry from the production monorepo endpoint
  • bump @yieldxyz/shield from 1.5.0 to 1.7.0

1.7.0 is intentional because an unrelated 1.6.0 change is already in review.

QA Proof

injected-oav vault-registry

What Needs to Be QA'd in Staging

  • SUPPLY to a context-injected allocator vault is accepted
  • WITHDRAW from a context-injected allocator vault is accepted
  • APPROVAL of the base input token to the injected allocator is accepted
  • APPROVAL of an unrelated token is rejected
  • The same allocator transaction without context is rejected
  • Static embedded allocator vaults remain valid without context
  • Refreshed registry entries resolve normally

QA Team Notification

  • QA team has been notified to test in staging

Note

Medium Risk
Changes ERC-4626 vault whitelisting for supply, withdraw, and approvals; incorrect context handling could allow or block the wrong contract addresses.

Overview
ERC-4626 validation now whitelists runtime allocator vault (OAV) addresses supplied in ValidationContext.feeConfiguration[].allocatorVaultAddress, alongside the static registry. resolveVault and APPROVAL spenders accept injected addresses by reusing the yield’s base vault metadata (input token, decimals, pause flags); without context or for unrelated tx.to, behavior stays fail-closed (not whitelisted / wrong approval token).

Adds a regression test suite for context-injected SUPPLY, WITHDRAW, and APPROVAL paths and confirms static allocatorVaults still work with no context. Refreshes vault-registry.json (new/updated vaults and allocator lists) and bumps @yieldxyz/shield to 1.7.0.

Reviewed by Cursor Bugbot for commit 14074fc. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 14074fc. Configure here.

Comment thread src/validators/evm/erc4626/erc4626.validator.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: high. Left a non-blocking comment and did not approve; reviewers were already assigned, so none were added. Cursor Bugbot skipped with one unresolved finding, Cursor Security Agent did not finish in time, and runtime OAV whitelist injection is above the low-risk approval threshold.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agentic security review completed for this head. One high-severity finding: caller-supplied ValidationContext.feeConfiguration[].allocatorVaultAddress expands the ERC-4626 vault/spender allowlist on the same request path as the untrusted unsigned transaction.

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

Comment on lines +702 to +706
private getInjectedAllocatorVaults(context?: ValidationContext): Set<string> {
const injected = new Set<string>();
for (const fee of context?.feeConfiguration ?? []) {
if (isNonEmptyString(fee.allocatorVaultAddress)) {
injected.add(fee.allocatorVaultAddress.toLowerCase());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: HIGH

Caller-supplied ValidationContext.feeConfiguration[].allocatorVaultAddress is treated as a vault/spender allowlist. Any non-empty string is accepted with no registry membership, checksum, chain binding, or attestation. resolveVault and validateApproval then treat that address as a legitimate ERC-4626 vault and reuse the yield’s base-vault metadata (including inputTokenAddress).

The JSON validate path forwards request.context from the same payload as unsignedTransaction, so the party that builds the transaction can also expand Shield’s destination allowlist. That breaks the embedded-registry / zero-trust model: a wallet that forwards Yield/dApp context can be told that approve(attacker) on the vault input token, or deposit/mint/withdraw/redeem to that attacker, is valid.

Impact: Users who sign after a Shield isValid: true result can grant unlimited allowance or deposit the vault’s underlying asset to an attacker contract that the static registry would have rejected.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 14074fc. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional. context.feeConfiguration is trusted control-plane input, not end-user input. Embedded validation never takes context from the transaction submitter. Standalone/JSON callers must not forward dApp-supplied context; they should inject only their own OAV addresses. Remaining invariants still apply (from/owner/receiver = user, method + calldata checks). We’ll document this; schema address format is hardening only.

@ajag408
ajag408 added this pull request to stack #36 September 11, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant