Open c4-bot-9 opened 2 months ago
kupermind (sponsor) confirmed
0xA5DF marked the issue as selected for report
0xA5DF marked the issue as satisfactory
High severity seems appropriate, given that this can lead to the distribution of staking incentives to arbitrary targets.
Fixed
Lines of code
https://github.com/code-423n4/2024-05-olas/blob/3ce502ec8b475885b90668e617f3983cea3ae29f/tokenomics/contracts/staking/GnosisTargetDispenserL2.sol#L99-L107
Vulnerability details
The
GnosisTargetDispenserL2
contract receives OLAS tokens and data from L1 to L2 via the Omnibridge, or just data via the AMB. When tokens are bridged, theonTokenBridged()
callback is invoked on the contract. This callback processes the received tokens and associated data by calling the internal_receiveMessage()
function.However, the
onTokenBridged()
callback does not verify the sender of the message on the L1 side (or the token received).This allows anyone to send any token to the
GnosisTargetDispenserL2
contract on L2 along with arbitrary data. The_receiveMessage()
function inDefaultTargetDispenserL2
will then process this data, assuming it represents valid staking targets and incentives.Impact
An attacker can bridge any tokens to the
GnosisTargetDispenserL2
contract on L2 with fake data for staking incentives. If the contract holds any withheld funds, these funds can be redistributed to arbitrary targets as long as they pass the checks in_processData()
.Even if the contract doesn't hold any withheld funds, the attacker can cause the amounts to be stored in
stakingQueueingNonces
and redeem them at a later point.Proof of Concept
relayTokensAndCall()
on the Omnibridge on L1 to send any tokens to theGnosisTargetDispenserL2
contract on L2payload
parameteronTokenBridged()
is called onGnosisTargetDispenserL2
, which invokes_receiveMessage()
to process the dataTools Used
Manual review
Recommended Mitigation Steps
The Omnibridge contracts do not seem to provide a way to access the original sender's address on L1 when executing the receiver callback upon receiving tokens. Hence the most sensible mitigation may be to send the bridged tokens and associated staking data separately:
relayTokens()
requireToPassMessage()
onTokenBridged()
callback fromGnosisTargetDispenserL2
This way, an attacker cannot send fake data along with the bridged tokens. The staking data will be validated to come from the authentic source on L1.
Assessed type
Access Control