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
, andvaultAddress
.
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 notlayerZeroRelayer
.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
andvaultAddress
.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 theassets
amount to the receiver. Ifreceiver
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
andtoToken
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