code-423n4 / 2023-06-lybra-findings

8 stars 7 forks source link

Users can grab free esLBR #156

Open code423n4 opened 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/miner/ProtocolRewardsPool.sol#L135-L140

Vulnerability details

Impact

The vulnerability allows users to obtain esLBR tokens without burning any LBR tokens when the amount being burned is small enough. This results in users acquiring free esLBR tokens, leading to direct theft ot funds.

Proof of Concept

ProtocolRewardPool's grabEsLBR is used to purchase the accumulated amount of pre claimed lost esLBR in the contract using LBR.

    function grabEsLBR(uint256 amount) external {
        require(amount > 0, "QMG");
        grabableAmount -= amount;
        LBR.burn(msg.sender, (amount * grabFeeRatio) / 10000);
        esLBR.mint(msg.sender, amount);
    }

The grabFeeRatio has a default value of 3000, but can be increased up to 8000.

    function setGrabCost(uint256 _ratio) external onlyOwner {
        require(_ratio <= 8000, "BCE");
        grabFeeRatio = _ratio;
    }

However, due to precision loss when performing calculations with small numbers, it is possible for users to burn 0 LBR tokens while still receiving the full amount of esLBR tokens. This happens when the result of (amount * grabFeeRatio) / 10000 is rounded down to 0.

The vulnerability lies in the fact that users can exploit this precision loss to acquire esLBR tokens without paying the required LBR tokens.

Here's a coded PoC how that would happen:

https://github.com/bytes032/playground/blob/5fd99efe9fc4157f0a4c927c5c48288fa113242b/test/6_PurchaseOtherEarningsFlow.t.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "forge-std/Test.sol";
import "forge-std/console.sol";

contract Test6 is Test {
  function testGrabbableAmount() external {
    uint256 x = 8000;
    uint256 y = 10000;
    console.log((1 wei * 3000) / y);
  }
}

Tools Used

Manual review

Recommended Mitigation Steps

Implement a minimum threshold for the amount parameter in the grabEsLBR function to ensure that users cannot burn 0 LBR tokens while still receiving esLBR tokens. This threshold should be set considering the precision limitations of the calculations involved.

function grabEsLBR(uint256 amount) external {
+    require(amount * grabFeeRatio) / 10000 > 0, "Amount must be above the minimum threshold");
    // Rest of the function code
}

Assessed type

Other

c4-pre-sort commented 1 year ago

JeffCX marked the issue as primary issue

JeffCX commented 1 year ago

this is true, but I doubt mint 1wei by 1wei will compensate the gas fee, will leave for sponsor review, sounds QA

c4-pre-sort commented 1 year ago

JeffCX marked the issue as low quality report

c4-pre-sort commented 1 year ago

JeffCX marked the issue as high quality report

c4-sponsor commented 1 year ago

LybraFinance marked the issue as disagree with severity

c4-judge commented 1 year ago

0xean changed the severity to QA (Quality Assurance)

c4-sponsor commented 1 year ago

LybraFinance marked the issue as sponsor confirmed