Overview
This audit covers 1inch Network Fusion Atomic Swaps, a two-party swap mechanism optimized for EVM-compatible chains, with well-aligned incentives to ensure fair and fast execution for all participants. Our security assessment spanned four days and involved a thorough review of the Solidity smart contracts intended for deployment on EVM-compatible chains. During the audit, we did not identify any major vulnerabilities. However, we did identify one optimization. The reported issue was addressed by the development team and subsequently verified by our team. As a result, we can confidently state that the protocol's security posture and code quality have improved following our audit.
Scope
The analyzed resources are located on:
https://github.com/1inch/cross-chain-swap/
- contracts/BaseEscrow.sol
- contracts/BaseEscrowFactory.sol
- contracts/Escrow.sol
- contracts/EscrowDst.sol
- contracts/EscrowFactory.sol
- contracts/EscrowSrc.sol
- contracts/interfaces/IBaseEscrow.sol
- contracts/interfaces/IEscrowFactory.sol
- contracts/libraries/ImmutablesLib.sol
- contracts/mocks/ResolverExample.sol
- contracts/zkSync/EscrowDstZkSync.sol
- contracts/zkSync/EscrowFactoryZkSync.sol
- contracts/zkSync/EscrowSrcZkSync.sol
- contracts/zkSync/EscrowZkSync.sol
Commit: d0a59ab2c4b6be5c9769d5775769681873fcf162
The issues described in this report were fixed in the following commit:
https://github.com/1inch/cross-chain-swap/pull/139
Commit: 339ab27e5a542737de610e0ebdae6f95dc20cd63
Summary
Weaknesses
This section contains the list of discovered weaknesses.
OIN11-2 | REDUNDANT CONVERSION FROM ADDRESS TO ADDRESS WHEN ENCODING
Severity:
Status:
Fixed
Path:
contracts/BaseEscrowFactory.sol#L141-L146
Description:
In the function BaseEscrowFactory._postInteraction(), the immutablesComplement.parameters value is computed (line 141 - line 146) as:
parameters: abi.encode(
protocolFeeAmount,
integratorFeeAmount,
Address.wrap(uint160(protocolFeeRecipient)),
Address.wrap(uint160(integratorFeeRecipient))
)
Here, the address values protocolFeeRecipient and integratorFeeRecipient are explicitly converted to the Address type (an alias for uint256, 32 bytes).
This conversion is unnecessary because abi.encode() already pads address types to 32 bytes automatically.
Remediation:
Consider modifying line 141 - line 146 to:
parameters: abi.encode(
protocolFeeAmount,
integratorFeeAmount,
-- Address.wrap(uint160(protocolFeeRecipient)),
-- Address.wrap(uint160(integratorFeeRecipient))
++ protocolFeeRecipient,
++ integratorFeeRecipient
)