Lybra Finance - sces60107's results

A protocol building the first interest-bearing omnichain stablecoin backed by LSD.

General Information

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

Lybra Finance

Findings Distribution

Researcher Performance

Rank: 68/132

Findings: 1

Award: $80.46

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: T1MOH

Also found by: 0xnev, Iurii3, KupiaSec, LaScaloneta, bytes032, cccz, devival, josephdara, pep7siup, sces60107, skyge, yjrwkk

Labels

bug
3 (High Risk)
satisfactory
duplicate-15

Awards

80.4648 USDC - $80.46

External Links

Lines of code

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

Vulnerability details

Impact

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.

Proof of Concept

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];
    }

Tools Used

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];
    }

Assessed type

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter