BriVault

First Flight #52
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: low
Invalid

There is no mechanism to ensure that winning users will definitely receive real rewards.

There is no mechanism to ensure that winning users will definitely receive real rewards.

Description

  • The protocol documentation states: Winners will share the prize pool in proportion to their deposited amount.

  • This leads ordinary users to believe that after participating in the activity, if they correctly guess the winning team, they will receive a real reward (i.e., the funds they can withdraw will cover their initial investment and yield a surplus).

  • However, once the number of users who guessed correctly is greater than the number of users who guessed incorrectly, and the difference is sufficiently large, the funds distributed equally among the winners will decrease further, potentially reaching a point where they only match or even fall below the "original invested amount".

  • If all users guess correctly, it is inevitable that the funds withdrawn by the winners will not be able to cover their initial investment.

Risk

Likelihood:

  • Inevitable when all users guess correctly.

Impact:

  • This means that even if users predict correctly, they may still face a net loss, which severely violates users' reasonable expectation of "winning means profiting".

  • Significantly reduces user willingness to participate, undermining the core economic model of the protocol.

  • If a situation occurs where "all users guess correctly but still incur losses", users may perceive the protocol rules as deceptive or flawed, leading to a crisis of trust, and potentially triggering collective protests or legal disputes.

Proof of Concept

  • Add the following function in test/BriVaultTest.t.sol, then run forge test --mt test__alllUserIsWinner -vv

function test__alllUserIsWinner() public {
// Admin sets country team information
vm.startPrank(owner);
briVault.setCountry(countries);
vm.stopPrank();
// user1 deposits all funds and bets on country team index
vm.startPrank(user1);
uint256 balanceBeforuser1_Before = mockToken.balanceOf(user1);
mockToken.approve(address(briVault), 20 ether);
uint256 user1Shares = briVault.deposit(20 ether, user1);
briVault.joinEvent(10);
vm.stopPrank();
// user2 deposits all funds and bets on country team index
vm.startPrank(user2);
uint256 balanceBeforuser2_Before = mockToken.balanceOf(user2);
mockToken.approve(address(briVault), 20 ether);
uint256 user2Shares = briVault.deposit(20 ether, user2);
briVault.joinEvent(10);
vm.stopPrank();
// user3 deposits all funds and bets on country team index
vm.startPrank(user3);
uint256 balanceBeforuser3_Before = mockToken.balanceOf(user3);
mockToken.approve(address(briVault), 20 ether);
uint256 user3Shares = briVault.deposit(20 ether, user3);
briVault.joinEvent(10);
vm.stopPrank();
// user4 deposits all funds and bets on country team index
vm.startPrank(user4);
uint256 balanceBeforuser4_Before = mockToken.balanceOf(user4);
mockToken.approve(address(briVault), 20 ether);
uint256 user4Shares = briVault.deposit(20 ether, user4);
briVault.joinEvent(10);
vm.stopPrank();
// Move timestamp to after the event ends
vm.warp(eventEndDate + 1);
// Admin announces the winning index (all users guessed the team correctly)
vm.startPrank(owner);
briVault.setWinner(10);
vm.stopPrank();
// user1 withdraws funds.
vm.prank(user1);
briVault.withdraw();
vm.assertTrue(mockToken.balanceOf(user1) < balanceBeforuser1_Before);
// user2 withdraws funds.
vm.prank(user2);
briVault.withdraw();
vm.assertTrue(mockToken.balanceOf(user2) < balanceBeforuser2_Before);
// user3 withdraws funds.
vm.prank(user3);
briVault.withdraw();
vm.assertTrue(mockToken.balanceOf(user3) < balanceBeforuser3_Before);
// user4 withdraws funds.
vm.prank(user4);
briVault.withdraw();
vm.assertTrue(mockToken.balanceOf(user4) < balanceBeforuser4_Before);
}
  • The console prints the following:

Ran 1 test for test/briVault.t.sol:BriVaultTest
[PASS] test__alllUserIsWinner() (gas: 2251094)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.45ms (1.58ms CPU time)

Recommended Mitigation

  • Add a mechanism to ensure that "as long as there are users who guess correctly, they will definitely receive a real reward".

  • For example, design a minimum reward threshold so that users who guess correctly are guaranteed a surplus.

  • This requires the protocol to provide a "reserve fund" to prevent such extreme scenarios, prioritizing the protection of user interests.

Updates

Appeal created

bube Lead Judge 19 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!