Summary
Producers can join events in the MartenitsaEvent.sol::joinEvent
function.
Vulnerability Details
As per the documentation, a Producer should not be able to join an event. If a Producer collects the amount of HealthTokens required healthTokenRequirement
to join the event, then they will not be stopped from joining. In the MartenitsaEvent.sol::joinEvent
function, the line:
require(!isProducer[msg.sender], "Producers are not allowed to participate");
Is only stopping producers set in the MartenitsaEvent.sol
contract from joining, but not Producers set in the MartenitsaToken.sol
contract.
Impact
The test below passes showing how a user can collect enough HealthTokens, then be assigned as a Producer, and then join the Martenitsa Event.
modifier eligibleForReward() {
vm.startPrank(chasy);
martenitsaToken.createMartenitsa("bracelet");
martenitsaToken.createMartenitsa("bracelet");
martenitsaToken.createMartenitsa("bracelet");
marketplace.listMartenitsaForSale(0, 1 wei);
marketplace.listMartenitsaForSale(1, 1 wei);
marketplace.listMartenitsaForSale(2, 1 wei);
martenitsaToken.approve(address(marketplace), 0);
martenitsaToken.approve(address(marketplace), 1);
martenitsaToken.approve(address(marketplace), 2);
marketplace.makePresent(bob, 0);
marketplace.makePresent(bob, 1);
marketplace.makePresent(bob, 2);
vm.stopPrank();
_;
}
modifier activeEvent() {
martenitsaEvent.startEvent(1 days);
_;
}
function testProducersCanJoinEvent() public activeEvent eligibleForReward {
vm.prank(bob);
marketplace.collectReward();
producers.push(bob);
martenitsaToken.setProducers(producers);
vm.startPrank(bob);
healthToken.approve(address(martenitsaEvent), 10 ** 18);
martenitsaEvent.joinEvent();
vm.stopPrank();
assert(healthToken.balanceOf(bob) == 0);
assert(healthToken.balanceOf(address(martenitsaEvent)) == 10 ** 18);
assert(martenitsaEvent.getParticipant(bob) == true);
assert(martenitsaEvent.isProducer(bob) == true);
assert(martenitsaToken.isProducer(bob) == true);
}
Tools Used
--Foundry
Recommendations
It is recommended to also check for Producers who are assigned in the MartenitsaToken.sol
contract and prevent them from joining.
MartenitsaToken public martenitsaToken;
function joinEvent() external {
require(block.timestamp < eventEndTime, "Event has ended");
require(!_participants[msg.sender], "You have already joined the event");
require(!isProducer[msg.sender], "Producers are not allowed to participate");
+ require(!martenitsaToken.isProducer(msg.sender), "Producers are not allowed to participate");
require(_healthToken.balanceOf(msg.sender) >= healthTokenRequirement, "Insufficient HealthToken balance");
_participants[msg.sender] = true;
participants.push(msg.sender);
emit ParticipantJoined(msg.sender);
(bool success) = _healthToken.transferFrom(msg.sender, address(this), healthTokenRequirement);
require(success, "The transfer is not successful");
_addProducer(msg.sender);
}