# Audit of onlyswaps and dcipher (BLS signatures)

- **Client**: Randa-mu
- **Date**: September 19th, 2025
- **Tags**: BLS, BLS12-381, Threshold Signatures, Shamir Secret Sharing, Hash-to-curve, Solidity

## Introduction

On September 8th, 2025, zkSecurity was commissioned to perform a security audit of Randa-mu's cross-chain OnlySwaps protocol and the BLS threshold signatures implementation. For the next two weeks, one consultant reviewed the code in search of bugs. A number of observations and findings have been reported to the Randa-mu team. The findings are detailed in the latter section of this report.
The codebase was found to be of high quality, accompanied by thorough tests and documentation.

### Scope

The scope of the audit was divided into three distinct parts:

* [onlyswaps-solidity](https://github.com/randa-mu/onlyswaps-solidity/tree/main): containing the main on-chain logic of the protocol (commit: `7607614bcff8ee2bd843f303db1b32c5f5c3f4e5`)
* [bls-solidity](https://github.com/randa-mu/bls-solidity/tree/main): a library implementing BLS verification in Solidity (commit: `9e10df92d631fab9c46f0ce9cd5c445f857bedcb`)
* [Parts of the dcipher repo](https://github.com/randa-mu/dcipher/tree/main): implementing the off-chain logic written in Rust (commit: `e08602de2d1543c508914b2ca9ddbcb647fb7bcf`). Specifically focusing on:
    * `onlyswaps-verifier`: main agent for verifying cross-chain swap fulfillments and creating threshold signatures
    * `omnievent`: listens to events from chains
    * `signer`: threshold signing
    * `crates/network`: wrapping functionality of libp2p used by the signer
    * `crates/utils`: utility functions for `hash_to_curve`, `dst`, and `serialize` (for the pairing operations)

The distributed key generation codebase was not part of this engagement. Furthermore, the main dependencies such as `libp2p` and `ark` are considered to be secure.

## Protocol Overview

OnlySwaps is a protocol for cross-chain token swaps that are fulfilled by solvers. An off-chain committee produces BLS threshold signatures verifying that a solver has fulfilled a request from a user in a destination chain. The signature is then submitted in the source chain to release the funds to the solver.

The following figure demonstrates an end-to-end example of OnlySwaps.

![Overview](/img/reports/randa-mu-onlyswaps/overview.png)

The main functions in the Router.sol contract that handle the on-chain activity are: 

* [requestCrossChainSwap](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L115): Called by a user in the source chain, it creates and saves a requestId with the passed parameters and emits an event about this request. With this function call, the user also sets the solver reward and sends the funds to the Router.
* [relayTokens](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L178): Called by a solver in the destination chain, it fulfills a request by sending the funds to the user-specified address. It further updates the state of the Router in the destination chain and emits an event.
* [rebalanceSolver](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L211): When a committee member has a BLS threshold signature that verifies that a requestId has been fulfilled correctly, they can submit the signature by calling this function in the source chain. It first verifies the signature, then updates the state, sends the solver reward to the solver, and emits an event. The BLS signature verification happens by calling the [verifySignature function from bls-solidity](https://github.com/randa-mu/bls-solidity/blob/2a810f01946431338c31b2ad1d8eb3d630563e0e/src/signature-schemes/BN254SignatureScheme.sol#L45).
* [updateSolverFeesIfUnfulfilled](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L157C14-L157C43): A user can call this function in the source chain to update the solver fee to incentivize solvers to fulfill their request. Importantly, this function can only increase the fee.

On the off-chain part, an [onlyswaps-verifier agent](https://github.com/randa-mu/dcipher/tree/main/onlyswaps-verifier) queries all supported blockchains for detecting new events. When it detects a new event that requires verification (e.g., a receipt event), it calls the [evaluate_and_send](https://github.com/randa-mu/dcipher/blob/074d574b15e54078b1b3599ddb284cd24970b2c9/onlyswaps-verifier/src/main.rs#L126C26-L126C43) function. This function is responsible for:

1. [Querying](https://github.com/randa-mu/dcipher/blob/074d574b15e54078b1b3599ddb284cd24970b2c9/onlyswaps-verifier/src/signing.rs#L70C1-L83C68) both the source chain and the destination chain to get the transfer params and the transfer receipt, respectively
2. Calling the [reconcile_transfer_params](https://github.com/randa-mu/dcipher/blob/074d574b15e54078b1b3599ddb284cd24970b2c9/onlyswaps-verifier/src/parsing.rs#L19) function that checks that the funds were sent and received in the correct chains, that the correct tokens were used, and that the correct amount was passed
3. Starting the signing process, which by communicating with other committee members using libp2p, generates a BLS threshold signature. The logic of the signing process is in the [signer directory](https://github.com/randa-mu/dcipher/tree/main/signer)
4. Optionally, when having a correct threshold signature, the committee member can call the `rebalanceSolver` function in the source chain to verify the signature on-chain and pay back the solver

## Threat Model

The OnlySwaps protocol operates with the following trust assumptions and administrative controls:

### Administrative Roles

**Router Admin:**

* `setVerificationFeeBps`: Modify the verification fee in basis points
* `setMinimumContractUpgradeDelay`: Set the minimum delay for contract upgrades
* `permitDestinationChainId`: Allow a new destination chain for swaps
* `blockDestinationChainId`: Block a destination chain from receiving swaps
* `setTokenMapping`: Configure token mappings across chains
* `removeTokenMapping`: Remove existing token mappings
* `withdrawVerificationFee`: Withdraw accumulated verification fees

**Upgrade Validator Committee:**

* `scheduleUpgrade`: Schedule a future contract upgrade
* `cancelUpgrade`: Cancel a scheduled upgrade
* `setContractUpgradeBlsValidator`: Update the BLS validator for contract upgrades
* `setSwapRequestBlsValidator`: Update the BLS validator for swap requests

**Swap Validator Committee:**

* `rebalanceSolver`: Reimburse solvers with valid threshold signatures

### Trust Assumptions

* The committee operating the threshold signature scheme maintains an honest majority (at least t honest members out of n total)
* The Router Admin is a trusted entity that will not act maliciously
* Solvers are untrusted but economically incentivized to fulfill swaps correctly
* Users trust the protocol's verification mechanism to ensure proper swap execution
* `t` honest nodes create valid partial and at least one of them aggregate them into a valid signature and submit it on-chain

## BLS Threshold Signatures

The OnlySwaps protocol uses BLS (Boneh-Lynn-Shacham) threshold signatures to verify cross-chain swap fulfillments. This cryptographic scheme allows a distributed committee to collectively sign messages while requiring only a threshold number of participants.

### BLS Signature Implementation

The implementation provides both standard BLS signatures and threshold signature capabilities through the following components:

**Core BLS Operations:**
The system implements the standard BLS signature scheme over the BN254 and BLS12-381 curves. Signatures are created by computing $\sigma = H(m)^{sk}$ where $H$ is a hash-to-curve function that maps messages to elliptic curve points.

Signature verification uses bilinear pairings to check the equation $e(\sigma, g_2) = e(H(m), pk)$, ensuring that only the holder of the private key (or the shared private key) corresponding to the public key could have generated the signature.

**Domain Separation:**
Following RFC 9380 standards, the implementation uses comprehensive domain separation tags (DSTs) to prevent signature reuse across different contexts. The DST format includes:

- Application identifier (e.g., "swap-v1" for OnlySwaps)
- Curve specification (BN254G1 or BLS12381G1)
- Hash function and expansion method (XMD:KECCAK-256 or XMD:SHA-256)
- Mapping algorithm (SVDW for BN254, SSWU for BLS12-381)
- Chain ID to prevent cross-chain replay attacks

For OnlySwaps, a typical DST looks like:
`swap-v1-BN254G1_XMD:KECCAK-256_SVDW_RO_0x[chain_id]_`

### Threshold Signature Protocol

The threshold signature scheme allows any `t` out of `n` committee members to produce a valid signature:

**Secret Sharing:**
The system assumes that private keys have been distributed using Shamir Secret Sharing, where each committee member $i$ holds a share $sk_i$ of the master secret. The corresponding verification key is $vk_i = g^{sk_i}$.

**Partial Signature Generation:**
When a swap needs verification, each committee member independently:

1. Computes their partial signature: $\sigma_i = H(m)^{sk_i}$
2. Broadcasts this partial signature to other committee members via libp2p
3. Verifies received partial signatures against the sender's public key

**Signature Aggregation:**
Once `t` valid partial signatures are collected, any committee member can reconstruct the full signature using Lagrange interpolation:

$$
\sigma = \prod_{i \in S} \sigma_i^{\lambda_i}
$$

where $λ_i$ are the Lagrange coefficients computed for the set $S$ of participating members.

### Network Protocol

The threshold signing protocol operates through a distributed network using libp2p:

1. **Event Detection:** The onlyswaps-verifier agent monitors blockchain events through the omnievent system
2. **Verification Request:** When a swap receipt is detected, the agent queries both source and destination chains to verify the swap parameters
3. **Partial Signature Exchange:** Committee members compute and broadcast their partial signatures using CBOR serialization
4. **Aggregation:** When exactly `t` partial signatures are collected, the full signature is computed
5. **On-chain Submission:** The aggregated signature can be submitted to the Router contract's `rebalanceSolver` function

### Implementation Architecture

The Rust implementation is organized into modular components:

- `BlsPairingSigner`: Handles individual BLS signing and verification operations
- `BlsThresholdSigner`: Coordinates the distributed threshold signature protocol
- `signer/src/bls/filter.rs`: Manages domain separation and DST generation
- `signer/src/bls/aggregation.rs`: Implements Lagrange interpolation for signature reconstruction
- `crates/utils`: Provides utility functions for hash-to-curve and serialization

The system supports both BN254 and BLS12-381 curves, with flexible configuration for different applications beyond OnlySwaps.

## Additional Differential Testing

To ensure the correctness of the BLS implementation in Solidity, beyond manual code review, we performed extensive differential testing between the bls-solidity library and a reference Rust implementation. Each test category was executed with at least one million randomly generated test cases to provide high confidence in the implementation's correctness.

### Testing Methodology

The differential testing framework consists of a Rust program that accepts various test parameters and computes reference outputs for comparison with the Solidity implementation. The testing covered:

**BLS Signature Generation and Verification:**

- BN254 curve signatures using Keccak256 hashing
- BLS12-381 curve signatures using SHA256 hashing
- Public key generation and signature creation
- Full signature verification flow

**Hash-to-Curve Mapping:**

- Shallue-van de Woestijne (SvdW) mapping for BN254
- Field element to curve point conversion

### Test Suites

Three comprehensive fuzz testing suites were developed:

**BLSTestFuzz.sol:**

- `testFfiBlsVerifyGenerated`: Verifies BLS signature generation and verification on BN254 curve by comparing Rust-generated signatures with Solidity verification
- `testFfiMapToPointBN254`: Tests the hash-to-curve mapping function, ensuring field elements map to the same curve points in both implementations

**BLS2TestFuzz.sol:**

- Similar test structure to BLSTestFuzz but using the BLS12-381 curve
- Validates signature operations with SHA256 hashing instead of Keccak256

**ModExpFuzz.t.sol:**

- `testFfiModExp1`: Validates modular exponentiation against the BN254 field modulus
- `testFfiModExpInverse`: Tests modular inverse computation
- `testFfiModExpSqrt`: Verifies modular square root calculations

### Testing Results

All differential tests passed successfully across millions of test cases, providing strong evidence that the Solidity BLS implementation correctly matches the reference Rust implementation using the arkworks library. This extensive testing gives high confidence in the cryptographic correctness of the bls-solidity library used in the OnlySwaps protocol.

![Differential Testing Results](/img/results.png)

## Findings

### DoS Attack in relayTokens Through Malicious requestId Usage

- **Severity**: High
- **Location**: Router.sol

**Description**. The [relayTokens](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L178) function is permissionless and accepts `requestId` as a parameter without binding it to `amountOut`. This allows any user to perform a Denial of Service (DoS) attack by monitoring `requestIds` on the source chain and calling `relayTokens` with a minimal amount (e.g., `0.00...01`) while using a valid `requestId`. Since the function checks if a `requestId` has already been fulfilled, legitimate calls will [fail](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L182) when attempting to use the same `requestId`, effectively blocking the proper execution of cross-chain swaps.

__NOTE:__ The [validators](https://github.com/randa-mu/dcipher/blob/b050cd7b15a686744b8e24dfd737e6f37520163c/onlyswaps-verifier/src/parsing.rs#L19) query both source and destination chains, map `requestIds` with `SwapReceipts` based on this logic (offchain), and if correct, they generate a signature. Hence, no funds would be lost, but they would be stuck in the contracts.

**Impact**. This vulnerability enables complete and extremely cheap DoS attacks on the protocol. While no funds would be lost, they would become stuck in the contracts as legitimate solvers cannot fulfill requests that have been maliciously marked as completed with incorrect amounts. The validation step by validators would correctly fail, but users' funds would remain locked.

**Recommendation**. Modify `relayTokens` to accept all parameters needed to reconstruct the `requestId` (excluding `dstChainId`). The function should then reconstruct the `requestId` based on these parameters. This ensures that if a solver calls the function with a different `amountOut`, the resulting `requestId` will be different, preventing the DoS attack vector.

**Client Response**. We have addressed this issue by updating the `relayTokens` function to require all swap request parameters necessary to reconstruct the `requestId` on-chain. This ensures that the `requestId` is always derived from the actual parameters provided, preventing mismatches and mitigating the described denial-of-service vulnerability. See commit [895c60f829e014d8806fe01f33f97bc2ea56ea9d](https://github.com/randa-mu/onlyswaps-solidity/commit/895c60f829e014d8806fe01f33f97bc2ea56ea9d) for details.

### Admin Can Delay Upgrades Indefinitely

- **Severity**: Medium
- **Location**: Router.sol

**Description**. The upgrade mechanism at line [476](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L476) allows the admin to unilaterally delay upgrades indefinitely. This creates a centralization risk where a single admin account (or multisig) can prevent critical protocol upgrades from being executed, even if they have been properly scheduled and the timelock period has passed.

**Impact**. A malicious or compromised admin could prevent important security patches, feature upgrades, or critical fixes from being deployed to the protocol. This could leave the protocol vulnerable to known issues or prevent it from evolving to meet user needs. 

**Recommendation**. The upgrade delay should be handled by both the Admin and the BLS upgrade committee.

**Client Response**. The ability for the admin to indefinitely delay scheduled upgrades has been addressed. The `onlyAdmin` modifier has been replaced with a requirement for a BLS signature as an input parameter, which is now used to validate changes to `minimumContractUpgradeDelay`. See commit [27fee3c1c982fafe6b6c4a22578dc7221ad616b5](https://github.com/randa-mu/onlyswaps-solidity/pull/72/commits/27fee3c1c982fafe6b6c4a22578dc7221ad616b5) and [af73e8a31b410fa392ebe14c7be3991c6eed7748](https://github.com/randa-mu/onlyswaps-solidity/pull/72/commits/af73e8a31b410fa392ebe14c7be3991c6eed7748) for details. The [IScheduledUpgradeable.sol](src/interfaces/IScheduledUpgradeable.sol) interface has also been updated in this commit [b4ea44708a46853f48138dc280e0e15b15c659d7](https://github.com/randa-mu/onlyswaps-solidity/commit/b4ea44708a46853f48138dc280e0e15b15c659d7).

### Missing Finality Checks Could Lead to Fund Loss During Chain Reorganizations

- **Severity**: Medium
- **Location**: dcipher/onlyswaps-verifier/

**Description**. The dcipher agents process verification requests by picking up `requestIds` through [omnievent](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/onlyswaps-verifier/src/main.rs#L93) (which retrieves events from the [latest blocks](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/omnievent/src/event_manager.rs#L363)) or by querying the [network_bus](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/onlyswaps-verifier/src/main.rs#L106) state. The [evaluate_and_send](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/onlyswaps-verifier/src/signing.rs#L66) method does not verify that blocks containing transfer and receive transactions have been finalized according to each chain's finality rules. This creates a vulnerability where verifiers might generate threshold signatures based on transactions that could later be reverted due to chain reorganizations.

**Impact**. If a chain reorganization occurs on the destination chain after verifiers have already created and submitted a threshold signature on the source chain:

1. The solver receives funds on the source chain based on the threshold signature
2. The destination chain transaction gets reverted due to the reorganization
3. The user never receives their funds on the destination chain
4. The protocol suffers a loss as funds have been released to the solver without the corresponding delivery to the user

This scenario, while unlikely under normal conditions, could lead to significant fund losses and break the protocol's security guarantees.

**Recommendation**. Modify the `evaluate_and_send` method to verify that blocks containing both transfer and receive transactions have reached finality according to each chain's specific rules before generating threshold signatures. This approach maintains good UX for users while ensuring protocol safety:

1. Solvers can still provide fast service by fulfilling orders on the destination chain at their own risk
2. Solvers must wait for finality before receiving reimbursement on the source chain
3. Implement chain-specific finality checks (e.g., different confirmation requirements for different chains)

This ensures that threshold signatures are only generated for irreversible transactions, preventing fund loss due to reorganizations.

**Client Response**. The team acknowledged this as a potential issue, noting they haven't addressed reorganizations yet due to their complexity. They agreed that waiting for finalization makes the most sense despite UX implications.

### Missing Zero Address Check for Recipient in requestCrossChainSwap

- **Severity**: Low
- **Location**: Router.sol

**Description**. The `requestCrossChainSwap` function at line [115](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L115) does not validate that the `recipient` parameter is not the zero address. This is inconsistent with the `rebalanceSolver` function at line [183](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L183), which properly includes a zero address check for its recipient parameter. Without this validation, users could accidentally request cross-chain swaps to the zero address, resulting in permanently lost tokens.

**Impact**. If a user mistakenly provides the zero address as the recipient, the cross-chain swap would proceed normally but the tokens would be sent to an unrecoverable address on the destination chain. This would result in permanent loss of user funds due to a simple input error that could have been prevented with proper validation.

**Recommendation**. Add a zero address check for the `recipient` parameter in the `requestCrossChainSwap` function, similar to the validation already implemented in `rebalanceSolver`. This can be done by adding:

```solidity
require(recipient != address(0), "Recipient cannot be zero address");
```

**Client Response**. A zero address check for the `recipient` parameter has been added to the `requestCrossChainSwap` function to prevent invalid recipient addresses. See commit [bde64881211baf131098cb88173c43d59a036eea](https://github.com/randa-mu/onlyswaps-solidity/commit/bde64881211baf131098cb88173c43d59a036eea) for details.

### Inconsistent Destination Chain Validation in requestCrossChainSwap

- **Severity**: Low
- **Location**: Router.sol

**Description**. The `requestCrossChainSwap` function at line [124](https://github.com/randa-mu/onlyswaps-solidity/blob/70d423aa6263bef123f409b6c38dbe5d63fb006a/src/Router.sol#L124) only checks `DestinationMapping` to validate the destination chain but does not verify against `AllowedDestination`. This creates an inconsistency with the admin's allow/disallow chain management logic. When an admin disallows a chain through the administrative functions, users and solvers can still interact with that chain if the token mapping is not removed from the `DestinationMapping` data structure.

**Impact**. This inconsistency undermines the admin's ability to properly manage allowed destination chains. If an admin needs to urgently disable a destination chain (e.g., due to a security incident or chain issues), users can continue to request cross-chain swaps to that destination as long as the token remains in `DestinationMapping`. 

**Recommendation**. Modify the `requestCrossChainSwap` function to also check `AllowedDestination` in addition to `DestinationMapping`. This ensures consistency with the admin's chain management decisions. The validation should verify that:

1. The destination token exists in `DestinationMapping` (current check)
2. The destination chain is marked as allowed in `AllowedDestination` (missing check)

This can be implemented by adding an additional require statement:
```solidity
require(AllowedDestination[dstChainId], "Destination chain not allowed");
```

**Client Response**. In addition to the check on the destination token mapping, we have added a validation for the destination chain id in `requestCrossChainSwap`. Please see commit [cf80cf7a1944954d2bb65fd33effad49207c9c09](https://github.com/randa-mu/onlyswaps-solidity/commit/cf80cf7a1944954d2bb65fd33effad49207c9c09) for details.

### Byzantine Committee Members Can DoS Benign Nodes Through Signature Flooding

- **Severity**: Low
- **Location**: dcipher/signer/

**Description**. The [`recv_new_requests`](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/signer/src/bls/handlers.rs#L41) function is vulnerable to denial-of-service attacks from byzantine committee members who can flood the network with partial signatures. There is currently no rate limiting or message throttling mechanism to prevent a malicious node from overwhelming benign committee members with excessive signature requests, potentially degrading the performance of the entire threshold signature scheme.

**Impact**. A byzantine committee member could:

- Overwhelm benign nodes with excessive partial signature flooding
- Cause legitimate signature requests to be delayed or dropped
- Degrade the overall performance of the threshold signature system
- Force benign nodes to expend excessive computational resources verifying spam signatures

While the impact is limited because byzantine nodes can be identified and removed from the protocol, this still presents an operational challenge and could cause temporary service disruption.

**Recommendation**. Implement rate limiting and message management strategies.

**Client Response**. The team agreed that rate limiting would be beneficial and discussed investigating libp2p's out-of-the-box support for peer rate limiting. They acknowledged the need for caching mechanisms that limit requests per node and rotate out older ones.

### Missing Timeout Mechanism for Unfulfilled Cross-Chain Swaps

- **Severity**: Informational
- **Location**: Router.sol

**Description**. The `requestCrossChainSwap` function does not implement a timeout mechanism for unfulfilled swap requests. Once users initiate a cross-chain swap request and their tokens are locked in the contract, there is no built-in mechanism for them to reclaim their funds if solvers fail to fulfill the order within a reasonable timeframe. This creates a dependency on solver activity and could result in indefinite fund lockup if no solver is willing or able to complete the swap.

**Impact**. While this does not pose a direct security risk, it significantly impacts user experience and capital efficiency. Users' funds could remain locked indefinitely if:

- No solver finds the swap profitable enough to execute
- Market conditions change making the swap uneconomical
- There is low solver activity on certain routes
- Technical issues prevent solvers from fulfilling requests

This could lead to user frustration and reduced protocol adoption.

**Recommendation**. Implement a timeout mechanism that allows users to cancel unfulfilled swap requests and reclaim their locked tokens after a reasonable period. Consider adding:

1. A configurable timeout period (e.g., 24-48 hours) per swap request
2. A `cancelRequest` function that users can call after the timeout expires
3. Proper event emission for cancelled requests to maintain transparency
4. Generate signatures accordingly and verify them on-chain.

**Client Response**. We’ve added support for users to cancel a swap request and claim a refund to a specified wallet address on the source chain if no solver fulfills the request.
Cancellation occurs in two phases:

* Stage Cancellation – Call `stageSwapRequestCancellation(bytes32 requestId)` to start the cancellation process. This opens a cancellation window, a grace period during which solvers can still fulfill the request.

* Finalize & Refund – After the cancellation window has elapsed, call `cancelSwapRequestAndRefund(bytes32 requestId, address refundRecipient)` to complete the cancellation and receive the refund.

The length of the cancellation window can be updated only via a threshold signature by calling
`setCancellationWindow(uint256 newSwapRequestCancellationWindow, bytes calldata signature)`.

See commit [bb2e7c8a3b3f2d44e112e84f53d9dee4d678f697](https://github.com/randa-mu/onlyswaps-solidity/commit/bb2e7c8a3b3f2d44e112e84f53d9dee4d678f697) for details.

### Eager Signing Mode Lacks Security Warnings

- **Severity**: Informational
- **Location**: dcipher/signer/

**Description**. The `with_eager_signing` function at line [311](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/signer/src/bls.rs#L311) enables a mode where the node automatically submits partial signatures upon receiving valid partial signatures from other nodes. When enabled, this functionality essentially treats all libp2p nodes as trusted entities and blindly signs any valid message received. While this feature is disabled by default (line [305](https://github.com/randa-mu/dcipher/blob/03ffbcd75925850bddcd2c34b7a24a0f3dc59f02/signer/src/bls.rs#L305)), the function lacks clear documentation warning about the security implications of enabling this mode.

**Impact**. Developers using this library might inadvertently enable eager signing without fully understanding the trust assumptions and security implications. This could lead to nodes automatically signing malicious or unintended messages

While the feature itself may have legitimate use cases in trusted environments, the lack of clear warnings could lead to misuse.

**Recommendation**. Add comprehensive documentation and warnings to the `with_eager_signing` function.

**Client Response**. The team acknowledged that eager signing essentially treats other libp2p nodes as "trusted", blindly signing their signature requests. They agreed to add warnings around the function.

---

This report was published on the [zkSecurity Audit Reports](https://reports.zksecurity.xyz) site by [ZK Security](https://www.zksecurity.xyz), a leading security firm specialized in zero-knowledge proofs, MPC, FHE, and advanced cryptography. For the full list of audit reports, see [llms.txt](https://reports.zksecurity.xyz/llms.txt).
