OverlayerWrapCore._credit() decrements totalBridgedOut on every destination chain receipt, but totalBridgedOut is only increased by _debit() on the local source deployment. On a fresh spoke deployment, totalBridgedOut starts at 0, so the first inbound bridge from the hub executes 0 - amountReceivedLD and reverts under Solidity 0.8 checked arithmetic. The inbound LayerZero delivery fails, so the bridged amount is not credited on the spoke and remains stuck in the failed cross-chain message flow until the protocol fixes and replays it.
Reproduction steps:
OverlayerWrap on a hub chain and a fresh spoke chain.totalBridgedOut == 0.OverlayerWrap on the hub for a normal user._debit() executes and increases the hub’s local totalBridgedOut._credit()._credit() runs:
amountReceivedLD = super._credit(...)totalBridgedOut -= amountReceivedLDtotalBridgedOut is 0, the subtraction underflows and the transaction reverts.Relevant code path:
function _debit(...) internal virtual override returns (...) {
(amountSentLD, amountReceivedLD) = super._debit(...);
totalBridgedOut += amountSentLD;
}
function _credit(...) internal virtual override returns (uint256 amountReceivedLD) {
amountReceivedLD = super._credit(to_, amountLD_, srcEid_);
totalBridgedOut -= amountReceivedLD;
}
Root causes:
totalBridgedOut is local storage per deployment_debit() increments it on the source chain_credit() decrements it on the destination chaintestCredit(receiver, amount, 0)on the fresh spoke before any local testDebit() has ever been executed on that same instance.