Skip to content

feat: inputSettlerBond#164

Draft
aalimsahin wants to merge 7 commits intoopenintentsframework:mainfrom
aalimsahin:bonded
Draft

feat: inputSettlerBond#164
aalimsahin wants to merge 7 commits intoopenintentsframework:mainfrom
aalimsahin:bonded

Conversation

@aalimsahin
Copy link
Copy Markdown

@aalimsahin aalimsahin commented Dec 26, 2025

Description

This PR aims to implement a new inputSettler contract. Unlike the Escrow model, the solver initiates the claim process by depositing a certain amount of bond after filling. If no one disputes, the order becomes final. A claim can be disputed by depositing a bond into the contract. In this case, the order is completed with the oracle result.

inputSettlerBond

Related Issues

#51

Third-Party Integration Checklist

⚠️ CRITICAL: All third-party integrations must follow strict dependency guidelines

  • No external library imports - Confirmed no new dependencies added to foundry.toml
  • Interfaces copied locally - All required interfaces copied to src/oracles/[oracle-type]/external/[protocol-name]/
  • Proper documentation - Each copied interface includes source header with:
    • Protocol name and version
    • Original source URL
    • Commit hash and copy date
    • List of any modifications made
  • Self-contained - Integration works with only repository code
  • Minimal interfaces - Only copied the specific methods/events needed

Additional Notes

The overall structure is still in the conceptual stage. It would be great to discuss the contract's flows. Currently, there is a fixed waiting period called DISPUTE_WAITING_TIME, but this may not be enough for all oracles or it may be too long. That's why it needs to be a different structure.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 26, 2025

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'enabled'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

Introduces two new Solidity contracts and an interface for managing input settlement with solver bonds. InputSettlerBond implements dual custody modes (bonded and escrow) with time-based finalization and refund mechanisms. SolverBondVault provides bond accounting per token with locking, unlocking, and penalization supporting multiple authorization schemes. Interface IInputSettlerBond defines the public API.

Changes

Cohort / File(s) Summary
Input Settlement Bond Contract
src/input/bond/InputSettlerBond.sol
New comprehensive contract implementing dual-mode input settlement: bonded flow (direct transfer to solver with solver signature), escrow flow (deposit via multiple authorization methods), with claim, refund, and finalize operations; includes order status tracking, solver authorization via EIP-712, time-based validation (TIME_TO_FILL), and bond interaction via SolverBondVault.
Solver Bond Vault Contract
src/input/bond/SolverBondVault.sol
New contract managing per-solver, per-token bond accounting with BondState struct tracking available and locked amounts; implements deposit, withdrawal, locking/unlocking, penalization/slashing flows; supports multiple input transfer mechanisms (direct, Permit2, ERC-3009) via internal helper functions; validates tokens and amounts.
Input Settler Bond Interface
src/interfaces/IInputSettlerBond.sol
New interface defining eight external function signatures: overloaded open/openFor variants, claim, finalise, refund, and orderIdentifier view function; establishes contract API for input settlement operations.

Sequence Diagrams

sequenceDiagram
    autonumber
    actor User
    participant ISB as InputSettlerBond
    participant SBV as SolverBondVault
    participant Token as ERC20 Token
    actor Solver
    
    rect rgb(200, 220, 255)
    note over User,Token: Bonded Settlement Flow
    User->>ISB: open(order, solver, solverSignature)
    ISB->>ISB: Validate solver signature (EIP-712)
    ISB->>SBV: Check solver bonds available
    ISB->>Token: Transfer inputs to solver
    ISB->>SBV: Lock solver bonds
    ISB->>ISB: Record OrderStatus.Open, solver, timestamp
    ISB-->>User: Emit Open event
    ISB-->>Solver: Emit Claimed event (implicit)
    end
    
    rect rgb(220, 255, 220)
    note over User,Token: Finalization Path (On-time)
    Solver->>ISB: finalise(order, solveParams)
    ISB->>ISB: Validate order status & timing
    ISB->>SBV: Unlock solver bonds
    ISB->>ISB: Update OrderStatus.Finalised
    ISB-->>Solver: Emit Finalised event
    end
    
    rect rgb(255, 220, 220)
    note over User,Token: Refund Path (Late/Default)
    User->>ISB: refund(order)
    ISB->>ISB: Validate order status
    alt Order in Open state
        ISB->>Token: Return inputs to user
    else Order in Claimed state
        ISB->>SBV: Slash solver bonds (basis points)
        ISB->>Token: Transfer slashed amount to user
    end
    ISB->>ISB: Update OrderStatus.Refunded
    ISB-->>User: Emit Refunded event
    end
Loading
sequenceDiagram
    autonumber
    actor User
    participant ISB as InputSettlerBond
    participant SBV as SolverBondVault
    participant Token as ERC20 Token
    actor Sponsor
    actor Solver
    
    rect rgb(200, 220, 255)
    note over User,Solver: Escrow Settlement Flow
    User->>ISB: openFor(order, sponsor, signature) <br/> [or open(order)]
    ISB->>ISB: Validate sponsor signature (if applicable)
    ISB->>Token: Transfer inputs into contract escrow
    ISB->>ISB: Record OrderStatus.Open, no solver yet
    ISB-->>User: Emit Open event
    end
    
    rect rgb(220, 255, 220)
    note over User,Solver: Solver Assignment (Optional variant)
    Sponsor->>ISB: openFor(order, sponsor, sig, solver, solverSig)
    ISB->>ISB: Validate both signatures
    ISB->>ISB: Store solver & timestamp
    ISB-->>Sponsor: Update orderSolver mapping
    end
    
    rect rgb(255, 240, 200)
    note over User,Solver: Claim Phase
    Sponsor->>ISB: claim(order)
    ISB->>ISB: Validate order Open status
    ISB->>Token: Transfer escrowed inputs to claimer
    ISB->>ISB: Update OrderStatus.Claimed, record solver/timestamp
    ISB-->>Sponsor: Emit Claimed event
    end
    
    rect rgb(255, 220, 220)
    note over User,Solver: Post-Claim Outcomes
    alt On-time finalization
        Solver->>ISB: finalise(order, solveParams)
        ISB->>ISB: Validate timing & status
        ISB->>ISB: Update OrderStatus.Finalised
        ISB-->>Solver: Emit Finalised event
    else Late/refund request
        User->>ISB: refund(order)
        ISB->>ISB: Validate OrderStatus.Claimed
        ISB->>SBV: Slash solver bonds (if solver assigned)
        ISB->>Token: Transfer penalty or return to user
        ISB->>ISB: Update OrderStatus.Refunded
        ISB-->>User: Emit Refunded event
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 With bonds of trust and vaults so deep,
We settle orders, promises to keep,
Through escrow paths and solver's care,
With EIP-712 signatures to spare—
No reentrancy shall pass this year! 🔐

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: inputSettlerBond' is clear and specific, directly referencing the main component added in this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed PR description includes a clear overview of the inputSettlerBond contract, relates to issue #51, and completes the third-party integration checklist with all items marked.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aalimsahin aalimsahin marked this pull request as draft December 26, 2025 17:22
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/input/bond/InputSettlerBond.sol (1)

545-563: Potential issue: _transferInputs uses safeTransferFrom even for self-transfers.

Unlike _lockBondsAndTransfer (lines 234-236) which handles the sender == address(this) case with safeTransfer, _transferInputs always uses safeTransferFrom. When called with sender = address(this) (as in escrow refunds at line 470), this may fail for tokens that don't allow self-transfers without approval.

🔎 Proposed fix
 function _transferInputs(
     address sender,
     address to,
     uint256[2][] calldata inputs
 ) internal {
     uint256 inputsLength = inputs.length;

     for (uint256 i = 0; i < inputsLength; ++i) {
         uint256[2] calldata input = inputs[i];

         address token = input[0].validatedCleanAddress();
         uint256 amount = input[1];

         _validateZeroAmount(amount);
         _validateToken(token);

-        IERC20(token).safeTransferFrom(sender, to, amount);
+        if (sender == address(this))
+            IERC20(token).safeTransfer(to, amount);
+        else IERC20(token).safeTransferFrom(sender, to, amount);
     }
 }
🧹 Nitpick comments (3)
src/input/bond/SolverBondVault.sol (1)

338-345: Consider handling receiveWithAuthorization return value explicitly.

The low-level call is used to attempt ERC-3009 authorization, with a silent fallback to the multi-signature path on failure. While this works, consider logging or differentiating the failure reason to aid debugging. The current behavior is functional but could mask unexpected token contract issues.

src/input/bond/InputSettlerBond.sol (2)

372-396: Consider adding fillDeadline validation in claim.

The claim function doesn't validate that order.fillDeadline hasn't passed. While this may be intentional (allowing late claims before expiry), a solver claiming after fillDeadline will likely face slashing during finalization. Consider whether early rejection would improve UX.


495-495: Minor: Consider documenting TIME_TO_FILL bounds.

While overflow at os.timestamp + TIME_TO_FILL is practically impossible with realistic timestamps, documenting expected bounds for TIME_TO_FILL (e.g., "expected to be hours or days, not years") would clarify the design intent.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 035fa57 and 4a07026.

📒 Files selected for processing (3)
  • src/input/bond/InputSettlerBond.sol
  • src/input/bond/SolverBondVault.sol
  • src/interfaces/IInputSettlerBond.sol
🔇 Additional comments (16)
src/input/bond/SolverBondVault.sol (8)

126-130: LGTM!

Constructor validation is correct - ensures slashBasisPoints cannot exceed 100% (10,000 BPS).


139-154: LGTM!

Good use of balance-before/after pattern to properly handle fee-on-transfer tokens. The validation and accounting are correct.


161-173: LGTM!

Proper checks-effects-interactions pattern with correct balance validation.


426-464: LGTM!

The unlock-then-slash logic correctly adds the locked amount back to available balance before calculating the slash. The use of Math.min ensures the slash cannot exceed available funds, preventing underflow.


472-498: LGTM!

Full penalization correctly transfers locked bonds directly to the recipient, bypassing the available balance. The accounting properly decrements only lockedAmount.


506-543: LGTM!

The penalize-and-slash logic correctly separates the full lock penalty from the additional slash on available balance. The combined transfer is efficient.


626-678: LGTM!

Clean separation of transfer-only logic from the lock-and-transfer variant. The fallback pattern is consistent with the locking version.


687-692: LGTM!

Correct use of Math.mulDiv with default floor rounding, appropriate for penalty calculations.

src/interfaces/IInputSettlerBond.sol (1)

10-45: LGTM!

Interface correctly declares all public entry points matching the implementation. The overloads for open and openFor properly distinguish bonded vs escrow modes.

src/input/bond/InputSettlerBond.sol (7)

119-127: LGTM!

Constructor properly initializes EIP712 domain and SolverBondVault. The immutable TIME_TO_FILL is set correctly.


170-203: LGTM!

Proper state machine with effective reentrancy protection via the status check pattern. The order of operations (set status → external call → verify status) is correct.


205-225: LGTM!

Escrow mode correctly deposits tokens to the contract and uses the same reentrancy protection pattern.


242-305: LGTM!

Clean multi-path authorization handling with proper validation. The signature type dispatch correctly routes to appropriate transfer methods.


405-424: LGTM!

Proper delegation to validation and finalization logic. The status check ensures only claimed orders can be finalized.


432-458: LGTM!

Refund correctly differentiates between claimed (penalize solver) and deposited (return escrow) states. The expiry check ensures premature refunds are blocked.


530-548: LGTM!

EIP712-compliant solver consent verification using SignatureChecker for smart contract wallet compatibility. The minimal typehash is sufficient since EIP712 domain provides contract-specific binding.

Comment thread src/input/bond/InputSettlerBond.sol Outdated
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