Platform: Code4rena
Start Date: 23/06/2023
Pot Size: $60,500 USDC
Total HM: 31
Participants: 132
Period: 10 days
Judge: 0xean
Total Solo HM: 10
Id: 254
League: ETH
Rank: 68/132
Findings: 1
Award: $80.46
🌟 Selected for report: 0
🚀 Solo Findings: 0
80.4648 USDC - $80.46
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L120-L122 https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L60 https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L67
In LybraGovernance.sol, it has three types of vote. https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L120-L122
forVotes = proposalData[proposalId].supportVotes[0]; againstVotes = proposalData[proposalId].supportVotes[1]; abstainVotes = proposalData[proposalId].supportVotes[2];
proposalData[proposalId].supportVotes[0]
should be the amount of the vote for the proposal. But LybraGovernance._voteSucceeded
and LybraGovernance._quorumReached
take proposalData[proposalId].supportVotes[1]
as forVotes
.
LybraGovernance.proposals
shows three types of support votes. And type 0 is forVote
.
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L120-L122
function proposals(uint256 proposalId) external view returns (uint256 id, address proposer, uint256 eta, uint256 startBlock, uint256 endBlock, uint256 forVotes, uint256 againstVotes, uint256 abstainVotes, bool canceled, bool executed) { id = proposalId; eta = proposalEta(proposalId); startBlock = proposalSnapshot(proposalId); endBlock = proposalDeadline(proposalId); proposer = proposalProposer(proposalId); forVotes = proposalData[proposalId].supportVotes[0]; againstVotes = proposalData[proposalId].supportVotes[1]; abstainVotes = proposalData[proposalId].supportVotes[2]; ProposalState currentState = state(proposalId); canceled = currentState == ProposalState.Canceled; executed = currentState == ProposalState.Executed; }
However, LybraGovernance._voteSucceeded
and LybraGovernance._quorumReached
consider type 1 as forVotes
.
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L60
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/governance/LybraGovernance.sol#L67
/** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view override returns (bool){ return proposalData[proposalId].supportVotes[1] + proposalData[proposalId].supportVotes[2] >= quorum(proposalSnapshot(proposalId)); } /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view override returns (bool){ return proposalData[proposalId].supportVotes[1] > proposalData[proposalId].supportVotes[0]; }
Manual Review
Correct those functions:
/** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view override returns (bool){ - return proposalData[proposalId].supportVotes[1] + proposalData[proposalId].supportVotes[2] >= quorum(proposalSnapshot(proposalId)); + return proposalData[proposalId].supportVotes[0] + proposalData[proposalId].supportVotes[2] >= quorum(proposalSnapshot(proposalId)); } /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view override returns (bool){ - return proposalData[proposalId].supportVotes[1] > proposalData[proposalId].supportVotes[0]; + return proposalData[proposalId].supportVotes[0] > proposalData[proposalId].supportVotes[1]; }
Error
#0 - c4-pre-sort
2023-07-04T13:43:09Z
JeffCX marked the issue as duplicate of #15
#1 - c4-judge
2023-07-28T15:33:13Z
0xean marked the issue as satisfactory