#38644 [SC-Insight] Q&A

Submitted on Jan 8th 2025 at 15:45:28 UTC by @focusoor for Audit Comp | Lombard

  • Report ID: #38644

  • Report Type: Smart Contract

  • Report severity: Insight

  • Target: https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/bridge/adapters/CLAdapter.sol

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

Description

[N-1] Unused payloadfield inside CLAdapter:_buildCCIPMessage

The _buildCCIPMessage method is used to construct a CCIP message for bridging LBTC tokens. When constructing token bridging without an additional call, the data field is not required and will be set to empty. Therefore, the _payload parameter in the function is unused and can be removed. https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/bridge/adapters/CLAdapter.sol#L225

 function _buildCCIPMessage(
        bytes memory _receiver,
        uint256 _amount,
->    bytes memory _payload
    ) private view returns (Client.EVM2AnyMessage memory) {
...
return
            Client.EVM2AnyMessage({
                receiver: _receiver,
->            data: "",
                tokenAmounts: tokenAmounts,
                extraArgs: Client._argsToBytes(
                    Client.EVMExtraArgsV2({
                        gasLimit: getExecutionGasLimit,
                        allowOutOfOrderExecution: true
                    })
                ),
                feeToken: address(0) // let's pay with native tokens
            });

Additionally, the CLAdapter:getFee method can be modified to remove the _payload parameter, as it is not required in the context of token bridging without an additional call. https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/bridge/adapters/CLAdapter.sol#L92

Furthermore, inside the Bridge:getAdapterFee method, the length of the payload data is not relevant, and passing new bytes(228) is unnecessary. This parameter can be safely removed to simplify the implementation. https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/bridge/Bridge.sol#L133

[N-2] CLAdapter:initWithdrawalNoSignatures is not used.

The CLAdapter:initWithdrawalNoSignatures method is not used in the current implementation and can be safely removed. Consider adding this method back only if unnotarized payloads are ever permitted in the future. https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/bridge/adapters/CLAdapter.sol#L192

[N-3] Unnecessary storage read inside LBTC:batchMintWithFee

Inside the batchMintWithFee method, before calling _mintWithFee, there is an unnecessary call to _getLBTCStorage that is not used. Consider removing it to save gas costs and improve code clarity. https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/LBTC/LBTC.sol#L446

[N-4] No constraints on absCommission when adding a destination chain.

https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/bridge/Bridge.sol#L332

When adding a new destination chain, the admin will set required parameters like relCommission and absCommission, which will be used for fee deduction during bridging events. While relCommission has a sanity check using FeeUtils.validateCommission, absCommission is unbounded and can be set to any value.

It is advised to add a sanity check, as this value will be directly added as a fee that users will pay during the deposit event.

[N-5] Height field from ValSetAction struct is never used.

When setting the validator configuration during a call to Consortium:setInitialValidatorSet, the data passed will represent a struct:

After validation, the right field will be populated; however, the height field will not be used.

https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/consortium/Consortium.sol#L91

If the field is only used for off-chain purposes, it is advised to add a comment explaining its purpose. Otherwise, consider removing the field to simplify the data being passed.

[N-6] The invalid BTCBPMM documentation does not align with the code and can lead to confusion.

The BTCBPMM contract allows users to swap BTCB for LBTC at a 1:1 rate with a relative fee. To control risk exposure, limits for staking are set and represented by the stakeLimit variable. Documentation present here, along with examples: https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/docs/btcb.md describes that the staking limit is in BTCB tokens. The BTCBPMM (BTCB Private Market Maker) contract allows users to swap BTCB for LBTC and manages the amount of BTCB that can be staked.

However, looking at the code, the stake is actually tracked in LBTC minted, rather than BTCB tokens swapped: https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/contracts/pmm/BTCB/BTCB.sol#L69

This works fine, as those two are represented in a 1:1 ratio. It’s important to note that LBTC has 8 decimals, while BTCB has 18, which means that during deployment, stakeLimit must be set in LBTC, otherwise, this would allow a significantly larger stake amount than intended. Looking at the deployment script file: https://github.com/lombard-finance/evm-smart-contracts/blob/edd557006050ee5b847fa1cc67c1c4e19079437e/scripts/deployments/pmm.ts#L21

there is no issue with parameter settings during deployment as stakeLimit is in LBTC, but it is highly recommended to update the present documentation to avoid further confusion about the intended behaviour.

[N-7] Complex bridging flow requires additional documentation.

The Lombard team has invested time in writing good documentation to describe the intended behaviour of the project and provide clear examples of how one can interact with the contracts. However, there are some areas that could benefit from additional details for advanced users, such as the Chainlink CCIP integration with CLAdapter. Although these types of diagrams are never fully complete, the attached image attempts to improve the documentation by providing a contract interaction flow. It is also advised to add additional documentation explaining the off-chain part of the code, including the process of sending transactions and integrating with the Chainlink CCIP system.

Proof of Concept

Proof of Concept

These issues are only meant to provide insights for improving the project's quality and documentation.

Last updated

Was this helpful?