feat: add AllowedRecipients and MaxTransactionValue policy rules#169
feat: add AllowedRecipients and MaxTransactionValue policy rules#169Sertug17 wants to merge 7 commits intoopen-wallet-standard:mainfrom
Conversation
Closes open-wallet-standard#153 - AllowedRecipients: deny transactions to unlisted addresses; contract creation (to=None) is always denied when this rule is present - MaxTransactionValue: deny transactions exceeding a per-tx wei cap; message signing and non-EVM chains pass through when value=None - CLI policy display updated for both new rule types - 8 new unit tests covering both rules, case-insensitivity, edge cases
|
@Sertug17 is attempting to deploy a commit to the MoonPay Team on Vercel. A member of the Team first needs to authorize it. |
njdawn
left a comment
There was a problem hiding this comment.
PR #169 — feat: add AllowedRecipients and MaxTransactionValue policy rules
Status: correctness risk
Findings:
High — ows/crates/ows-lib/src/policy_engine.rs: AllowedRecipients denies when transaction.to is None, which is fine for contract creation. But ows/crates/ows-lib/src/key_ops.rs currently builds API-key policy contexts with transaction.to and transaction.value unset, so this rule appears to deny all API-key signing rather than only blocking contract creation or disallowed recipients.
Medium — ows/crates/ows-core/src/policy.rs: Docs say these rules are effectively EVM sign_transaction rules, but evaluation is not explicitly gated by chain or operation type. Current behavior depends on how PolicyContext happens to be populated.
Low — ows/crates/ows-core/src/policy.rs: New rule variants do not appear to have serde round-trip coverage comparable to the older policy rule variants.
Testing:
Ran cargo test -p ows-lib policy_engine.
New recipient/value tests passed
Two existing executable-policy tests timed out after 5 seconds; they look unrelated to this change but leave an integration gap.
- key_ops: parse to/value from EVM tx bytes before policy evaluation so AllowedRecipients and MaxTransactionValue rules work correctly - policy_engine: gate AllowedRecipients and MaxTransactionValue to eip155 chains only — non-EVM chains pass through - policy: add serde round-trip tests for both new rule variants
|
Addressed all review findings: High — Medium — Low — Added serde round-trip tests for both |
… before test module
|
Also addressed the Cursor Bugbot finding: moved eval_allowed_recipients |
- key_ops: handle all EIP-2718 typed tx types (0x00-0x7f) in parse_evm_tx_fields, not just 0x01 and 0x02 - policy: add SigningOperation enum to PolicyContext so rules can distinguish sign_transaction from sign_message/sign_hash - policy_engine: gate AllowedRecipients and MaxTransactionValue to SignTransaction only — message signing always passes through - tests: add message_signing pass-through tests for both rules
|
Addressed both Cursor Bugbot findings: EIP-2718 typed tx bypass — parse_evm_tx_fields now strips the type Message signing blocked by AllowedRecipients — Added a |
…ard#169 - enforce_policy_and_decrypt_key: parse EVM to/value from tx bytes and set operation=SignTransaction (was SignMessage + None fields) - parse_evm_tx_fields: handle value fields > 16 bytes safely: values > u128::MAX treated as infinite, values > 32 bytes (invalid uint256) return sentinel string to trigger MaxTransactionValue denial
|
Addressed the two remaining Cursor Bugbot findings: enforce_policy_and_decrypt_key bypass — This function (used by Value truncation — parse_evm_tx_fields now handles large value
|
…ions EIP-4844 (0x03) and EIP-7702 (0x04) use EIP-1559 field layout where to=index 5 and value=index 6. Previously they fell through to legacy indices (3,4) which reads max_fee_per_gas as to and gas_limit as value, enabling a MaxTransactionValue policy bypass.
|
Fixed the remaining medium finding: EIP-4844/7702 field indices — parse_evm_tx_fields now correctly |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cdf3470. Configure here.
u128::MAX.to_string() is a valid parseable u128, so a max_wei set to u128::MAX would allow oversized values through. Replace with 'U128_OVERFLOW' sentinel which fails u128::parse() and triggers denial in eval_max_transaction_value.
|
Fixed the final Cursor Bugbot finding: u128::MAX.to_string() was replaced with "U128_OVERFLOW" sentinel for |
|
@njdawn All review findings and Cursor Bugbot issues have been addressed |

Closes #153
Summary
Adds two new declarative policy rules to the OWS policy engine:
AllowedRecipientsDeny transactions to addresses not in an explicit allowlist. Contract creation (
to = None) is always denied when this rule is present — same strict stance asAllowedTypedDataContractsfor missingverifyingContract.{ "type": "allowed_recipients", "addresses": ["0x742d35Cc6634C0532925a3b844Bc9e7595f2bD0C"] }MaxTransactionValueDeny transactions whose value exceeds a per-tx wei cap. Message signing and non-EVM chains pass through when
value = None.{ "type": "max_transaction_value", "max_wei": "100000000000000000" }Changes
ows-core/src/policy.rs— two newPolicyRulevariantsows-lib/src/policy_engine.rs— evaluation logic + 8 new unit testsows-cli/src/commands/policy.rs— CLI display for new rule typesTest plan
cargo fmtandcargo clippy -D warningscleanNote
Medium Risk
Adds new declarative enforcement in the signing path (including EVM transaction field parsing), which can deny previously-allowed transactions if parsing or rule configuration is incorrect. Changes touch core policy types and agent signing context, so compatibility and edge cases around tx formats/values are the main risk.
Overview
Adds two new declarative policy rules:
allowed_recipients(EVMsign_transactionrecipient allowlist, denying contract creation) andmax_transaction_value(per-tx wei cap).Extends
PolicyContextwithSigningOperationand updates agent signing to populateoperationplus parse EVMto/valuefrom raw tx bytes for policy evaluation; non-EVM chains and message signing bypass these rules. Updates CLIpolicy showoutput and adds unit tests covering serde and rule behavior (case-insensitive matching, contract creation denial, value limits, and pass-through cases).Reviewed by Cursor Bugbot for commit 0596edb. Bugbot is set up for automated code reviews on this repo. Configure here.