Skip to content

docs: add technical flow diagrams for audit#56

Merged
shunkakinoki merged 2 commits intomasterfrom
docs/add-technical-flow-diagrams
Oct 15, 2025
Merged

docs: add technical flow diagrams for audit#56
shunkakinoki merged 2 commits intomasterfrom
docs/add-technical-flow-diagrams

Conversation

@shunkakinoki
Copy link
Collaborator

Summary

Comprehensive technical sequence diagrams documenting all Trails contract interactions, created in response to the October 15, 2025 audit call with Tim Sigl, Andy Lin, and Leonardo Passos.

Motivation

During the audit call, Tim requested:

"If you could create like a technical graphic or sequence diagram that shows how the contracts interact with each other, including contract and function names."

Andy also had questions about when injectAndCall() is used versus direct placeholder replacement in same-chain scenarios.

What's Included

6 Detailed Flow Diagrams:

  1. Cross-chain flow WITHOUT destination calldata - Simple bridge/swap scenarios
  2. Cross-chain flow WITH destination calldata - Balance injection for DeFi/NFT interactions
  3. Same-chain flow WITHOUT destination calldata - Simple token swaps
  4. Same-chain flow WITH destination calldata - Direct replacement optimization
  5. Origin chain failure & refund flow - Error handling on origin
  6. Destination chain failure & refund flow - Error handling on destination

Each Flow Documents:

Key Technical Details:

  • When and why injectAndCall() is used (cross-chain only)
  • Why same-chain flows use direct replacement (optimization)
  • TrailsRouterShim purpose (solves circular dependency for quotes)
  • Sentinel validation and onlyFallback mechanisms
  • Fee collection timing and refund locations
  • Error handling and recovery paths

Testing

Validated against:

  • Test scenarios in /packages/0xtrails/test/scenarios/testScenarios.ts
  • Existing contract implementations
  • Backend calldata construction logic

References

  • Audit Call: October 15, 2025
  • Commit Hash: ca3916e
  • Auditors: Tim Sigl, Andy Lin, Leonardo Passos

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Add comprehensive technical sequence diagrams documenting all Trails
contract interaction flows. Created in response to the October 15, 2025
audit call request for detailed contract interaction documentation.

Includes 6 detailed flows with Mermaid diagrams:
1. Cross-chain flow without destination calldata
2. Cross-chain flow with destination calldata (balance injection)
3. Same-chain flow without destination calldata
4. Same-chain flow with destination calldata (direct replacement)
5. Origin chain failure and refund flow
6. Destination chain failure and refund flow

Each flow includes:
- Call batch sequence numbering (Call #1, #2, #3, etc.)
- Key characteristics and use cases
- Detailed Mermaid sequence diagrams
- Implementation notes and semantics
- Contract addresses, function signatures, and call types

Addresses audit requests from Tim Sigl and Andy Lin regarding:
- Contract interaction details with function names
- When injectAndCall() is used vs direct replacement
- TrailsRouterShim purpose and call forwarding
- Sentinel validation and fallback mechanisms

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings October 15, 2025 15:00
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Adds comprehensive technical sequence diagrams and documentation for Trails contract interactions to support the October 15, 2025 audit, focusing on cross-chain, same-chain, and failure/refund scenarios.

  • Six mermaid sequence diagrams with call batch sequences and implementation notes
  • Clarifies when injectAndCall is used vs. direct replacement, sentinel mechanics, and fee/refund paths

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

participant OriginIntent as Origin Intent Address<br/>(Sequence v3 Wallet)
participant Shim as TrailsRouterShim
participant Router as TrailsRouter
participant MC3 as Multicall3<br/>(0xcA11...bde05)
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

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

The shortened Multicall3 address is incorrect. The canonical address is 0xcA11bde05977b3631167028862bE2a173976CA11, so the shortened form should end with ...CA11 (e.g., 0xcA11...CA11), not ...bde05.

Suggested change
participant MC3 as Multicall3<br/>(0xcA11...bde05)
participant MC3 as Multicall3<br/>(0xcA11...CA11)

Copilot uses AI. Check for mistakes.
Comment on lines +603 to +610
| Scenario | Origin Chain | Destination Chain | Injection Used? | Key Function |
|----------|--------------|-------------------|-----------------|--------------|
| Cross-chain simple transfer | Same as any flow | `sweep(user)` | No | N/A |
| Cross-chain with dest calldata | Same as any flow | `injectAndCall()` | **Yes** | Balance unknown until post-bridge |
| Same-chain simple swap | `pullAndExecute()` | N/A (same chain) | No | N/A |
| Same-chain with dest calldata | `pullAndExecute()` | N/A (same chain) | **No** | Backend replaces placeholder pre-intent |
| Origin failure | `refundAndSweep()` (fallback) | N/A (never bridged) | No | Refund + fee collection |
| Destination failure | Same as any flow | `sweep(user)` (after revert) | Attempted but failed | Refund on destination chain |
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

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

The table markup at the end renders incorrectly due to leading pipes in the header row of the original and an extra header bar in the diff shown earlier. Use standard Markdown table syntax with a single header row and alignment row. Example correction: Start the header with '|' once and remove any duplicated leading '|'.

Copilot uses AI. Check for mistakes.
- **Placeholder format:** We use `0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef` as a 32-byte marker
- **amountOffset:** Backend figures out where in the calldata the placeholder sits (byte offset)
- **Trust model:** User trusts the backend got the offset right. Wrong offset → `PlaceholderMismatch` → revert → refund
- **Native ETH:** No injection needed (amountOffset=0, placeholder=0). We just forward msg.value
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

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

This statement is overly broad. Forwarding msg.value is sufficient only when the target function derives the amount exclusively from msg.value; if the protocol function also encodes an amount parameter in calldata, you still need to inject/replace that argument. Please clarify that injection is skipped for ETH-only targets that do not require an amount parameter in calldata.

Suggested change
- **Native ETH:** No injection needed (amountOffset=0, placeholder=0). We just forward msg.value
- **Native ETH:** Injection is skipped only for ETH-only targets that do not require an amount parameter in calldata (amountOffset=0, placeholder=0). In these cases, we just forward msg.value. If the protocol function also encodes an amount parameter in calldata, injection is still required.

Copilot uses AI. Check for mistakes.
- **Fees on failure:** Yeah, we still collect fees even when things go wrong
- **Partial refunds:** If there's not enough balance for the full refund, we send what's there and emit `ActualRefund`
- **Atomicity:** Everything happens in one transaction—no way to double-spend
- **Sentinel scope:** The sentinel only lives for the transaction (tstore or sstore, depending on chain)
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

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

The 'only lives for the transaction' claim is accurate for transient storage (TSTORE/TLOAD) but not for an SSTORE fallback unless the code explicitly clears the slot. Please update this to specify the exact cleanup semantics when falling back to SSTORE (e.g., that the sentinel is reset/cleared at the end of the flow), or soften the statement to avoid implying transactional lifetime under SSTORE.

Suggested change
- **Sentinel scope:** The sentinel only lives for the transaction (tstore or sstore, depending on chain)
- **Sentinel scope:** The sentinel only lives for the transaction when using transient storage (tstore). For sstore fallback, the sentinel may persist unless explicitly cleared at the end of the flow.

Copilot uses AI. Check for mistakes.
continue; // Skip this call
}
```
- **Fees on failure:** Yeah, we still collect fees even when things go wrong
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

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

[nitpick] Suggest using neutral tone and clarifying the rule to aid auditability. For example: 'Fees are collected on the origin chain from any remaining balance during the fallback refund path.'

Suggested change
- **Fees on failure:** Yeah, we still collect fees even when things go wrong
- **Fees on failure:** Fees are collected on the origin chain from any remaining balance during the fallback refund path, even if the transaction fails.

Copilot uses AI. Check for mistakes.
Updated the technical flow diagrams documenting Trails contract interactions by removing specific references to the October 15, 2025 audit call and enhancing the clarity of various sections. Adjusted wording for better readability and streamlined the presentation of key characteristics and implementation notes across different scenarios.
@shunkakinoki shunkakinoki merged commit 1cdb0e6 into master Oct 15, 2025
1 check passed
@pkieltyka pkieltyka deleted the docs/add-technical-flow-diagrams branch October 23, 2025 10:33
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.

2 participants