Nomad

QuantstampFiles named in the report

Quantstamp reviewed Nomad on 11 May 2022: 40 findings, 0 critical; 10 marked fixed, 24 acknowledged, 6 open.

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

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings40

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

SeverityOpenAcknowledgedFixed
Critical000
High001
Medium204
Low4245
HighMessages Can Be Proven And Processed In The Replica Even On `Failed` StateFixed

The `prove`, `process`, and `proveAndProcess` methods can be called even if the `Replica` contract is on `Failed` state. Therefore, if governance does not deal with the replica immediately (replace replica in the corresponding `XAppConnectionManager` or remove fraudulent roots via the `setConfirmation` method), fraudulent roots might have enough time to be confirmed, thereby letting fraudulent messages to be proven and processed.

MediumImpossibility To Recover From A Failed StateFixed

Whenever fraud is detected in the `Home` or `Replica` contracts, they will be moved to a `Failed` state (via the `doubleUpdate` or `improperUpdate` methods). However, once a contract moves to that state, it's not possible to return it to `Active`. The only way out is to upgrade the contracts' code or deploy new instances.

MediumMessages Can Be Delivered Out Of OrderFixed

According to the [Nomad documentation](https://docs.nomad.xyz/#replica), the replica has to ensure that messages are delivered in order. However, that's not the case. As long as a message has been marked as `PROVEN`, the processor is free to call the `process` method in the replica in any order it wants. This is a problem because a malicious processor or malicious third-party (the `process` method is not protected, so anyone could call it) could force the replica to process their messages in a way that is beneficial to them (front-run).

MediumMissing Validation On The `optimisticSeconds`Fixed

The `optimisticSeconds` parameter is not validated, so it could be set to 0 or a minimal amount. This would allow updates to be accepted in a very short time, thereby not leaving the replica with enough time to respond to fraud (this is also a problem in the `initialize` method).

MediumMissing Verification On The `FEE_NUMERATOR`Fixed

During an upgrade of the contract, `PRE_FILL_FEE_NUMERATOR` could be set to a value greater than 10000. This behaviour would result in impacting the logic of the contract.

LowFloating PragmaFixed

The contract makes use of the floating-point pragma ^0.6.11. Contracts should be deployed using the same compiler version. Locking the pragma helps ensure that contracts are not unintentionally deployed using another pragma, such as an obsolete version, that may introduce issues in the contract system.

LowFront Running Can Make Liquidity Providers Lose Their FundsFixed

The `preFill` method allows a liquidity provider (LP) to fill a transfer that hasn't been verified yet for a fee. This method ensures that only one liquidity provider can provide liquidity to a single transfer (`L230`). However, it does not verify if the transfer has already been processed by the `handle` method (`L107`). A malicious processor (or even a malicious miner) could wait to send the message that will trigger the `handle` method just before a `preFill` method call is done, thereby letting the recipient receive funds from both, the router and the liquidity provider. To make things worse, once the `send` method has been processed, another LP would be able to call `preFill` again for the same transaction.

LowInteger Overflow /UnderflowFixed

The codebase is not using `SafeMath` in the arithmetic operations. Some places can potentially be overflow or underflow in edge cases.

LowLiquidity Provider Fee Can Be BypassedFixed

In the `_applyPreFillFee` function, the `_amtAfterFee` is calculated using the following formula ``` (_amnt * PRE_FILL_FEE_NUMERATOR) / PRE_FILL_FEE_DENOMINATOR; ``` The issue here is that is if `_amt * PRE_FILL_NUMERATOR` is less than `PRE_FILL_FEE_DENOMATOR` the `_amtAfterFee` will be equal to 0.

LowTransactions Are Marked As Processed Even If They FailFixed

The `process` method forwards messages to their destination and mark the messages as processed regardless of the outcome of the method. If dApps do not account for this, they might end up in invalid states. For example, the `BridgeRouter` is assuming that trades sent across the chain always work and has no functionality to recover if the `handle` method fails for any reason.

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 (66)

  • Nomad/monrepo/packages/contracts-bridge/contracts/TokenRegistry.sol
  • Nomad/monrepo/packages/local-environment/tests/utils/token/contract/IERC20.sol
  • Nomad/monrepo/packages/contracts-core/contracts/UpdaterManager.sol
  • Nomad/monrepo/packages/contracts-router/contracts/XAppConnectionClient.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/BridgeMessage.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestRecipient.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/Encoding.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestMerkle.sol
  • Nomad/zodiac/contracts/test/Imports.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/test/TestBridgeRouter.sol
  • Nomad/monrepo/packages/contracts-core/contracts/XAppConnectionManager.sol
  • Nomad/monrepo/packages/local-environment/tests/utils/token/contract/Token.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/MysteryMathV1.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipient2.sol
  • Nomad/monrepo/packages/contracts-core/contracts/libs/Message.sol
  • Nomad/monrepo/packages/contracts-core/contracts/upgrade/UpgradeBeaconController.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestMessage.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestCommon.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipient6.sol
  • Nomad/monrepo/packages/contracts-core/contracts/interfaces/IMessageRecipient.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestHome.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestGovernanceMessage.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/interfaces/IBridgeToken.sol
  • Nomad/monrepo/packages/contracts-core/contracts/libs/TypeCasts.sol
  • Nomad/monrepo/packages/contracts-core/contracts/interfaces/IUpdaterManager.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/test/MockCore.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipientHandle.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipient3.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipient5.sol
  • Nomad/monrepo/packages/contracts-core/contracts/Queue.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/BridgeToken.sol
  • Nomad/zodiac/contracts/test/TestAvatar.sol
  • Nomad/monrepo/packages/contracts-core/contracts/Home.sol
  • Nomad/monrepo/packages/contracts-core/contracts/upgrade/UpgradeBeaconProxy.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/MysteryMath.sol
  • Nomad/zodiac/contracts/test/Mock.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/test/TestBridgeMessage.sol
  • Nomad/monrepo/packages/contracts-core/contracts/Version0.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/vendored/OZERC20.sol
  • Nomad/monrepo/packages/contracts-core/contracts/libs/Queue.sol
  • Nomad/monrepo/packages/contracts-core/contracts/Replica.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestQueue.sol
  • Nomad/monrepo/packages/local-environment/tests/utils/token/contract/ERC20.sol
  • Nomad/zodiac/contracts/test/TestFactory.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestReplica.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/test/MockWeth.sol
  • Nomad/monrepo/packages/contracts-core/contracts/libs/Merkle.sol
  • Nomad/monrepo/packages/contracts-router/contracts/Router.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/interfaces/ITokenRegistry.sol
  • Nomad/monrepo/packages/contracts-core/contracts/Merkle.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestXAppConnectionManager.sol
  • Nomad/zodiac/contracts/GnomadModule.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/TestGovernanceRouter.sol
  • Nomad/monrepo/packages/contracts-core/contracts/NomadBase.sol
  • Nomad/monrepo/packages/contracts-core/contracts/governance/GovernanceRouter.sol
  • Nomad/zodiac/contracts/test/MockConnectionManager.sol
  • Nomad/monrepo/packages/contracts-core/contracts/upgrade/UpgradeBeacon.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/test/TestEncoding.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/ETHHelper.sol
  • Nomad/monrepo/packages/contracts-core/contracts/governance/GovernanceMessage.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/BridgeRouter.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipient4.sol
  • Nomad/monrepo/packages/contracts-bridge/contracts/interfaces/IWeth.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/bad-recipient/BadRecipient1.sol
  • Nomad/monrepo/packages/contracts-core/contracts/test/MysteryMathV2.sol
  • Nomad/monrepo/packages/local-environment/tests/utils/token/contract/Context.sol

Part of Nomad’s security record

Nomad
Audits1 audit by 1 firmLast audit May 2022, by Quantstamp.
Critical findingsNo open critical findingsIn 1 report.
IncidentIncident 31 Jul 2022Source: De.Fi incident database.
Open Nomad’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