Skip to content

Conversation

@ccashwell
Copy link
Member

This PR introduces @uniswap/the-compact-sdk, a comprehensive TypeScript SDK for interacting with The Compact v1 protocol. The SDK provides a fluent, type-safe API for creating compacts, processing claims, and managing resource locks with full EIP-712 signing support.

@socket-security
Copy link

socket-security bot commented Nov 18, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​types/​node@​24.9.1 ⏵ 24.10.1100 +110081 +195100
Updatedsane@​4.1.0 ⏵ 5.0.19910010082 +32100
Updatedsemantic-release@​25.0.1 ⏵ 25.0.29810010098 +1100

View full report

@socket-security
Copy link

socket-security bot commented Nov 18, 2025

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn Low
Dynamic module loading: npm jest-util

Location: Package overview

From: ?npm/[email protected]

ℹ Read more on: This package | This alert | What is dynamic require?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Packages should avoid dynamic imports when possible. Audit the use of dynamic require to ensure it is not executing malicious or vulnerable code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Ignoring alerts on:

View full report

@semgrep-code-uniswap
Copy link

Semgrep found 2 ssc-cee3e6d5-d7c8-4c35-9815-076aa1ebfd49 findings:

Risk: Affected versions of rollup are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

Manual Review Advice: A vulnerability from this advisory is reachable if you use Rollup to bundle JavaScript with import.meta.url and the output format is set to cjs, umd, or iife formats, while allowing users to inject scriptless HTML elements with unsanitized name attributes

Fix: Upgrade this library to at least version 2.79.2 at sdks/package-lock.json:38446.

Reference(s): GHSA-gcx4-mw62-g8wm, CVE-2024-47068

Semgrep found 4 ssc-aff5e8de-c638-4356-8a93-120597e35ce9 findings:

Risk: Affected versions of @babel/traverse, babel-traverse, @babel/plugin-transform-runtime, @babel/preset-env, @babel/helper-define-polyfill-provider, babel-plugin-polyfill-corejs2, babel-plugin-polyfill-corejs3, babel-plugin-polyfill-es-shims, and babel-plugin-polyfill-regenerator are vulnerable to Incomplete List Of Disallowed Inputs. An attacker can exploit a vulnerability in the internal Babel methods path.evaluate() or path.evaluateTruthy() by compiling specially crafted code, potentially resulting in arbitrary code execution during compilation. babel-traverse does not have a fix version. If you are using babel-traverse, switch to @babel/traverse.

Manual Review Advice: A vulnerability from this advisory is reachable if you use Babel to compile untrusted JavaScript

Fix: Upgrade this library to at least version 0.5.3 at sdks/package-lock.json:40336.

Reference(s): GHSA-67hx-6x53-jw92, CVE-2023-45133

@ccashwell ccashwell requested a review from a team as a code owner November 19, 2025 14:47
@ccashwell
Copy link
Member Author

@SocketSecurity ignore npm/[email protected]

@semgrep-code-uniswap
Copy link

Semgrep found 1 ssc-cee3e6d5-d7c8-4c35-9815-076aa1ebfd49 finding:

Risk: Affected versions of rollup are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

Manual Review Advice: A vulnerability from this advisory is reachable if you use Rollup to bundle JavaScript with import.meta.url and the output format is set to cjs, umd, or iife formats, while allowing users to inject scriptless HTML elements with unsanitized name attributes

Fix: Upgrade this library to at least version 2.79.2 at sdks/yarn.lock:10793.

Reference(s): GHSA-gcx4-mw62-g8wm, CVE-2024-47068

Semgrep found 2 ssc-aff5e8de-c638-4356-8a93-120597e35ce9 findings:

Risk: Affected versions of @babel/traverse, babel-traverse, @babel/plugin-transform-runtime, @babel/preset-env, @babel/helper-define-polyfill-provider, babel-plugin-polyfill-corejs2, babel-plugin-polyfill-corejs3, babel-plugin-polyfill-es-shims, and babel-plugin-polyfill-regenerator are vulnerable to Incomplete List Of Disallowed Inputs. An attacker can exploit a vulnerability in the internal Babel methods path.evaluate() or path.evaluateTruthy() by compiling specially crafted code, potentially resulting in arbitrary code execution during compilation. babel-traverse does not have a fix version. If you are using babel-traverse, switch to @babel/traverse.

Manual Review Advice: A vulnerability from this advisory is reachable if you use Babel to compile untrusted JavaScript

Fix: Upgrade this library to at least version 0.5.3 at sdks/yarn.lock:3726.

Reference(s): GHSA-67hx-6x53-jw92, CVE-2023-45133

ccashwell and others added 17 commits November 19, 2025 16:21
Fix witness typestring generation to omit final closing parenthesis
per The Compact spec, and add comprehensive tests validating complex
nested mandate structures like those used in Tribunal.

Changes:
- Fix buildWitnessTypestring to remove final closing paren
- Add 8 new tests for complex nested mandate types
- Test simple nested structures
- Test arrays in nested structures
- Test alphabetical sorting of multiple nested types
- Test Tribunal-like deeply nested structures with recursive refs
- Test full Tribunal-style mandate with 5 nested types
- Test bytes vs bytes32 in nested structures

Added comprehensive tests to validate SDK mandate encoding against Tribunal's
reference implementation:

- Nested custom types (Mandate_*)
- Arrays of nested types (Mandate_Fill[])
- Recursive type references (Mandate_Compact contains Mandate)
- Complex multi-level nesting (up to 5 nested types)
- Mandate typehash matches Tribunal's MANDATE_TYPEHASH constant
- Mandate_Fill typehash matches MANDATE_FILL_TYPEHASH
- Mandate_FillComponent typehash matches MANDATE_FILL_COMPONENT_TYPEHASH
- Mandate_Lock typehash matches MANDATE_LOCK_TYPEHASH
- All typehashes computed from typestrings match Tribunal contract constants
- Full Tribunal mandate encoding test case from TribunalBasicTest.sol
- Validates encoding structure (address + fillsHash = 64 bytes)
- Verifies hash computation is deterministic

These tests ensure the SDK's EIP-712 encoding is compatible with Tribunal's
on-chain mandate derivation functions (deriveMandateHash, deriveFillHash).
1) Add collectCoverageFrom and coverage reporting configuration to enable test coverage measurement. Includes text, text-summary, and HTML reporters.

2) Add complete parameter and return type documentation to all functions:

Price Curve Library:
- Document all parameters with types and descriptions
- Add return type documentation with value ranges
- Clarify scaling factor semantics (1e18 = neutral)
- Document error conditions and edge cases

Tribunal Builders:
- Full @param documentation for all builder methods
- Document chaining behavior with @returns
- Add class-level documentation with usage examples
- Document build() method preconditions

Convenience Functions:
- Complete parameter documentation for createSameChainFill()
- Full parameter docs for createCrossChainFill()
- Clarify cross-chain callback semantics

3) Add many new test cases for claim and batch claim functionality
…lders

Add extensive class-level and method documentation to all builder classes
in compact.ts and claim.ts, improving API discoverability and usage examples.
Replace basic README with comprehensive documentation covering all aspects
of the SDK usage, from installation to advanced patterns.
Add functional e2e tests using Supersim for testing against forked chains
…eriods

Add E2E test demonstrating batch compacts covering multiple resource locks
with different reset periods, processed in a single batch claim transaction.
Add a simpler `fromCompact()` method to BaseBatchClaimBuilder that pre-fills
sponsor, nonce, expires, and signature from a BatchCompact struct without
requiring ids/amounts upfront. This provides a cleaner API for building batch
claims:

Before:
  ClaimBuilder.batch(domain)
    .sponsor(compact.sponsor)
    .nonce(compact.nonce)
    .expires(compact.expires)
    .addClaim()...

After:
  ClaimBuilder.batch(domain)
    .fromCompact({ compact, signature })
    .addClaim()...

The method is inherited by BatchClaimBuilder, BatchMultichainClaimBuilder,
and ExogenousBatchMultichainClaimBuilder, providing consistent API across
all batch claim builder types.
Add calculators for various auction types including dutch and reverse dutch,
stepped schedules and multi-phase auctions, as well as utils for conversion,
evaluation and validation of curve configurations.

- Dutch auction curves (exact-in mode, decreasing prices)
- Reverse Dutch auction curves (exact-out mode, increasing prices)
- Stepped price calculators with configurable intervals
- Multi-phase auction builder supporting N phases
- Percentage conversion utilities
- Price evaluation and validation helpers
- Curve composition tools (concatenate, plateau, flat price)
@ccashwell ccashwell force-pushed the the-compact-sdk branch 3 times, most recently from 3b6f0e6 to 4aaae2c Compare November 19, 2025 21:56
Add the official Tribunal allocator mandate type definition to the SDK
and update README documentation with accurate usage examples.

1. **New TribunalMandate export** in src/builders/mandate.ts:
   - Complete type definition matching official Tribunal allocator structure
   - Includes all nested types: Fill, FillComponent, Lock, BatchCompact, RecipientCallback
   - Supports dynamic pricing via priceCurve arrays (compatible with price curve calculators)

2. **README improvements**:
   - Show integration with price curve calculators (createDutchAuction)
   - Demonstrate actual Tribunal mandate structure with all required fields
   - Document dynamic pricing, cross-chain fills, fill validation, callbacks
@ccashwell ccashwell marked this pull request as draft November 19, 2025 22:29
Update README to showcase the TribunalBuilder's fluent interface for
composing Tribunal mandates, rather than passing inline configuration
objects.

Example pattern:
```typescript
const mandate = TribunalBuilder.mandate()
  .adjuster(adjuster)
  .fill(f => f.chainId(1n).tribunal(addr).component(c => ...))
  .build()

const compact = await client.sponsor.compact()
  // ...
  .witness(TribunalMandate, mandate)
  .build()
```
Copy link
Collaborator

@marktoda marktoda left a comment

Choose a reason for hiding this comment

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

looks great! Love the builder pattern, feels quite clean.

Any thoughts for integration tests <> the code itself? for UniswapX we had a mini hardhat test suite that built orders with the SDK and executed them against the real solidity

* @returns This builder for chaining
* @throws {Error} If lockTag is not set before calling this method
*/
addTransfer(params: { recipient: `0x${string}`; amount: bigint }): this {
Copy link
Collaborator

Choose a reason for hiding this comment

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

probably worth doing some isAddress validation with viem or ethers just to check eip55 checksum and length etc. Presume there should be better types than 0xstring also

Copy link
Member Author

Choose a reason for hiding this comment

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

It is actually validated elsewhere but I am refactoring this file to be more DRY and will enforce Viem's Address or Hex types as appropriate

@ccashwell
Copy link
Member Author

looks great! Love the builder pattern, feels quite clean.

Any thoughts for integration tests <> the code itself? for UniswapX we had a mini hardhat test suite that built orders with the SDK and executed them against the real solidity

I do have some E2E integration tests in sdks/the-compact-sdk/src/e2e.test.ts which use the SDK to perform the entire lifecycle from deposit to claim under a handful of different scenarios, more to be done here for sure.

Refactored claim builder hierarchy to eliminate code duplication by introducing base classes:

- Created BaseClaimBuilder abstract class with common fields (sponsor, nonce, expires, allocatorData, sponsorSignature, witness)
- Created BaseSingleResourceClaimBuilder extending BaseClaimBuilder with single resource fields (id, allocatedAmount, claimants, lockTag) and methods (addTransfer, addConvert, addWithdraw, addClaimant, addComponent)
- Refactored SingleClaimBuilder to extend BaseSingleResourceClaimBuilder
- Refactored MultichainClaimBuilder to extend BaseSingleResourceClaimBuilder
- Refactored ExogenousMultichainClaimBuilder to extend MultichainClaimBuilder
- Refactored BaseBatchClaimBuilder to extend BaseClaimBuilder
Implemented allocator address to allocator ID conversion matching the Solidity IdLib.sol implementation:

- Added `allocatorToAllocatorId(allocator: Address): bigint` function to convert allocator addresses to uint96 allocator IDs
- Added internal `toCompactFlag(allocator: Address): number` helper to compute 4-bit compact flags using bit manipulation and population counting
- Compact flag represents the position of the first set bit in the upper 72 bits of the address, used for efficient storage
- Final allocator ID combines: upper 4 bits (compact flag) + lower 88 bits of address
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.

3 participants