Omniscia Mantissa Finance Audit
MasterMantis Manual Review Findings
MasterMantis Manual Review Findings
MMS-01M: Improper Vote Management of Duplicate Entries
Type | Severity | Location |
---|---|---|
Logical Fault | MasterMantis.sol:L421-L429 |
Description:
The MasterMantis::vote
function will improperly allow the caller to supply duplicate pid
values for the votes they perform.
Given that the second for
loop within MasterMantis::vote
will overwrite whatever data was present in the userVoteItem
entry, it is possible to vote multiple times for the same pid
retaining the duplicate votes as the userVoteItem
value will be subtracted once during a vote "reset" with the last value voted.
Impact:
It is presently possible to arbitrarily inflate the totalVotes
a particular pool has, compromising the voting system of MasterMantis
.
Example:
409function vote(UserVotePayload calldata payload) external nonReentrant whenNotPaused {410 require(payload.totalVotes <= IERC20(veMnt).balanceOf(msg.sender), "Votes too high");411 gaugeUpdate();412 uint256 userVotedPidsSize = userVotedPids[msg.sender].length;413 for (uint256 i=0; i < userVotedPidsSize; i++) {414 uint256 pid = userVotedPids[msg.sender][i];415 poolInfo[pid].totalVotes -= userVoteItem[msg.sender][pid];416 delete userVoteItem[msg.sender][pid];417 }418 delete userVotedPids[msg.sender];419 uint256 voteAmount;420 uint256 numPids = payload.votes.length;421 for (uint256 i=0; i < numPids; i++) {422 uint256 amount = payload.votes[i].amount;423 require(amount > 0, "Cannot vote 0 amount");424 uint256 pid = payload.votes[i].pid;425 userVoteItem[msg.sender][pid] = amount;426 userVotedPids[msg.sender].push(pid);427 poolInfo[pid].totalVotes += amount;428 voteAmount += amount;429 }430 require(voteAmount == payload.totalVotes, "Vote Mismatch");431 userVoteTotal[msg.sender] = voteAmount;432
433 emit UserVoted(msg.sender, payload);434}
Recommendation:
We advise the MasterMantis::vote
function to either disallow duplicate pid
entries by ensuring that userVoteItem
is 0
, or to properly support duplicate entries by incrementing the userVoteItem
instead of subtracting it and pushing the pid
to the userVotedPids
solely when userVoteItem
was 0
.
We consider either of those two approaches as adequate in alleviating this exhibit.
Alleviation (418ee413ad8e26f7eea383764c19953ff31b2bf3):
The code was fixed by applying the former of the two solutions proposed, ensuring that the userVoteItem
entry of a pid
being processed is 0
before being set to a non-zero amount and thus guaranteeing that duplicate pid
values cannot be utilized when voting.