OverlayerWrapCore tracks bridged supply with totalBridgedOut. On the source side, _debit() increases this value after tokens are burned for a cross-chain transfer. On the destination side, _credit() always decreases it again.
The problem is that this accounting is applied on every chain, not only on the hub chain where the tracked bridged-out amount actually exists.
In the current logic:
This only works if the same contract instance had previously increased totalBridgedOut.
On a satellite chain, totalBridgedOut starts at 0. When a user bridges tokens from the hub chain to the satellite chain, the destination _credit() tries to subtract the received amount from zero. This causes an arithmetic underflow and the inbound credit reverts.
As a result, an inbound bridge delivery to a non-hub chain can fail deterministically. The source-side debit can already have happened on the hub side, while the destination-side credit fails, creating a lock in the user bridge flow.
Relevant vulnerable logic:
function debit( address from, uint256 amountLD_, uint256 minAmountLD_, uint32 dstEid_ ) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) { (amountSentLD, amountReceivedLD) = super.debit( from, amountLD_, minAmountLD_, dstEid_ ); totalBridgedOut += amountSentLD; }
function credit( address to, uint256 amountLD_, uint32 srcEid_ ) internal virtual override returns (uint256 amountReceivedLD) { amountReceivedLD = super.credit(to, amountLD_, srcEid_); totalBridgedOut -= amountReceivedLD; }
Reproduction flow:
This is not theoretical. I reproduced it locally with a runnable Hardhat PoC and observed the satellite-side inbound credit revert with panic code 0x11.
hub totalBridgedOut after debit: 5000000000000000000 satellite totalBridgedOut before credit: 0 expected revert on satellite inbound credit Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)