code-423n4 / 2024-05-olas-findings

12 stars 3 forks source link

Arbitrary tokens and data can be bridged to `GnosisTargetDispenserL2` to manipulate staking incentives #22

Open c4-bot-9 opened 2 months ago

c4-bot-9 commented 2 months ago

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, the onTokenBridged() 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 in DefaultTargetDispenserL2 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

  1. Attacker calls relayTokensAndCall() on the Omnibridge on L1 to send any tokens to the GnosisTargetDispenserL2 contract on L2
  2. Attacker includes malicious staking data in the payload parameter
  3. onTokenBridged() is called on GnosisTargetDispenserL2, which invokes _receiveMessage() to process the data
  4. Since the L1 sender is not validated, the malicious data is accepted and fake staking incentives are distributed

Tools 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:

  1. When bridging tokens, only send the token amount without any data via relayTokens()
  2. Always transmit the staking data through the AMB via requireToPassMessage()
  3. Remove the onTokenBridged() callback from GnosisTargetDispenserL2

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

c4-sponsor commented 2 months ago

kupermind (sponsor) confirmed

c4-judge commented 2 months ago

0xA5DF marked the issue as selected for report

c4-judge commented 2 months ago

0xA5DF marked the issue as satisfactory

0xA5DF commented 2 months ago

High severity seems appropriate, given that this can lead to the distribution of staking incentives to arbitrary targets.

vsharma4394 commented 1 month ago

Fixed