hats-finance / Possum-Labs--Portals--0xed8965d49b8aeca763447d56e6da7f4e0506b2d3

GNU General Public License v2.0
0 stars 2 forks source link

Incorrect Calculation of maxStakeDebt in Unstake Function #79

Open hats-bug-reporter[bot] opened 1 year ago

hats-bug-reporter[bot] commented 1 year ago

Github username: @0xmahdirostami Twitter username: 0xmahdirostami Submission hash (on-chain): 0xad0fb59acb53719666b679fc578e0f6c12114049a33c1b7b028ddb102800ec61 Severity: low

Description: Description\ As mentioned in issue #7, maxStakeDebt will be calculated in the following way:

accounts[_user].maxStakeDebt = (accounts[msg.sender].stakedBalance * maxLockDuration) / SECONDS_PER_YEAR

but in unstake function, it's calculated in the following way:

        uint256 maxStakeDebt = accounts[msg.sender].maxStakeDebt -= (_amount * maxLockDuration) / SECONDS_PER_YEAR;

Impact\ The incorrect calculation of maxStakeDebt in the unstake function may lead to inaccurate values for maxStakeDebt and availableToWithdraw.

Attachments\

  1. Proof of Concept (PoC) File

    add the following helper functions:

    function unstakeA(uint256 _amount) external nonReentrant existingAccount returns(uint256){
    _updateAccount(msg.sender,0);
    
    uint256 stakedBalance = accounts[msg.sender].stakedBalance - _amount;
    uint256 maxStakeDebt = accounts[msg.sender].maxStakeDebt - (_amount * maxLockDuration) / SECONDS_PER_YEAR;
    return(maxStakeDebt);
    }
    function unstakeB(uint256 _amount) external nonReentrant existingAccount returns(uint256){
    _updateAccount(msg.sender,0);
    
    uint256 stakedBalance = accounts[msg.sender].stakedBalance =- _amount;
    uint256 maxStakeDebt = (accounts[msg.sender].stakedBalance * maxLockDuration) / SECONDS_PER_YEAR;
    return(maxStakeDebt);
    }

    test:

    function testFuzz_mahdi(uint256 x) public {
    help_fundAndActivate();
    help_stake(); // stake 1e22
    vm.startPrank(Alice);
    vm.assume(x>0&&x<1e22);
    assertEq(portal.unstakeA(x), portal.unstakeB(x));
    }

    output:

    Failing tests:
    Encountered 1 failing test in test/fuzz/PortalFuzz.t.sol:PortalTest
    [FAIL. Reason: assertion failed; counterexample: calldata=0xbd0e12b300000000000000000000000000000000000000000000000000000000000000de args=[222]] testFuzz_mahdi(uint256) (runs: 3, μ: 1028058, ~: 1028058)
  2. Revised Code File (Optional)

    Replace the incorrect calculation with the correct formula:

    
    -           uint256 maxStakeDebt = accounts[msg.sender].maxStakeDebt -= (_amount * maxLockDuration) / SECONDS_PER_YEAR;
PossumLabsCrypto commented 1 year ago

Thank you ✅

https://github.com/PossumLabsCrypto/Portals/commit/aaaba6e63759e3546119d0c5385c47edd6082f93