prePO contest - bin2chen's results

Decentralized Exchange for Pre-IPO Stocks & Pre-IDO Tokens.

General Information

Platform: Code4rena

Start Date: 09/12/2022

Pot Size: $36,500 USDC

Total HM: 9

Participants: 69

Period: 3 days

Judge: Picodes

Total Solo HM: 2

Id: 190

League: ETH

prePO

Findings Distribution

Researcher Performance

Rank: 33/69

Findings: 1

Award: $210.78

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Trust

Also found by: 0Kage, Parth, aviggiano, ayeslick, bin2chen, cccz, chaduke, fs0c, hansfriese, imare, mert_eren, rvierdiiev

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-310

Awards

210.7761 USDC - $210.78

External Links

Lines of code

https://github.com/prepo-io/prepo-monorepo/blob/3541bc704ab185a969f300e96e2f744a572a3640/apps/smart-contracts/core/contracts/WithdrawHook.sol#L66-L72

Vulnerability details

Impact

The maximum withdrawal value per Period for the user may be much smaller than userWithdrawLimitPerPeriod

Proof of Concept

WithdrawHook#hook() will limit the user's maximum withdrawal per Period. The logic is: when a new Period , the new Period starts counting from 0. But there is a logic error that causes this: only the first user of the Period is recalculated, the other users are not recalculated, and the new Period follows the userToAmountWithdrawnThisPeriod[_sender] of the previous cycle

lastUserPeriodReset needs to be changed to mapping(address => uint256), independent for each user

  function hook(
    address _sender,
    uint256 _amountBeforeFee,
    uint256 _amountAfterFee
  ) external override onlyCollateral {
..

    if (lastUserPeriodReset + userPeriodLength < block.timestamp) {
      lastUserPeriodReset = block.timestamp; //***@audit All users share a common “lastUserPeriodReset” ***//
      userToAmountWithdrawnThisPeriod[_sender] = _amountBeforeFee;  //**@audit only first user of period,  counting from 0***//
    } else {
      require(userToAmountWithdrawnThisPeriod[_sender] + _amountBeforeFee <= userWithdrawLimitPerPeriod, "user withdraw limit exceeded");
      userToAmountWithdrawnThisPeriod[_sender] += _amountBeforeFee;
    }

  }

Tools Used

lastUserPeriodReset needs to be changed to mapping(address => uint256), independent for each user

contract WithdrawHook is IWithdrawHook, TokenSenderCaller, SafeAccessControlEnumerable {
..
- uint256 private lastUserPeriodReset;
+ mapping(address => uint256) private lastUserPeriodReset;

...

  function hook(
    address _sender,
    uint256 _amountBeforeFee,
    uint256 _amountAfterFee
  ) external override onlyCollateral {
...

-   if (lastUserPeriodReset + userPeriodLength < block.timestamp) {
-     lastUserPeriodReset = block.timestamp;
-     userToAmountWithdrawnThisPeriod[_sender] = _amountBeforeFee;
-   } else {
-     require(userToAmountWithdrawnThisPeriod[_sender] + _amountBeforeFee <= userWithdrawLimitPerPeriod, "user withdraw limit exceeded");
-     userToAmountWithdrawnThisPeriod[_sender] += _amountBeforeFee;
-   }

+   if (lastUserPeriodReset[_sender] + userPeriodLength < block.timestamp) {
+     lastUserPeriodReset[_sender] = block.timestamp;
+     userToAmountWithdrawnThisPeriod[_sender] = _amountBeforeFee;
+   } else {
+     userToAmountWithdrawnThisPeriod[_sender] += _amountBeforeFee;
+   }
+   require(userToAmountWithdrawnThisPeriod[_sender] <= userWithdrawLimitPerPeriod, "user withdraw limit exceeded"); 

...

#0 - hansfriese

2022-12-14T18:04:41Z

duplicate of #310

#1 - c4-judge

2022-12-19T09:33:09Z

Picodes marked the issue as duplicate of #310

#2 - c4-judge

2023-01-01T17:21:04Z

Picodes marked the issue as satisfactory

#3 - c4-judge

2023-01-09T20:35:11Z

Picodes changed the severity to 3 (High Risk)

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter