Datachain - IBC

QuantstampRepository at commit ca7a56c

Quantstamp reviewed Datachain (Datachain - IBC) on 9 Dec 2024: 13 findings, 0 critical; 10 marked fixed, 3 acknowledged.

No open critical findings
Open the reportOpen Datachain’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings13

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High015
Medium002
Low023
High`IBCChannelHandshake.channelOpenAck()` Does Not Require Connection to Be Open Before Opening ChannelFixed

`IBCChannelHandshake.channelOpenAck()` does not confirm that the connection is open before opening the channel. As a result, an ibc-solidity chain can open a channel although the connection in which it resides is not open. This is a fundamental flaw as the connection handshake must be complete before any packets can be sent or received through it to ensure that two ConnectionEnds between chains are totally in sync. Additionally, creating a channel on a connection that hasn't completed the handshake will totally bypass all logic contained in `IBCConnection.connectionOpenConfirm()`. Another impact is that if the channel were created in this fashion, from the ChannelEnd on ChainB, `channelCloseInit()` could never be invoked, as this function requires that the `ConnectionEnd.State == STATE_OPEN`, which could result in the ChainB ChannelEnd being forced to continously receive what could be malicious packets from a counterparty. Throughout this implementation there is a missing enforcement of an open connection as defined in the specs as the Datachain team incorrectly assumes that an open channel implies an open connection. The comment `// NOTE: We can assume here that the connection state is OPEN because the channel state is OPEN` notes all places in the codebase where this assumption is made. Resolving this issue will allow this assumption to hold true, and we have not identified such a clear exploit resulting from the missing checks, however, we encourage the Datachain team to take a closer look here.

HighClosing an Ordered Channel on Packet Timeout Is Not Reflected in the Provable StoreFixed

In the function `IBCChannelPacketTimeout.timeoutPacket()`, when closing an ordered channel due to packet timeout, the closed channel state is not written to the provable store. This creates the possibility for counterparty chains to be able to verify a different state of this channel that what is intended.

HighMissing Logic for `STATE_FLUSHING` Channel StateFixed

During several packet operations there is missing logic in the ibc-solidity implementation when the Channel is in the `STATE_FLUSHING` state and actively completing an upgrade. According to the specs, this logic enforces a counterparty upgrade timeout. The logic is missing from the `acknowledgePacket()` and `timeoutPacket()` functions.

HighNo Error if Commitment Exists in `updateClientCommitments()`Fixed

`IBCClient.updateClientCommitments()` does not enforce that the `commitments` mapping is zero for the `consensusStateCommitmentKey` that is trying to be written. This is directly contradictory to what is documented in ADR-001 by the Datachain team. Perhaps, if the key exists, and is equivalent to the consensus state we derived from the light client, it would make sense to continue. However, the existence of the key with a different consensus state should signal that there is something out of sync between the clients. For example, in the case of a reorg, there could be a consensus state written at that key that is from a malicious series of blocks, that can be accepted as valid state alongside valid blocks.

HighPacket Commitment Not Deleted in `timeoutOnClose()`Fixed

The two functions `timeoutPacket()` and `timeoutOnClose()` first check if a packet's timeout has been exceeded, and if so, update the channel's state accordingly. In order to avoid replaying the same timeout multiple times, the packet's commitment key can be removed after use, as is suggested for both functions in the [ICS-04 specification](https://github.com/cosmos/ibc/blob/47fea20d4d400e967721396092c6b43398c65d78/spec/core/ics-004-channel-and-packet-semantics/README.md). However, this check does not occur in `timeoutOnClose()`. Note that if `timeoutOnClose()` is called multiple times for the same packet, the following module call will occur each time: ``` lookupModuleByChannel(msg_.packet.sourcePort, msg_.packet.sourceChannel).onTimeoutPacket( msg_.packet, _msgSender() ``` Since we cannot know how each different module will handle this call, this replay scenario should be avoided. This could be particularly problematic if the module refunds a user's tokens in this scenario.

Medium`timeoutPacket()` and `timeoutOnClose()` Incorrectly Enforce an Open Channel StateFixed

As the protocol is intended to support optimistic packet sends, that will be sent on channels that will either open in the future, or never open, there should be support for the timing out of packets on channels that are in a state different than `OPEN`. However, these two functions incorrectly enforce an open channel state.

MediumMissing Checks on `revision_number`Fixed

A packet is expected to have either a nonzero `timeoutHeight` or a nonzero `timeoutTimestamp`. An example of this check occurs in `sendPacket()`: `timeoutHeight.isZero() && timeoutTimestamp == 0`. Notably, the call to `isZero()` checks both `revision_number` and `revision_height`. There are several other locations in the code that do not check the `revision_number`, such as in `recvPacket()`: `if (msg_.packet.timeoutHeight.revision_height != 0 && block.number >= msg_.packet.timeoutHeight.revision_height)`. If the `revision_number != 0` but `revision_height = 0`, it may allow a packet from an earlier revision to be received after its time out. In the worst case, this could lead to a double-spend, such that the sending chain refunds a user based on timeout, and the receiving chain later accepts a timed-out packet. Although the attack window is small and unlikely, as it requires a zero-height upgrade and a packet to be sent in block zero, the impact could be significant if used for an attack such as a double-spend. Another function that does not check `revision_number` is `timeoutChannelUpgrade()`: ``` if ( upgrade.timeout.height.revision_height != 0 && msg_.proofHeight.revision_height < upgrade.timeout.height.revision_height ) ``` Note that "zero-height upgrades" are possible, as described in [ICS-07](https://github.com/cosmos/ibc/blob/main/spec/client/ics-007-tendermint-client/README.md): "This is designed to allow the height to reset to 0 while the revision number increases by one in order to preserve timeouts through zero-height upgrades."

LowNot All Sequence Variables Are Stored in the Provable StoreFixed

The function `initializeSequences()` sets initial values in `channelStorage` for `nextSequenceSend`, `nextSequenceRecv`, and `nextSequenceAck`. However, only `nextSequenceRecv` is stored directly in the provable store: ``` getCommitments()[IBCCommitment.nextSequenceRecvCommitmentKey(portId, channelId)] = keccak256(abi.encodePacked((bytes8(uint64(1))))); ``` The [ICS-024 specification](https://github.com/cosmos/ibc/blob/47fea20d4d400e967721396092c6b43398c65d78/spec/core/ics-024-host-requirements/README.md#path-space) suggests that all three should be committed to the provable store.

LowPotential Arbitrary Calls in `updateClient()`Fixed

In `IBCClient.updateClient()`, there is the possibilitiy for a light client supporting arbitrary function calls, in the case where the call to `lc.routeUpdateClient()` were to return an unexpected function selector that would then be invoked on the Light Client itself. The Datachain team has already noted this situation in documentation ADR-001 however we include it here for clarity. There, they mention that this can be mitigated at the relayer level, by relayers including a whitelist of expected functions. Additionally, we trust that the light clients are implemented honestly to not support arbitrary calls.

LowValidator Does Not Check for Suggested Identifier Size RestrictionsFixed

The table in [ICS-024](https://github.com/cosmos/ibc/blob/47fea20d4d400e967721396092c6b43398c65d78/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators) suggests that a client identifier should be between 9-64 characters, however no such check occurs in `validateClientType()`. Note that `validatePortIdentifier()` does include checks for the suggested length.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (53)

  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IBCHostConfigurator.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/03-connection/IIBCConnection.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/IIBCClient.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/OwnableUpgradeableIBCHandler.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/IIBCClientErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/26-router/IBCModuleManager.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/Channel.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/Commitment.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/03-connection/IBCConnection.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/IBCClientConnectionChannelHandler.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IIBCHostConfigurator.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IBCHost.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/ILightClient.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/apps/commons/IBCChannelUpgradableModule.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/IBCHeight.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/apps/commons/IBCAppBase.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IBCCommitment.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IBCChannelPacketSendRecv.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IIBCChannelUpgrade.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/26-router/IIBCModuleUpgrade.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/Client.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/IBCClient.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/apps/commons/IIBCChannelUpgradableModule.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/GoogleProtobufAny.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/QBFT.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IBCSelfStateValidator.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IIBCChannelErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/MockClient.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/IBCClientLib.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IIBCHostErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/IIBCQuerier.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/IIBCHandler.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IBCChannelPacketTimeout.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IBCChannelHandshake.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IIBCChannel.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IBCChannelLib.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/ProtoBufRuntime.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/03-connection/IBCConnectionLib.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IBCHostLib.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/03-connection/IIBCConnectionErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/Connection.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/OwnableIBCHandler.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/26-router/IIBCModuleErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/03-connection/IBCConnectionSelfStateNoValidation.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/26-router/IIBCModule.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/02-client/ILightClientErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/proto/Localhost.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/IBCHandler.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IBCChannelUpgrade.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/26-router/IIBCModuleManager.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/04-channel/IIBCChannelUpgradeErrors.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/25-handler/IBCQuerier.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61
  • https://github.com/hyperledger-labs/yui-ibc-solidity/contracts/core/24-host/IBCStore.sol at commit ca7a56c85749b83d5fb35aae7cd7e0b07e655b61

Part of Datachain’s security record

Datachain
Audits7 audits by 1 firmLast audit Jul 2025, by Quantstamp.
Critical findingsNo open critical findingsAcross 7 reports.
Open Datachain’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us