Open code423n4 opened 1 year ago
raymondfam marked the issue as duplicate of #69
raymondfam marked the issue as high quality report
The severity should be medium.
raymondfam marked the issue as not a duplicate
raymondfam marked the issue as duplicate of #27
HickupHH3 marked the issue as not a duplicate
HickupHH3 changed the severity to 2 (Med Risk)
HickupHH3 marked the issue as primary issue
Valid griefing concern.
HickupHH3 marked the issue as selected for report
asselstine (sponsor) acknowledged
Lines of code
https://github.com/GenerationSoftware/pt-v5-vault-boost/blob/9d640051ab61a0fdbcc9500814b7f8242db9aec2/src/VaultBooster.sol#L142-L165 https://github.com/GenerationSoftware/pt-v5-vault-boost/blob/9d640051ab61a0fdbcc9500814b7f8242db9aec2/src/VaultBooster.sol#L211-L237
Vulnerability details
Impact
setBoost()
function inVaultBooster
, which allows the owner to configure boost parameters for a specific token (tokenOut
)._initialAvailable
to ensure it does not exceed the contract's balance.liquidate()
through the Liquidation Pair contract, reducing the contract's balance. As a result, the owner's transaction will revert, preventing the update of the liquidation pair and other boost parameters.1 wei
is sufficient to prevent the owner from configuring the boost parameters for as long as needed. This allows the attacker to maintain control and hinder the owner's ability to update the boost settings._multiplierOfTotalSupplyPerSecond
and_tokensPerSecond
when needed could lead to suboptimal boost strategies, inefficiencies, and missed opportunities for the associated prize vault. Flexibility in adjusting these parameters is crucial for adapting to changing market conditions and maintaining competitiveness in the dynamic DeFi ecosystem.Proof of Concept
Assembling this PoC will take a little work as the standard tests used only mock addresses instead of actual contracts.
/2023-08-pooltogether/pt-v5-vault-boost/test/PoC
/2023-08-pooltogether/pt-v5-vault-boost/test/PoC/MockERC20.sol
import "openzeppelin/token/ERC20/ERC20.sol";
contract MockERC20 is ERC20 { constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {}
function mint(address to, uint256 amount) public { _mint(to, amount); } }
/2023-08-pooltogether/pt-v5-vault-boost/test/PoC/PoC.t.sol
import "forge-std/Test.sol"; import "forge-std/console.sol";
import "./MockERC20.sol"; import "./LiquidationPair.sol";
import { SD1x18, unwrap, UNIT, sd1x18 } from "prb-math/SD1x18.sol"; import { UD2x18, ud2x18 } from "prb-math/UD2x18.sol";
import { VaultBooster, Boost, UD60x18, UD2x18, InitialAvailableExceedsBalance, OnlyLiquidationPair, UnsupportedTokenIn, InsufficientAvailableBalance } from "../../src/VaultBooster.sol"; import { PrizePool, TwabController, ConstructorParams, IERC20 } from "pt-v5-prize-pool/PrizePool.sol";
contract PoC is Test {
// Tons of params required to setup the whole PoolTogether system
ConstructorParams params; VaultBooster booster; LiquidationPair liquidationPair; ILiquidationSource source; TwabController twabController; PrizePool prizePool; MockERC20 boostToken; MockERC20 prizeToken;
address vault; SD59x18 decayConstant = wrap(0.001e18); uint32 periodLength = 1 days; uint32 periodOffset = 1 days; uint32 targetFirstSaleTime = 12 hours; uint112 initialAmountIn = 1e18; uint112 initialAmountOut = 1e18; uint256 minimumAuctionAmount = 0; uint32 drawPeriodSeconds = 1 days; uint64 lastClosedDrawStartedAt = uint64(block.timestamp + 1 days); uint8 initialNumberOfTiers = 3; address drawManager = address(this);
function setUp() public { //TokenIn prizeToken = new MockERC20("PrizeToken", "PT");
}
function testFrontRun() public { vm.warp(0);
} }
Tools Used
Manual Review
Recommended Mitigation Steps
Assessed type
Other