📄

Report #27958

Report Date
January 22, 2024
Status
Confirmed
Payout
1,000

Attacker can steal one `root` at a time from other users

Report Info

Report ID

#27958

Report type

Smart Contract

Has PoC?

Yes

Target

https://etherscan.io/address/0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5

Impacts

  • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
  • Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)

Bug Description

By calling SiloFacet:transferDeposit() with an amount of 0, an attacker is able to steal one wei of root at any time from any other user. This is due to a lack of zero-value transfer checks in transferDeposit(), as well as the following calculation in LibSilo:

roots = stalk == s.a[sender].s.stalk ? s.a[sender].roots : s.s.roots.sub(1).mul(stalk).div(s.s.stalk).add(1);

https://github.com/BeanstalkFarms/Beanstalk/blob/bfc0617b5a325ba57c48518468d112b55656badd/protocol/contracts/libraries/Silo/LibSilo.sol#L314

When stalk == 0 and the victim (sender) has a balance, we hit the "false" case of this statement. This equation can be rephrased as: (a - 1) * 0 / b + 1, which will always equal 1, given a and b are positive numbers.

Further in the function, this roots value is then subtracted from the sender root balance, and added to the recipient's:

  // Subtract Stalk and Roots from the 'sender' balance.
        s.a[sender].s.stalk = s.a[sender].s.stalk.sub(stalk);
        s.a[sender].roots = s.a[sender].roots.sub(roots);
        emit StalkBalanceChanged(sender, -int256(stalk), -int256(roots));

        // Add Stalk and Roots to the 'recipient' balance.
        s.a[recipient].s.stalk = s.a[recipient].s.stalk.add(stalk);
        s.a[recipient].roots = s.a[recipient].roots.add(roots);

Impact

While this will not be profitable for an attacker due to gas costs, it is still technically theft and violates core invariants of the system. I have labeled it here as "direct theftield" as well as "griefing"

Risk Breakdown

Difficulty to Exploit: Easy Weakness: Calculation error CVSS2 Score: Medium

Recommendation

  • Include a 0 value transfer check
  • Rework the "false" case of the offending

Proof of concept

See gist

BIR-11: Stalk Ownership Griefing

BIC Response

After reviewing your bug report, we believe that it is in scope for our bug bounty program and the threat level is Medium.

Based on our bounty page, this submission's ( Smart Contract - Medium ) reward is based on a set of internal criteria established by the BIC (with a minimum reward of USD 1 000), primarily taking into account the exploitability of the bug, the impact it causes and likelihood of the vulnerability presenting itself.

The BIC determined that the impact of this issue is low given that roots cannot be redeemed for any underlying value and the costs of any form of an "attack" would not be profitable by a significant margin. Thus, the most applicable impact in scope is griefing and any "attack" related to this bug report would have an extremely low likelihood. For these reasons, the BIC has determined that this bug report be rewarded 1,000 Beans.