Platform: Code4rena
Start Date: 19/01/2024
Pot Size: $36,500 USDC
Total HM: 9
Participants: 113
Period: 3 days
Judge: 0xsomeone
Id: 322
League: ETH
Rank: 20/113
Findings: 2
Award: $363.08
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: windhustler
363.0765 USDC - $363.08
https://github.com/code-423n4/2024-01-decent/blob/011f62059f3a0b1f3577c8ccd1140f0cf3e7bb29/src/bridge_adapters/DecentBridgeAdapter.sol#L127-L139 https://github.com/code-423n4/2024-01-decent/blob/011f62059f3a0b1f3577c8ccd1140f0cf3e7bb29/src/bridge_adapters/StargateBridgeAdapter.sol#L183-L207
Tokens are left in the bridge when the swap at the destination chain fails
When tokens are bridged trough the bridge (DecentBridgeAdapter
and StargateBridgeAdapter
) they can be left in them if the swap in the UTB#receiveFromBridge
fails.
Both bridges suffers from the same problem. When tokens arrive at the main bridge contract callback the swap can fail leaving the user without funds which are now locked inside the protocol:
When token are bridged trough DecentBridgeAdapter#receiveFromBridge
this contract has an allowance from the layerzero (token are sent trought the OTF2 DcntEth
implementation) relay to transfer the tokens but the user sending them has no allowance or method to "save" the bridged token :
The StargateBridgeAdapter#sgReceive
has the tokens already transferred in
In the process of bridging next step is the swapping of tokens part, both contract end using the following swap call inside the UTB#receiveFromBridge
:
which choses a swapper and tries to achieve a successful swap
https://github.com/code-423n4/2024-01-decent/blob/011f62059f3a0b1f3577c8ccd1140f0cf3e7bb29/src/UTB.sol#L141 https://github.com/code-423n4/2024-01-decent/blob/011f62059f3a0b1f3577c8ccd1140f0cf3e7bb29/src/UTB.sol#L95
in case of the provided UniSwapper
swapper the swapper.swap(swapInstructions.swapPayload);
line can revert the call and leave the token inside the two mentioned bridges.
The swap in case of the UniSwapper
can fail in one of the two reasons :
in the line
can fail with the revert Too little received
and in the line
can fail with the revert Too much requested
If the revert happens the token don't get saved to the refund address.
Manual review
Account for the possibility that the swap can fail on the destination chain and if it happens transfer funds/tokens to the refund address. Something like :
// for both bridge contract the change is the same - IUTB(utb).receiveFromBridge( - postBridge, - target, - paymentOperator, - payload, - refund - ); +try IUTB(utb).receiveFromBridge( + postBridge, + target, + paymentOperator, + payload, + refund + ) { + } + catch { + IERC20(swapParams.tokenIn).transfer(refund, swapParams.amountIn) // the same amount we have successfully transferred in + }
Token-Transfer
#0 - c4-pre-sort
2024-01-24T08:12:52Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2024-01-24T08:13:01Z
raymondfam marked the issue as primary issue
#2 - raymondfam
2024-01-24T08:14:00Z
Inadequate elaboraion.
#3 - alex-ppg
2024-02-02T10:29:34Z
The failure of the DecentBridgeAdapter
should lead to a failure of the overall cross-chain relayed transaction and permit it to be replayed until it succeeds. This will not result in loss of funds.
Stargate will indeed transmit the funds to the contract and then attempt the relay transaction to succeed. This is a correct observation and falls under #665 with a partial reward.
#4 - c4-judge
2024-02-02T10:30:02Z
alex-ppg marked the issue as duplicate of #665
#5 - c4-judge
2024-02-02T10:30:05Z
alex-ppg marked the issue as satisfactory
#6 - c4-judge
2024-02-02T10:30:09Z
alex-ppg marked the issue as partial-50
#7 - c4-judge
2024-02-04T23:05:25Z
alex-ppg changed the severity to 2 (Med Risk)