Root + Impact
Allowed organizer to manipulate the pass prices
Description
-
An organizer can call FestivalPass::configurePass as many times he want and can able to manipulate the prices ones he starts the Festival
-
EX :: consider that the organizer has set the prices initially for passes
GENERAL_PASS = 1 eth;
VIP_PASS = 2 2eth;
BACKSTAGE_PASS = 3eth;
and later what if the oranizer wants to loot more money and increases the pricess
GENERAL_PASS = 3 eth;
VIP_PASS = 6 2eth;
BACKSTAGE_PASS = 15eth;
and the people who have bought previoulsy has paid less price than the new ones, who has paid more and both are having the same facilities or rights inside the festival
Risk
Oraganizer may not follow the equality for all the individual passes
Likelihood: Medium
Impact: Medium
Proof of Concept
function test_organizerManipulatingPrices() public {
uint256 PRICE_MULTIPLIER = 3;
vm.prank(user1);
festivalPass.buyPass{value: GENERAL_PRICE}(1);
vm.startPrank(organizer);
festivalPass.configurePass(1, GENERAL_PRICE * PRICE_MULTIPLIER, GENERAL_MAX_SUPPLY);
festivalPass.configurePass(2, VIP_PRICE * PRICE_MULTIPLIER, VIP_MAX_SUPPLY);
festivalPass.configurePass(3, BACKSTAGE_PRICE * PRICE_MULTIPLIER, BACKSTAGE_MAX_SUPPLY);
vm.stopPrank();
vm.prank(user2);
vm.expectRevert("Incorrect payment amount");
festivalPass.buyPass{value: GENERAL_PRICE}(1);
}
we can paste this code in the tests file and can able to verify
Recommended Mitigation
- mapping(uint256 => uint256) public passSupply; // Current minted
- mapping(uint256 => uint256) public passMaxSupply; // Max allowed
- mapping(uint256 => uint256) public passPrice;
+ struct PassDetails {
+ uint256 passSupply;
+ uint256 passMaxSupply;
+ uint256 passPrice;
+ bool isPassActive;
+ }
+ mapping(uint256 passNo => PassDetails ) passesMap
function configurePass(
uint256 passId,
uint256 price,
uint256 maxSupply
) external onlyOrganizer {
require(!passesMap[passId][isPassActive],"This pass is already active")
require(passId == GENERAL_PASS || passId == VIP_PASS || passId == BACKSTAGE_PASS, "Invalid pass ID");
require(passesMap[passId][price] > 0, "Price must be greater than 0");
require(passesMap[passId][maxSupply] > 0, "Max supply must be greater than 0");
passPrice[passId] = price;
passMaxSupply[passId] = maxSupply;
passSupply[passId] = 0; // Reset current supply
passesMap[passId][isPassActive] = true
}
if we can depend on something like isPassActive , then we can prevent the price manipulation