#  LayerZeroModule miscalculates gas, risking loss of assets

LayerZeroModule used source-chain baseGas/gasPerByte for destination LZ delivery, underpricing gas so lzReceive reverts and bridged NFTs get stuck permanently.

- Payout: Contest reward
- Severity: high
- Program: Holograph
- Credited: Trust
- Disclosed: 2022-12-15
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-10-holograph-findings/issues/445
- Library page: https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AH-03
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:dos

**Target:** LayerZeroModule.sol send() / LayerZero relayer adapter params
**Root cause:** send() encodes relayer adapter params using global _baseGas() and _gasPerByte() values rather than destination-chain-specific DstConfig, so gas limits are wrong when opcode costs differ across chains.
**Steps:**
1. Read LayerZeroModule.sol send() at L431-L445: adapter params = abi.encodePacked(uint16(1), uint256(_baseGas() + crossChainPayload.length * _gasPerByte())).
2. Note _baseGas()/_gasPerByte() are single global getters, not keyed by destination chainID, unlike LZ DstConfig mapping.
3. Compare against LayerZero RelayerV2 DstConfig which stores baseGas/gasPerByte per chainID.
4. When destination chain opcode costs exceed source-chain assumption, encoded gas is insufficient; lzReceive reverts on delivery.
5. Observe lzReceive failure emits no event (unlike executeJob), leaving the NFT permanently stuck.
**How found:** Code review of the send() adapter-params encoding, noticing the gas getters were global while LayerZero's own DstConfig is keyed per destination chainID; confirmed by protocol team after discussion.
**Exploitation:** No attacker action required; a legitimate cross-chain bridge message to a chain with higher gas costs underprices delivery, lzReceive reverts, and the NFT is stranded with no failure event to recover it.
**Escalation:** Judge noted it could also wedge the LZ channel (issue #244), blocking subsequent messages.
**Insight:** When integrating a messaging layer, check whether gas/relayer parameters are per-destination-chain; a single global config silently breaks on chains with different opcode pricing, and a reverting receive with no failure event turns a gas bug into permanent asset loss.
