PoolTogether V5: Part Deux - Angry_Mustache_Man's results

A protocol for no-loss prize savings.

General Information

Platform: Code4rena

Start Date: 02/08/2023

Pot Size: $42,000 USDC

Total HM: 13

Participants: 45

Period: 5 days

Judge: hickuphh3

Total Solo HM: 5

Id: 271

League: ETH

PoolTogether

Findings Distribution

Researcher Performance

Rank: 8/45

Findings: 2

Award: $1,114.70

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: bin2chen

Also found by: Angry_Mustache_Man, Giorgio, dirk_y

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-90

Awards

321.319 USDC - $321.32

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-vault-boost/blob/9d640051ab61a0fdbcc9500814b7f8242db9aec2/src/VaultBooster.sol#L249-#L257

Vulnerability details

Impact

Accounting error in accruing at VaultBooster.sol will cause unexpected problems in VaultBooster.sol contract.

Proof of Concept

The _accrue function of VaultBooster.sol at :

https://github.com/GenerationSoftware/pt-v5-vault-boost/blob/9d640051ab61a0fdbcc9500814b7f8242db9aec2/src/VaultBooster.sol#L249-#L257

does not check whether the return variable of _computeAvailable(_tokenOut) i.e., available is greater than _tokenOut.balanceOf(address(this)).

One main problem that could occur is underflow error while withdrawing the boosted tokens

Let’s consider a case of emergency, where Owner is trying to withdraw all the boosted tokens from the contract at a time. He would call getBoost function to get information regarding available boosted tokens. Then he will try to withdraw all boosted tokens at a time . But it will cause problems as


(available balance of boosted tokens) > (_tokenOut.balanceOf(address(this)) 

And this line shown below which is present in withdraw function will cause an underflow error:


uint256 remainingBalance = availableBalance - _amount; 

Because the amount entered by Owner would be _boosts[_tokenOut].available which as we can see from above is less than (_tokenOut.balanceOf(address(this)).

Tools Used

Manual Review

Add these modifications to _accrue() :


  function _accrue(IERC20 _tokenOut) internal returns (uint256) { 

    uint256 available = _computeAvailable(_tokenOut);   

  +   uint256 total =  (available > (_tokenOut.balanceOf(address(this))) ? (_tokenOut.balanceOf(address(this)) : available; 

    _boosts[_tokenOut].available = total.toUint144(); 

    _boosts[_tokenOut].lastAccruedAt = uint48(block.timestamp); 

  

    emit BoostAccrued(_tokenOut, available); 

 +   return total; 

  } 


## Assessed type

Error

#0 - raymondfam

2023-08-08T03:12:10Z

A similarly known issue in the bot.

#1 - c4-pre-sort

2023-08-08T03:12:15Z

raymondfam marked the issue as low quality report

#2 - c4-pre-sort

2023-08-08T04:25:38Z

raymondfam marked the issue as remove high or low quality report

#3 - c4-pre-sort

2023-08-08T04:26:31Z

raymondfam marked the issue as duplicate of #90

#4 - raymondfam

2023-08-08T06:14:02Z

The severity should be medium.

#5 - c4-judge

2023-08-14T07:08:44Z

HickupHH3 changed the severity to 2 (Med Risk)

#6 - c4-judge

2023-08-14T07:09:18Z

HickupHH3 marked the issue as satisfactory

Findings Information

🌟 Selected for report: dirk_y

Also found by: Angry_Mustache_Man

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-24

Awards

793.3802 USDC - $793.38

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-cgda-liquidator/blob/7f95bcacd4a566c2becb98d55c1886cadbaa8897/src/libraries/ContinuousGDA.sol#L39

Vulnerability details

Impact

Breaks the core functionality of the Liquidation Pair contract.

Usage of wrong formula for calculation of Continuous Gradual Dutch Auction results in wrong calculation of purchase price which is basically used to find the swapAmountIn during liquidations .

Proof of Concept

Statements from PoolTogether Code4rena docs:

The LiquidationPair prices yield liquidations using a periodic Continuous Gradual Dutch Auction. It's periodic in the sense that the auction runs in periods that will be aligned with the prize pool periods. At the beginning of each period, the CGDA adjusts the emissions rate and target price so that it adapts to changing market conditions.

PoolTogether implementation of Continuous Gradual Dutch Auction uses formula:


(k/(r))*(e**((lambda)*q)/r)-1)/(e**((lambda)*T)) 

at: https://github.com/GenerationSoftware/pt-v5-cgda-liquidator/blob/7f95bcacd4a566c2becb98d55c1886cadbaa8897/src/libraries/ContinuousGDA.sol#L39

The original formula of Continuous Gradual Dutch Auction:



(k/(lambda))*(e**((lambda)*q)/r)-1)/(e**((lambda)*T)) 

First Term is k/(lambda) not (k/(r).

Reference :

Official Paradigm Article on CGDA’s which shows the correct formula

Official Github Link of Correct Implementaion of CGDA’s by Paradigm

Tools Used

Manual Review

Reimplement the first term of Formula as k/(lambda) that is k.div(_decayConstant).

Assessed type

Error

#0 - raymondfam

2023-08-07T22:11:04Z

The doc says "... many different price functions can work." So it needs not to be the exact example in the doc.

https://www.paradigm.xyz/2022/04/gda

If ever valid, the severity should be medium.

#1 - c4-pre-sort

2023-08-07T22:11:09Z

raymondfam marked the issue as low quality report

#2 - c4-pre-sort

2023-08-09T03:42:00Z

raymondfam marked the issue as remove high or low quality report

#3 - c4-pre-sort

2023-08-09T03:42:19Z

raymondfam marked the issue as duplicate of #24

#4 - c4-judge

2023-08-14T03:52:42Z

HickupHH3 marked the issue as satisfactory

#5 - c4-judge

2023-08-14T03:52:47Z

HickupHH3 changed the severity to 2 (Med 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