chore: refactor permission rules and add additional validation#7844
chore: refactor permission rules and add additional validation#7844jeffsmale90 wants to merge 8 commits intomainfrom
Conversation
4cd5553 to
df72ecd
Compare
1bc5acb to
a9450f5
Compare
…ion to ensure that permission data invariants are not violated.
…ype is self-describing and can be more easily tested in isolation. Add validation and test coverage for each permission type.
Plus minor changes: - Remove redundant amendment to ChecksumCaveat type - Remove unused ValidateDecodedPermission type - Fixes controller tests that expected the controller to self-report GatorPermissionsSnap id - Make decode functions internal, and rename to align with public interface
a9450f5 to
8700f23
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
packages/gator-permissions-controller/src/decodePermission/rules/erc20TokenPeriodic.test.ts
Show resolved
Hide resolved
…e ChecksumEnforcersByChainId type rather than explicitly declaring a new type
52df231 to
e1cb91e
Compare
| const startTime = hexToNumber(startTimeRaw); | ||
| const initialAmountBigInt = hexToBigInt(initialAmount); | ||
| const maxAmountBigInt = hexToBigInt(maxAmount); | ||
|
|
There was a problem hiding this comment.
Should we also add an amountPerSecond check here, similar to how it’s handled in native-token-stream ?
| }); | ||
|
|
||
| it('rejects when startTime is 0', () => { | ||
| const tokenAddress = '0xdddddddddddddddddddddddddddddddddddddddd' as Hex; |
There was a problem hiding this comment.
I think the valid 20-byte addresses should be 40 hex chars.
| const tokenAddress = '0xdddddddddddddddddddddddddddddddddddddddd' as Hex; | |
| const tokenAddress = '0xdddddddddddddddddddddddddddddddddddddd' as Hex; |
| }); | ||
|
|
||
| it('rejects when startTime is 0', () => { | ||
| const tokenAddress = '0xdddddddddddddddddddddddddddddddddddddddd' as Hex; |
There was a problem hiding this comment.
| const tokenAddress = '0xdddddddddddddddddddddddddddddddddddddddd' as Hex; | |
| const tokenAddress = '0xdddddddddddddddddddddddddddddddddddddd' as Hex; |
There was a problem hiding this comment.
Lol, I counted those ds very carefully!
| const [periodAmount, periodDurationRaw, startTimeRaw] = splitHex( | ||
| terms, | ||
| [32, 32, 32], | ||
| ); | ||
| const periodDuration = hexToNumber(periodDurationRaw); | ||
| const startTime = hexToNumber(startTimeRaw); | ||
|
|
||
| if (periodDuration <= 0) { | ||
| throw new Error( | ||
| 'Invalid native-token-periodic terms: periodDuration must be a positive number', | ||
| ); | ||
| } | ||
|
|
||
| if (startTime <= 0) { | ||
| throw new Error( | ||
| 'Invalid native-token-periodic terms: startTime must be a positive number', | ||
| ); | ||
| } | ||
|
|
||
| return { periodAmount, periodDuration, startTime }; |
There was a problem hiding this comment.
should we add periodAmount > 0 check here?
| splitHex(terms, [20, 32, 32, 32]); | ||
| const periodDuration = hexToNumber(periodDurationRaw); | ||
| const startTime = hexToNumber(startTimeRaw); | ||
|
|
There was a problem hiding this comment.
should we add periodAmount > 0 check here?
Explanation
It's critical that the
GatorPermissionController's Permission decoding logic is strict, and will not decode EIP-712 payload to a permission unless the payload exactly meets the expectations of that permission.This PR refactors the permission rules to be more self contained, and self describing. This allows each permission type's decoding rules to be more thoroughly tested in isolation. Validation and decoding logic is combined, as decoding is an implicit part of the validation step.
This PR also adds explicit validation of the "implicit" caveats for each permission type (
valueLtefor ERC20 permissions,exactCalldatafor native token permissions), where previously we were ensuring that they caveats exist, but not validating their terms.References
Checklist
Note
Medium Risk
Refactors core permission decoding/validation logic, which can cause previously accepted delegations to fail decoding if their caveat terms are malformed or slightly non-conforming. While largely additive hardening with extensive new tests, it touches security-sensitive permission interpretation paths.
Overview
Permission decoding is refactored to be rule-driven and stricter.
GatorPermissionsController.decodePermissionFromPermissionContextForOriginnow builds per-chain permission rules, selects the single matching rule by caveat/enforcer addresses (findRuleWithMatchingCaveatAddresses), and validates+decodes terms viavalidateAndDecodePermission, failing decoding on any invalid terms.Adds per-permission validation/decoding rules with expanded test coverage. Introduces
createPermissionRulesForContractsand rule modules for each supported permission type (native/erc20 stream/periodic and erc20 revocation), adding explicit validation for “implicit” caveats (ExactCalldataEnforcermust be0x,ValueLteEnforcermust be zero/32-bytes) plus stricter term length/field checks; replaces the olderidentifyPermissionByEnforcers/getPermissionDataAndExpiryapproach and updates/expands tests accordingly.Written by Cursor Bugbot for commit f956a28. This will update automatically on new commits. Configure here.