Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Users can grab free esLBR #156

Open
code423n4 opened this issue Jun 28, 2023 · 7 comments
Open

Users can grab free esLBR #156

code423n4 opened this issue Jun 28, 2023 · 7 comments
Labels
bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) downgraded by judge Judge downgraded the risk level of this issue grade-a high quality report This report is of especially high quality primary issue Highest quality submission among a set of duplicates QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

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

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Jun 28, 2023
code423n4 added a commit that referenced this issue Jun 28, 2023
@c4-pre-sort
Copy link

JeffCX marked the issue as primary issue

@c4-pre-sort c4-pre-sort added the primary issue Highest quality submission among a set of duplicates label Jul 8, 2023
@JeffCX
Copy link

JeffCX commented Jul 8, 2023

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 c4-pre-sort added the low quality report This report is of especially low quality label Jul 8, 2023
@c4-pre-sort
Copy link

JeffCX marked the issue as low quality report

@c4-pre-sort
Copy link

JeffCX marked the issue as high quality report

@c4-pre-sort c4-pre-sort added high quality report This report is of especially high quality and removed low quality report This report is of especially low quality labels Jul 8, 2023
@c4-sponsor c4-sponsor added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Jul 14, 2023
@c4-sponsor
Copy link

LybraFinance marked the issue as disagree with severity

@c4-judge c4-judge removed the 3 (High Risk) Assets can be stolen/lost/compromised directly label Jul 26, 2023
@c4-judge
Copy link
Contributor

0xean changed the severity to QA (Quality Assurance)

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax labels Jul 26, 2023
@c4-sponsor
Copy link

LybraFinance marked the issue as sponsor confirmed

@c4-sponsor c4-sponsor added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Jul 27, 2023
This was referenced Jul 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) downgraded by judge Judge downgraded the risk level of this issue grade-a high quality report This report is of especially high quality primary issue Highest quality submission among a set of duplicates QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

6 participants