# Sherlock Audit Mitigation Overview The Sherlock audit of the PoolTogether V5 codebase has concluded and the codebase has been udpated to mitigate the issues raised in the audit. This post outlines the changes made to the codebase as well as any recommended actions for protocol participants. > [!Important] > There is no immediate action required for depositors in PoolTogether V5. The following recommendations are for prize vault deployers, protocol bot runners, and interface operators only. > [!Note] > The core contracts in the live PoolTogether V5 deployments (Optimism, Base, and Arbitrum) are non-upgradable and will not be updated with these latest changes. There were no protocol-breaking issues found related to the live deployments, so a redploy on these networks *is **not** required*. However, some of the peripheral contracts, such as the `Claimer` will be redeployed to reflect the improvements that resulted from the audit. Deployers of prize vaults will be able to opt-in to the new claimer contract if desired. ## Issues Requiring Actions (Sorted by Protocol Participants) > The full Sherlock report is available [on their github](https://github.com/sherlock-protocol/sherlock-reports/blob/main/audits/2024.06.06%20-%20Final%20-%20PoolTogether%3A%20The%20Prize%20Layer%20for%20DeFi%20Audit%20Report.pdf). The following is a comprehensive list of issues raised in the Sherlock audit grouped by which issues directly pertain to each kind of protocol participant. There is also a full list of issues below. --- ### Depositors No immediate action required. The deployers of some prize vaults may choose to opt-in to the new claimer contract, but the depositor experience will remain exactly the same and prizes will not be interrupted. --- ### Prize Vault Deployers You can opt-in to the new claimer contract deployed at the following addresses: - Optimism: [0x220C9398b0Ee07472bF8906e44574Cb9FE3B8D90](https://optimistic.etherscan.io/address/0x220C9398b0Ee07472bF8906e44574Cb9FE3B8D90) - Base: [0xcdCE635b774DE77cdF791647601dba64a75547ba](https://basescan.org/address/0xcdCE635b774DE77cdF791647601dba64a75547ba) - Arbitrum: [0xBEA38368f2A657f00f173764f18F00e841317c73](https://arbiscan.io/address/0xBEA38368f2A657f00f173764f18F00e841317c73) This can be done by calling `setClaimer(address)` on the prize vault contract. This can be done at any time and is not mandatory, but the new claimer provides more protections for claimer bots in addition to fee structure improvements so it is recommended to switch over. The following issues were addressed with code changes to the `Claimer` contract: - [Issue 73](#73-Claims-can-be-frontrun-on-networks-with-public-mempools) - [Issue 84](#84-Claimer-fees-will-revert-if-no-contributions-were-made-during-the-draw) In addition to the new claimer contract, some minor changes have been made to the `PrizeVault` codebase to ensure it remains ERC4626 compatible under extreme scenarios, to improve liquidation logic, and to add more prize hook safety restraints for prize claimers. It is ***not*** mandatory to migrate to a new prize vault, but any new prize vaults are recommended to be deployed via the updated factory contract: - Optimism: [0xec9f59bD06465b105e719c0b0483A4Ed6A656775](https://optimistic.etherscan.io/address/0xec9f59bd06465b105e719c0b0483a4ed6a656775) - Base: [0xa55a74A457D8a24D68DdA0b5d1E0341746d444Bf](https://basescan.org/address/0xa55a74a457d8a24d68dda0b5d1e0341746d444bf) - Arbitrum: [0x8020Fb37b21E0eF1707aDa7A914baf44F9045E52](https://arbiscan.io/address/0x8020fb37b21e0ef1707ada7a914baf44f9045e52) The following issues were addressed with code changes to the `PrizeVault` and related contracts: - [Issue 163](#163-Prize-hooks-can-contain-gas-bombs) - [Issue 88](#88-Prize-vault-does-not-consider-the-yield-fee-in-the-mint-limit-when-liquidating-assets) - [Issue 134](#134-maxDeposit-does-not-comply-with-ERC4626-for-some-lossy-deposits) - [Issue 136](#136-maxRedeem-does-not-comply-with-ERC4626-when-all-assets-have-been-lost) > [!Note] > To free up bytecode size for the prize vault factory, the [`sponsor` helper function was removed from the `PrizeVault` contract](https://github.com/GenerationSoftware/pt-v5-vault/pull/118/commits/f6190ce31f12b9685741faabd734e167bc7bbeb6). If you would like to sponsor a prize vault, you can still do so by depositing and then calling `delegate(address)` on the `TwabController` with the delegate address set to the sponsorship address: `0x0000000000000000000000000000000000000001` (note the `1` at the end). --- ### Liquidation Bots Liquidation bots should be aware of [Issue 88](#88-Prize-vault-does-not-consider-the-yield-fee-in-the-mint-limit-when-liquidating-assets) and simulate all transactions before sending them onchain to ensure that unexpected reversions do not occur. --- ### Prize Claimer Bots There is a new `Claimer` contract on each network with some minor logic changes and safety improvements. Please ensure that your bots can handle prize vaults that use the old claimer as well as prize vaults that use the new claimer. Prize vault owners can update this at any time, so it is best to check which claimer is being used dynamically. The new claimer addresses on each network are as follows: - Optimism: [0x220C9398b0Ee07472bF8906e44574Cb9FE3B8D90](https://optimistic.etherscan.io/address/0x220C9398b0Ee07472bF8906e44574Cb9FE3B8D90) - Base: [0xcdCE635b774DE77cdF791647601dba64a75547ba](https://basescan.org/address/0xcdCE635b774DE77cdF791647601dba64a75547ba) - Arbitrum: [0xBEA38368f2A657f00f173764f18F00e841317c73](https://arbiscan.io/address/0xBEA38368f2A657f00f173764f18F00e841317c73) You can check which claimer a prize vault is using by calling the `claimer()` view function on the prize vault contract in question. It will return the active claimer contract that is permitted to make prize claims for that vault. The following issues were addressed with code changes to the `Claimer` contract: - [Issue 73](#73-Claims-can-be-frontrun-on-networks-with-public-mempools) - [Issue 84](#84-Claimer-fees-will-revert-if-no-contributions-were-made-during-the-draw) Claimer bots should also be aware of the following issues: - [Issue 124](#124-Claimers-will-receive-less-fees-when-including-failing-claims-in-a-claim-batch) - [Issue 163](#163-Prize-hooks-can-contain-gas-bombs) --- ### Draw Auction (RNG) Bots The audit discovered some minor issues accross the `DrawManager` and `RngWitnet` contracts. These issues do not break the protocol behaviour, but cannot be fixed on live deployments since these contracts are non-upgradable. Future prize pools on new networks will be deployed with the additional mitigations. Draw auction bots should be aware of the following issues: - [Issue 125](#125-Draw-cannot-be-awarded-if-there-are-not-enough-rewards-for-triggering-the-RNG) - [Issue 27](#27-Draws-can-be-retried-when-there-is-a-random-number-available) - [Issue 126](#126-The-RNG-auctions-can-overpay-rewards-if-Witnet-takes-too-long-to-respond-with-the-result) - [Issue 129](#129-DrawManagercanStartDraw-does-not-consider-retried-RNG-requests-when-determining-if-a-new-draw-auction-can-be-started) --- ### Prize Hook Developers The amount of arbitrary `hookData` that can be returned by the `beforePrizeClaim` hook is now limited to 32 bytes on new prize vaults. If this limit is exceeded, prize claims that use your hook will revert. The full details can can be seen in [Issue 163](#163-Prize-hooks-can-contain-gas-bombs). --- ### Core Protocol Deployers The following issues pertain to network compatibility with the protocol: - [Issue 79](#79-Linea-does-not-support-the-PUSH0-opcode) - [Issue 114](#114-The-prize-pool-does-not-handle-auto-accruing-WETH-on-Blast) - [Issue 127](#127-Witnet-is-not-available-on-some-networks-listed) --- ### Interface Operators and Statistical Analysts The following issues pertain to informational issues and statistical analysis: - [Issue 96](#96-Prize-pool-vault-portion-calculation-period-rounds-up) - [Issue 95](#95-Prize-count-estimates-round-down) - [Issue 28](#28-Prize-pool-drawTimeout-activates-one-draw-earlier-than-described) ## Complete Issue Overview ### [#27 Draws can be retried when there is a random number available](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/27) #### Summary Witnet RNG requests can fail and then be back-filled with a request fulfilled after the original. This behaviour can lead to some unexpected scenarios where the draw manager allows for a new random number to be generated even though the previous request has been backfilled. #### Codebase Mitigation [pt-v5-rng-witnet#8](https://github.com/GenerationSoftware/pt-v5-rng-witnet/pull/8) The `isRequestComplete` function on the RNG contract has been updated to only consider the *exact* request from Witnet to avoid confusion with the backfill behaviour. #### Impact on Live Deployments This behaviour was implemented before the Arbitrum deployment, but the Optimism and Base deployments are both using previous deployment logic. #### Recommended Actions RNG bot runners should be aware of the differences between Optimism, Base, and Arbitrum draw managers and should not assume that a new Witnet RNG request will backfill previously failed RNG requests on Arbitrum and future deployments. --- ### [#28 Prize pool drawTimeout activates one draw earlier than described](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/28) #### Summary The `drawTimeout` in the prize pool is described as: > "The maximum number of draws that can be missed before the prize pool is considered inactive." However, the logic is implemented such that the draw timeout is actually activated 1 draw earlier. #### Codebase Mitigation [pt-v5-prize-pool#117](https://github.com/GenerationSoftware/pt-v5-prize-pool/pull/117) The natspec description of the `drawTimeout` has been updated to describe it specifically as: > "The maximum number of draws that can pass since the last awarded draw before the prize pool is considered inactive." In addition, a minimum `drawTimeout` of `2` is now enforced in the constructor. #### Impact on Live Deployments No significant impact; The comment on the `drawTimeout` for the verified prize pool contracts reflects the out of date description. #### Recommended Actions Ensure the accuracy of any application timestamp logic that references the `drawTimeout` of the prize pool. --- ### [#38 Price Formula in TPDA Liquidation Pair does not account for a jump in liquid balance](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/38) #### Summary The TPDA liquidation pair assumes a somewhat smooth yield accrual rate to perform efficient liquidations. Proper precaution and setup should be taken when using the TPDA liquidation pair with yield sources that experience large and sudden increases in yield. #### Codebase Mitigation This is part of the TPDA liquidation design, so no changes are necessary. The `smoothingFactor` can be set to a higher value to ensure liquidations are within a desired efficiency range. #### Impact on Live Deployments No impact. #### Recommended Actions Ensure that an appropriate `smoothingFactor` is set for each yield source when deploying a new TPDA liquidation pair. If large yield jumps are expected, consider using a different strategy for liquidation. --- ### [#39 Liquidations cannot occur if the `mintLimit` is reached on a prize vault](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/39) #### Summary Prize Vaults are limited by the TWAB Controller mint limit (total supply limited by `uint96`). If a vault reaches this limit, liquidations can no longer occur unless there is no yield fee and the liquidation pair is set to liquidate assets rather than shares. #### Codebase Mitigations No mitigation required. This behaviour is a known limitation of the prize vault and should be considered before deploying a prize vault that may reach the limit. #### Impact on Live Deployments No new impact. #### Recommended Actions If a deployment is expected to reach the mint limit, consider setting the liquidation pair to liquidate underlying assets instead of prize vault shares. Otherwise, consider using a custom vault that scales down the share exchange rate such that the limit cannot be realistically reached (this would be recommended for any tokens that have 18 decimals or more and exceed 78 billion in total supply). --- ### [#73 Claims can be frontrun on networks with public mempools](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/73) #### Summary This Sherlock issue showcases a complex interaction that someone can exploit to frontrun prize claims using prize hooks by re-entering the `claimPrizes` function. While showing a unique method of frontrunning, the core aspect of the issue is that claims can be frontrun on networks with public mempools. #### Codebase Mitigations [pt-v5-claimer#32](https://github.com/GenerationSoftware/pt-v5-claimer/pull/32) A reentrancy guard has been added to the `claimPrizes` function to prevent the specific frontrun strategy presented in the issue. This does not prevent frontrunning in general, which should be mitigated by individual bot runners. #### Impact on Live Deployments The live deployments are on networks without public mempools, so frontrunning is not likely to occur if bots runners use private network providers. #### Recommended Actions Bots that claim prizes should ensure they use private network providers as well as simulate transaction results to ensure that claims won't be frontrun through the use of a reentrancy prize hook. In addition, any deployments on networks with a public mempool should use the latest `Claimer` contract to ensure reentrancy is not possible. --- ### [#79 Linea does not support the `PUSH0` opcode](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/79) #### Summary Linea does not currently support the `PUSH0` opcode. The PoolTogether V5 bytecode uses the `PUSH0` opcode, so a deployment to Linea cannot occur until their EVM is updated to support this new opcode. Opcode differences for Linea can be viewed on [evmdiff.com](https://www.evmdiff.com/diff?base=1&target=59144) #### Codebase Mitigations None. #### Impact on Live Deployments None. #### Recommended Actions Wait until Linea opcodes are updated before deploying the protocol. --- ### [#80 Bots that use a proxy contract with a fallback function to start the RNG may not receive refunded ETH on ZKSync](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/80) #### Summary The `Requestor` contract sends refunded ETH back to the caller through a `transfer` call, but ZKSync imposes a gas limit on this call, which can cause it to fail in the event of a fallback function on the callee. #### Codebase Mitigation [pt-v5-rng-witnet#9](https://github.com/GenerationSoftware/pt-v5-rng-witnet/pull/9) The ETH transfer has been updated to use `call` instead of `transfer`. #### Impact on Live Deployments No impact. #### Recommended Actions No recommended actions. --- ### [#84 Claimer fees will revert if no contributions were made during the draw](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/84) #### Summary The `Claimer` fees ramp up from the 2nd canary value to the daily prize size value over time. If either of these values are zero, the calculation will revert and the claim will not be possible unless the claimer commits to claiming the prize with zero fees. #### Codebase Mitigations [pt-v5-claimer#33](https://github.com/GenerationSoftware/pt-v5-claimer/pull/33) [pt-v5-claimer#34](https://github.com/GenerationSoftware/pt-v5-claimer/pull/34) The claim fee calculation has been modified to handle the case where there were no contributions in the draw. #### Impact on Live Deployments Prize Vaults that use the original `Claimer` contract will be subject to this limitation if no contributions occur in a draw. #### Recommended Actions Prize vault deployers should consider updating the permitted claimer to the newly deployed claimer on each of the live networks: - Optimism: [0x220C9398b0Ee07472bF8906e44574Cb9FE3B8D90](https://optimistic.etherscan.io/address/0x220C9398b0Ee07472bF8906e44574Cb9FE3B8D90) - Base: [0xcdCE635b774DE77cdF791647601dba64a75547ba](https://basescan.org/address/0xcdCE635b774DE77cdF791647601dba64a75547ba) - Arbitrum: [0xBEA38368f2A657f00f173764f18F00e841317c73](https://arbiscan.io/address/0xBEA38368f2A657f00f173764f18F00e841317c73) Claimer bots should also update their logic to support prize claims through this new claimer contract while still supporting claims through the old contract for prize vaults that choose to not opt-in to the new claimer. --- ### [#88 Prize vault does not consider the yield fee in the mint limit when liquidating assets](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/88) #### Summary When a prize vault is set to liquidate underlying assets AND has a yield fee set AND is close to the mint limit imposed by the TWAB Controller, it is possible for a liquidation to seem possible through a `TpdaLiquidationPair`, but revert when executed due to the `mintLimit` being exceeded by the accrued yield fee. #### Codebase Mitigations [pt-v5-vault#114](https://github.com/GenerationSoftware/pt-v5-vault/pull/114) The yield fee is now considered with regards to the `mintLimit` when returning the liquidatable asset balance in a prize vault. #### Impact on Live Deployments If any prize vaults use asset liquidations with a yield fee and are getting close to the mint limit, the liquidation pair for the prize vault may begin to revert when liquidating the `maxAmountOut`. #### Recommended Actions If you are the deployer of a prize vault that is subject to the specific circumstance of this issue, consider deploying a new prize vault through the new factory contract: - Optimism: [0xec9f59bD06465b105e719c0b0483A4Ed6A656775](https://optimistic.etherscan.io/address/0xec9f59bd06465b105e719c0b0483a4ed6a656775) - Base: [0xa55a74A457D8a24D68DdA0b5d1E0341746d444Bf](https://basescan.org/address/0xa55a74a457d8a24d68dda0b5d1e0341746d444bf) - Arbitrum: [0x8020Fb37b21E0eF1707aDa7A914baf44F9045E52](https://arbiscan.io/address/0x8020fb37b21e0ef1707ada7a914baf44f9045e52) Most prize vaults liquidate shares (prz- tokens) rather than assets and are not affected at all by this issue. Liquidation bot runners should also be aware of this limitation and ensure that transactions are successfully simulated before being sent onchain. --- ### [#95 Prize count estimates round down](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/95) #### Summary The estimated prize counts used to determine if enough claims ocurred to go up/down in tiers rounds down for each tier estimation. #### Codebase Mitigation No mitigation required. #### Impact on Live Deployments Any statistical calculations should be aware of the rounding behaviour in the estimated prize counts. #### Recommended Actions Check statistical formulas that use the onchain prize count estimates for accuracy. --- ### [#96 Prize pool vault portion calculation period rounds up](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/96) #### Summary The `getVaultPortion` function in the `PrizePool` contract looks back a number of draws equal to the estimated prize frequency, but this time period rounds up such that a GP period of 365 would actually look back 366 draws, which can lead to an inconsistent prize pool state since it is only built to support 365 draws of historical contribution data. #### Codebase Mitigation [pt-v5-prize-pool#115](https://github.com/GenerationSoftware/pt-v5-prize-pool/pull/115/files) The estimated prize frequency is now set to be capped at the defined GP period. #### Impact on Live Deployments There is no significant impact on live deployments since the GP period for the latest deployments was set to `91`. This issue means that the winning chance calculations for the live GPs actually looks back 92 draws rather than the expected 91. #### Recommended Actions None. --- ### [#114 The prize pool does not handle auto-accruing WETH on Blast](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/114) #### Summary WETH is an auto-accruing token on the Blast network. The prize pool would auto-accrue WETH and anyone would be able to claim this accrual on behalf of their vault by calling the `contributPrizeTokens` function. #### Codebase Mitigation [pt-v5-prize-pool#114](https://github.com/GenerationSoftware/pt-v5-prize-pool/pull/114) A Blast-specific prize pool extension contract was created that will prevent the described gameable behaviour and instead allow anyone to donate the accrued WETH to the prize pool such that everyone benefits equally from the accrual. #### Impact on Live Deployments None. #### Recommended Actions Depoloy with the new Blast-specific prize pool extension when deploying to Blast. --- ### [#124 Claimers will receive less fees when including failing claims in a claim batch](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/124) #### Summary The `feePerClaim` in the `Claimer` is calculated before the claims occur. This means that if any claims in the batch fail, the `feeRecipient` will receive slightly less fees than what they would have received if they didn't include the failing claim(s) in the batch. This is due to the variable pricing of the auction fees which raise over time and lower with each claim that occurs. #### Codebase Mitigations No mitigitation required. #### Impact on Live Deployments Prize claims that include failing claims in a batch will receive slightly less than if they excluded the failing claims from the batch. #### Recommended Actions Claimer bots should simulate claims before sending prize claim batches and should exclude any failing claims from the batches. --- ### [#125 Draw cannot be awarded if there are not enough rewards for triggering the RNG](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/125) #### Summary If there are not enough rewards available for the RNG auctions, the `finishDraw` function on the `DrawManager` will revert, causing that draw to be skipped. This is likely to only happen if there was insuffient yield generated in that draw period or if there was a network or bot outage that prevents bots from participating in the auctions for that draw. #### Codebase Mitigation [pt-v5-draw-manager#17](https://github.com/GenerationSoftware/pt-v5-draw-manager/pull/17) [pt-v5-draw-manager#18](https://github.com/GenerationSoftware/pt-v5-draw-manager/pull/18) The total rewards for auctions will be capped at 100% of the available rewards, such that even if there are not enough rewards for all the auctions, a charitable actor can still award the draw if desired. #### Impact on Live Deployments RNG auction participants should be aware of the current behaviour and ensure that they don't start the RNG process if there is likely to not be enough funding to complete the process. #### Recommended Actions RNG Bots should ensure their logic can handle this scenario on Optimism, Base, and Arbitrum deployments. Later deployments will have the mitigation fix in place, but bots should still be aware of the reward cap and not start a draw if they don't think there will be enough rewards for it to finish. --- ### [#126 The RNG auctions can overpay rewards if Witnet takes too long to respond with the result](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/126) #### Summary For `startDraw` retries and `finishDraw` calls, if the time it takes for a Witnet response to be posted onchain takes longer than the draw manger's `auctionTargetTime`, then the resulting reward is likely to be overpaid since the auction starts when the last auction was completed. #### Codebase Mitigations No mitigations required. Witnet does not store the timestamp at which it posts the RNG on the destination chain, but they claim that results should be posted around 5-10 minutes after the randomness has been generated. As long as the `auctionTargetTime` exceeds the total expected randomness generation period, the auction is not likely to be overpaid. In addition, the `maxRewards` set on the draw manager will act as the last layer of defense for any outlier auctions. #### Impact on Live Deployments The described behaviour applies to all live deployments that use Witnet (Optimism, Base, and Arbitrum). The `auctionTargetTime` is set to an hour on each of these deployments which should be plenty of time for Witnet to return the RNG results. #### Recommended Actions No actions required. --- ### [#127 Witnet is not available on some networks listed](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/127) #### Summary The audit listed current deployment networks as well as possible future networks. This issue highlights the following networks that Witnet is not yet deployed to: Blast, Linea, ZkSync, Zerion. #### Codebase Mitigations No mitigations required. #### Impact on Live Deployments No impact. #### Recommended Actions Ensure networks have a Witnet deployment before deploying. --- ### [#129 DrawManager.canStartDraw does not consider retried RNG requests when determining if a new draw auction can be started](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/129) #### Summary > [!Note] > This issue only applies to the view function logic of `canStartDraw`. The `startDraw` function uses the correct logic. The `canStartDraw` function returns false after one full `auctionDuration` has passed since the close of the last draw period regardless if a retry can be started or not. After that time has passed, `canStartDraw` will return false even though the `startDraw` function might be able to be retried. #### Codebase Mitigations [pt-v5-draw-manager#15](https://github.com/GenerationSoftware/pt-v5-draw-manager/pull/15) The `canStartDraw` time logic has been updated to provide the correct state. #### Impact on Live Deployments Base and Arbitrum `DrawManager` contracts are both subject to this bug. (The Optimism `DrawManager` is affected by an unrelated bug that disables normal retries completely, so this issue does not further limit it's functionality.) #### Recommended Actions RNG bot runners should update their logic for the Arbitrum and Base deployments to either caclulate the correct `canStartDraw` result based off the [correct implementation](https://github.com/GenerationSoftware/pt-v5-draw-manager/blob/b55a44c7ec40a28570cf677fcd3fdf19c41a295a/src/DrawManager.sol#L277), or bypass the `canStartDraw` call completely by using simulations on the `RngWitnet.startDraw` function to determine if the draw can be started/retried. New deployments going forward will not be affected by this issue. --- ### [#133 Some prizes may be claimed immediately before TWAB shutdown](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/133) #### Summary If the prize pool enters shutdown mode after the TWAB Controller expires (in 136 years), the shutdown will occur mid-draw and some prizes may already be claimed before the shutdown occurs. The shutdown balance calculations that distribute remaining prize pool funds to depositors assume that the shutdown occurs at the start of the draw; therefore any prizes that are claimed will be cutting into the shutdown balances and will cause a race condition for the remaining value to be claimed by depositors. > [!Note] > This does not occur if the prize pool shuts down due to the `drawTimeout` (aka. if the RNG source stops working before the TWAB Controller expires). #### Codebase Mitigation [pt-v5-prize-pool#116](https://github.com/GenerationSoftware/pt-v5-prize-pool/pull/116) The shutdown timestamp calculation has been changed to truncate the timestamp to the draw period, ensuring that it cannot shutdown mid-draw. #### Impact on Live Deployments Please inform your kids/grandkids that they should pay close attention to the draws on Optimism, Base, and Arbitrum and withdraw their shutdown balance immediately after the corresponding shutdown timestamps to avoid missing out on their portion of unused prizes: - Optimism: 25 May 2160, 06:00 UTC - Base: 22 June 2160, 01:00 UTC - Arbitrum: 06 July 2160, 01:00 UTC --- ### [#134 maxDeposit does not comply with ERC4626 for some lossy deposits](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/134) #### Summary The prize vault performs a "lossy deposit" check whenever funds are deposited to ensure that there was no unexpected loss immediately after the deposit; however, the `maxDeposit` function does not take this fully into consideration and there could exist some scenario where `maxDeposit` returns some non-zero value and then an immediate `deposit` of that amount causes a revert due to a lossy deposit. This behaviour would not be 4626 compliant since the `maxDeposit` function should return zero if the deposit will not go through. #### Codebase Mitigations [pt-v5-vault#113](https://github.com/GenerationSoftware/pt-v5-vault/pull/113) Extra precaution has been added to the `maxDeposit` function to return zero if the yield buffer is below half full. #### Impact on Live Deployments No significant impact; Prize Vaults may no longer be fully ERC4626 compliant if the underlying yield source is in the process of losing funds. #### Recommended Actions Any new prize vaults should be deployed through the new factory contract to ensure 4626 compliance: - Optimism: [0xec9f59bD06465b105e719c0b0483A4Ed6A656775](https://optimistic.etherscan.io/address/0xec9f59bd06465b105e719c0b0483a4ed6a656775) - Base: [0xa55a74A457D8a24D68DdA0b5d1E0341746d444Bf](https://basescan.org/address/0xa55a74a457d8a24d68dda0b5d1e0341746d444bf) - Arbitrum: [0x8020Fb37b21E0eF1707aDa7A914baf44F9045E52](https://arbiscan.io/address/0x8020fb37b21e0ef1707ada7a914baf44f9045e52) --- ### [#136 maxRedeem does not comply with ERC4626 when all assets have been lost](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/136) #### Summary In the unlikely and unfortunate scenario that the underlying yield source of a prize vault has lost all of it's assets, the `maxRedeem` function will attempt a division by zero and revert. This breaks the ERC4626 spec since this function must never revert. #### Codebase Mitigations [pt-v5-vault#112](https://github.com/GenerationSoftware/pt-v5-vault/pull/112) The division by zero edge case has been addressed in the `maxRedeem` function. #### Impact to Live Deployments No significant impact; If a yield vault has lost all funds, the depositors would likely not be worried if the prize vault is still 4626-compliant. #### Recommended Actions Any new prize vaults should be deployed through the new factory contract to ensure 4626 compliance: - Optimism: [0xec9f59bD06465b105e719c0b0483A4Ed6A656775](https://optimistic.etherscan.io/address/0xec9f59bd06465b105e719c0b0483a4ed6a656775) - Base: [0xa55a74A457D8a24D68DdA0b5d1E0341746d444Bf](https://basescan.org/address/0xa55a74a457d8a24d68dda0b5d1e0341746d444bf) - Arbitrum: [0x8020Fb37b21E0eF1707aDa7A914baf44F9045E52](https://arbiscan.io/address/0x8020fb37b21e0ef1707ada7a914baf44f9045e52) --- ### [#162 Users can setup prize hooks to control the expansion of tiers](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/162) #### Summary This was raised as an issue in this audit, but was previously [highlighted as a democratic feature of the protocol](https://pooltogether.mirror.xyz/-96mdzllmO9_9sUbd21eD4IEDJjtGZKLYOk7pgrenEI). #### Codebase Mitigations No mitigations needed. #### Impact to Live Deployments Depositors can use prize hooks to vote on the prize sizes for each prize pool. #### Recommended Actions Vote. --- ### [#163 Prize hooks can contain gas bombs](https://github.com/sherlock-audit/2024-05-pooltogether-judging/issues/163) #### Summary The `beforeClaimPrize` hook allows for some arbitrary data to be passed through to the `afterClaimPrize` call. Malicious winners can use this data to create a gas bomb in which they return an enormous amount of data that gets copied to memory and uses up all of the transaction's gas, causing the entire claim batch to revert. #### Codebase Mitigations [pt-v5-vault#115](https://github.com/GenerationSoftware/pt-v5-vault/pull/115) The arbitrary return data has been limited to 32 bytes. #### Impact on Live Deployments All previously deployed prize vaults are subject to gas bombs when claiming prizes. #### Recommended Actions Claimer bot runners should be aware of the possibility of a gas bomb in prize hooks and should simulate all transactions before sending claims onchain. In addition, new prize vaults should be deployed through the new factory contract to mitigate this issue: - Optimism: [0xec9f59bD06465b105e719c0b0483A4Ed6A656775](https://optimistic.etherscan.io/address/0xec9f59bd06465b105e719c0b0483a4ed6a656775) - Base: [0xa55a74A457D8a24D68DdA0b5d1E0341746d444Bf](https://basescan.org/address/0xa55a74a457d8a24d68dda0b5d1e0341746d444bf) - Arbitrum: [0x8020Fb37b21E0eF1707aDa7A914baf44F9045E52](https://arbiscan.io/address/0x8020fb37b21e0ef1707ada7a914baf44f9045e52) Prize hook deployers should also be aware of the new 32 byte limitation that new prize vaults will enforce and should consider using transient storage for temporarily storing large amounts of data cheaply.