Ajna Protocol - Juntao's results

A peer to peer, oracleless, permissionless lending protocol with no governance, accepting both fungible and non fungible tokens as collateral.

General Information

Platform: Code4rena

Start Date: 03/05/2023

Pot Size: $60,500 USDC

Total HM: 25

Participants: 114

Period: 8 days

Judge: Picodes

Total Solo HM: 6

Id: 234

League: ETH

Ajna Protocol

Findings Distribution

Researcher Performance

Rank: 57/114

Findings: 2

Award: $107.57

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: hyh

Also found by: Jiamin, Juntao, aashar, bytes032, circlelooper, mrpathfindr

Labels

bug
2 (Med Risk)
satisfactory
edited-by-warden
duplicate-465

Awards

71.327 USDC - $71.33

External Links

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-grants/src/grants/base/StandardFunding.sol#L441

Vulnerability details

Impact

Proposals received 0 vote in funding stage may still be eligible for funding

Proof of Concept

Once the voting period ends, the winning proposals that can be executed are decided through a one week challenge period. In the challenge period, anyone can submit a set of winning proposals to execute. If is is more optimal than the previously submitted slate of proposals, then it becomes the new winning slate. This is implemented in function updateSlate(uint256[] calldata proposalIds_, uint24 distributionId_). In L310, function validateSlate(uint24 distributionId, uint256 endBlock, uint256 distributionPeriodFundsAvailable_, uint256[] calldata proposalIds_, uint256 numProposalsInSlate_) is called to check the validity of a potential slate of proposals to execute, and sum the slate's fundingVotesReceived.

function _validateSlate(uint24 distributionId_, uint256 endBlock, uint256 distributionPeriodFundsAvailable_, uint256[] calldata proposalIds_, uint256 numProposalsInSlate_) internal view returns (uint256 sum_) { // check that the function is being called within the challenge period if (block.number <= endBlock || block.number > _getChallengeStageEndBlock(endBlock)) { revert InvalidProposalSlate(); } // check that the slate has no duplicates if (_hasDuplicates(proposalIds_)) revert InvalidProposalSlate(); uint256 gbc = distributionPeriodFundsAvailable_; uint256 totalTokensRequested = 0; // check each proposal in the slate is valid for (uint i = 0; i < numProposalsInSlate_; ) { Proposal memory proposal = _standardFundingProposals[proposalIds_[i]]; // check if Proposal is in the topTenProposals list if (_findProposalIndex(proposalIds_[i], _topTenProposals[distributionId_]) == -1) revert InvalidProposalSlate(); // account for fundingVotesReceived possibly being negative if (proposal.fundingVotesReceived < 0) revert InvalidProposalSlate(); // update counters sum_ += uint128(proposal.fundingVotesReceived); // since we are converting from int128 to uint128, we can safely assume that the value will not overflow totalTokensRequested += proposal.tokensRequested; // check if slate of proposals exceeded budget constraint ( 90% of GBC ) if (totalTokensRequested > (gbc * 9 / 10)) { revert InvalidProposalSlate(); } unchecked { ++i; } } }

If the proposals in the submitted slate are in the topTenProposals list, and none of the proposals' funding votes received being negative, then the total funding votes received by all proposals in the proposed slate will be returned. As confirmed with sponsor team, proposals received 0 vote should not be eligible for funding, however, as it can be seen in L441, there is no checking for fundingVotesReceived being 0, which means proposals received 0 vote in may still be eligible for funding as long as there is no other proposal with higher votes.

if (proposal.fundingVotesReceived < 0) revert InvalidProposalSlate();

Tools Used

Manual Review

Please consider to change L441 as following:

if (proposal.fundingVotesReceived <= 0) revert InvalidProposalSlate();

Assessed type

Access Control

#0 - c4-judge

2023-05-18T14:11:48Z

Picodes marked the issue as duplicate of #465

#1 - c4-judge

2023-05-30T20:13:03Z

Picodes 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