Assessment reports>Y2K Finance>Threat Model>lzReceive

Function: lzReceive(uint16 _srcChainId, byte[] _srcAddress, uint64 _nonce, byte[] _payload)

This allows to receive the message from other chains using LayerZero protocol. Only LZ Endpoint can call this function. The function allows to perform one of the actions that is determined by the value of the funcSelector. If funcSelector == 0x01 then _withdrawFromVault function will be invoke to direct withdraw funds from vaultAddress to the receiver address in this chain. If funcSelector == 0x03 then the withdrawn from vaultAddress tokens will be swaped for the token requested by the user and after that bridged to the other chain. Otherwise the withdrawn from vaultAddress tokens will be just bridged to the other chain.

Inputs

  • _srcChainId

    • Constraints: There is a check that trustedRemoteLookup for _srcChainId is equal to _srcAddress.

    • Impact: The messages can be received only from trusted chains.

  • _srcAddress

    • Constraints: There is a check that trustedRemoteLookup for _srcChainId is equal to _srcAddress.

    • Impact: The messages can be received only from trusted user application from other chains.

  • _nonce

    • Constraints: N/A.

    • Impact: Not used.

  • _payload

    • Constraints: N/A.

    • Impact: Contains the data: the action, bridgeId, receiver, id, and vaultAddress.

Branches and code coverage (including function calls)

Intended branches

  • The swap over UniswapV2 performed properly.

  • The swap over UniswapV3 performed properly.

Negative behavior

  • msg.sender is not layerZeroRelayer.

  • trustedRemoteLookup is not set.

  • _srcChainId is untrusted.

  • swapId > 0x02.

Function call analysis

  • _withdraw(funcSelector, bridgeId, receiver, id, _srcChainId, vaultAddress, _payload); -> _withdrawFromVault(id, assets, receiver, vaultAddress)

    • What is controllable? id and vaultAddress.

    • If return value controllable, how is it used and how can it go wrong? n/a

    • What happens if it reverts, reenters, or does other unusual control flow? the whitelisted trusted vaultAddress contract is called which transfer the assets amount to the receiver. If receiver address is wrong then funds can be lost, but in case of calling from other chain over lz the address of receiver is msg.sender address, so it cannot be wrong.

  • _withdraw(funcSelector, bridgeId, receiver, id, _srcChainId, vaultAddress, _payload); -> _swapToBridgeToken(amountReceived, asset, _payload);

    • What is controllable? _payload

    • If return value controllable, how is it used and how can it go wrong? return the resulted token address, the rest of payload and the final swap amount. The token address is controlled by user, but for this address the valid uniswap pair contract should exists, otherwise function will revert.

    • What happens if it reverts, reenters, or does other unusual control flow? can revert if uniswap pair is not exist for token and toToken addresses.

  • _withdraw(funcSelector, bridgeId, receiver, id, _srcChainId, vaultAddress, _payload); -> _bridgeToSource(bridgeId, receiver, asset, _srcChainId, _payload);

    • What is controllable? bridgeId, _payload, _srcChainId

    • If return value controllable, how is it used and how can it go wrong? n/a

    • What happens if it reverts, reenters, or does other unusual control flow? can revert due to issues during bridging

Zellic © 2024Back to top ↑