PoolTogether - ni8mare's results

A protocol for no-loss prize savings

General Information

Platform: Code4rena

Start Date: 07/07/2023

Pot Size: $121,650 USDC

Total HM: 36

Participants: 111

Period: 7 days

Judge: Picodes

Total Solo HM: 13

Id: 258

League: ETH

PoolTogether

Findings Distribution

Researcher Performance

Rank: 37/111

Findings: 2

Award: $446.12

🌟 Selected for report: 1

🚀 Solo Findings: 0

Awards

2.2492 USDC - $2.25

Labels

bug
3 (High Risk)
satisfactory
duplicate-396

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L394-L402

Vulnerability details

Impact

Anyone can call mintYieldFee in the Vault contract to mint shares for themselves, which are supposed to go to the _yieldFeeRecipient.

Proof of Concept

The comment above the function mintYieldFee says the following:

@notice Mint Vault shares to the yield fee _recipient.

https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L388

So, the intention is clearly to mint Vault shares to the _yieldFeeRecipient. But, the function lacks any check to verify whether the _recipient argument is equal to the _yieldFeeRecipient. Hence, it allows, anyone to mint themselves shares by subtracting that amount from the _yieldFeeTotalSupply.

Tools Used

Manual Review

It is recommended that the function include a modifier to prevent this or check that the _recipient be equal to the _yieldFeeRecipient

require(_yieldFeeRecipient == _recipient, "_recipient is not the same as _yieldFeeRecipient");

Assessed type

Access Control

#0 - c4-judge

2023-07-14T22:17:57Z

Picodes marked the issue as duplicate of #396

#1 - c4-judge

2023-08-05T22:04:37Z

Picodes marked the issue as satisfactory

Findings Information

🌟 Selected for report: ni8mare

Also found by: hals, ni8mare, shaka

Labels

bug
2 (Med Risk)
satisfactory
sponsor confirmed
edited-by-warden
duplicate-458

Awards

443.8749 USDC - $443.87

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L394-L402

Vulnerability details

Impact

Theoretically, it is possible to mint more than the maxMint amount using the mintYieldFee function in the Vault contract.

Proof of Concept

The functions in Vault contract like mint, mintWithPermit call the _beforeMint function which checks whether _shares are greater than maxMint amount and reverts if it's indeed the case. But, the mintYieldFee amount does not check this. The yieldFeeTotalSupply is a unit256 which gets subtracted with shares, but the maxMint only allows for uint96. So theoretically, it is possible to mint more shares than maxMint, because shares are a uint256 value, not uint96 in the function.

But, there is a scenario where the protocol should be mindful. There is no limit on the decimals of the asset tokens that are used as the vaults can be created permissionless by anyone. And shares also have the same amount of decimals. So, yieldFeeTotalSupply could accumulate in amount (even if the underlying value is less) to be greater than max(uint96) value, which makes it possible for a share greater than maxMint(max(uint96)) amount to be subtracted from yieldFeeTotalSupply and hence possible to mint shares greater than max(uint96) value.

Tools Used

Manual review

It is recommended that the protocol add the maxMint check in the mintYieldFee function.

Assessed type

Invalid Validation

#0 - c4-sponsor

2023-07-20T22:52:51Z

asselstine marked the issue as sponsor confirmed

#1 - c4-judge

2023-08-07T16:30:05Z

Picodes marked the issue as satisfactory

#2 - Picodes

2023-08-07T16:30:52Z

This finding, https://github.com/code-423n4/2023-07-pooltogether-findings/issues/89 and https://github.com/code-423n4/2023-07-pooltogether-findings/issues/458 would all be mitigated by having the check at the _mint level. Because of this I'll flag them as duplicates.

#3 - c4-judge

2023-08-07T16:31:34Z

Picodes marked the issue as primary issue

#4 - c4-judge

2023-08-07T16:32:26Z

Picodes marked issue #458 as primary and marked this issue as a duplicate of 458

#5 - PierrickGT

2023-08-09T23:42:55Z

I've moved the maxMint check into the _mint function in this PR: https://github.com/GenerationSoftware/pt-v5-vault/pull/11

There is also another edge case we need to check for. When the Vault is partially collateralized, meaning users can withdraw their full deposit but there are not enough yield available in the YieldVault to back the amount of shares minted by mintYieldFee, then the transaction should revert to avoid minting more shares and enter in an undercollateralization state. This issue has been fixed in the following PR: https://github.com/GenerationSoftware/pt-v5-vault/pull/13

Findings Information

🌟 Selected for report: ni8mare

Also found by: hals, ni8mare, shaka

Labels

bug
2 (Med Risk)
primary issue
satisfactory
selected for report
sponsor confirmed
M-04

Awards

443.8749 USDC - $443.87

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L407-L415

Vulnerability details

Impact

It is theoretically possible for the deposit amount to mint shares more than the maxMint amount

Proof of Concept

The deposit function has a check for maxDeposit and reverts if the deposit value is more than max(uint96). But, it does not check the shares to be less than maxMint amount and hence bypasses this check. Theoretically, if the assets are equal to max(uint96) and if the vault is under-collateralised, the ratio of _assetUnit to _exchangeRate is greater than or equal to 2, then the calculation in _convertToShares:

_assets.mulDiv(_assetUnit, _exchangeRate, _rounding); could return a value more than the maxMint amount. This is possible in those scenarios where the _assetUnit is a big enough number (possible, as there is no limit on the decimals of the underlying asset, and _assetUnit = 10 ** super.decimals()) and the Vault is severely under-collateralized.

Tools Used

Manual Review

Include the maxMint check in the deposit function to prevent this problem.

Assessed type

Invalid Validation

#0 - c4-sponsor

2023-07-20T23:30:53Z

asselstine marked the issue as sponsor confirmed

#1 - c4-judge

2023-08-07T15:19:55Z

Picodes marked the issue as satisfactory

#2 - c4-judge

2023-08-07T15:20:00Z

Picodes marked the issue as primary issue

#3 - c4-judge

2023-08-07T16:32:13Z

Picodes marked the issue as duplicate of #435

#5 - c4-judge

2023-08-07T16:32:28Z

Picodes marked the issue as selected for report

#6 - PierrickGT

2023-08-14T23:16:03Z

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