Closed code423n4 closed 1 year ago
Interesting but it is more a design choice than a security finding, as there are incentives to create proposal (as they can get funded) so it seems reasonable to expect > 10 proposals to be created
Picodes changed the severity to QA (Quality Assurance)
This previously downgraded issue has been upgraded by Picodes
This previously downgraded issue has been upgraded by Picodes
Picodes marked the issue as duplicate of #274
Picodes marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-05-ajna/blob/fc70fb9d05b13aee2b44be2cb652478535a90edd/ajna-grants/src/grants/base/StandardFunding.sol#L357-L358
Vulnerability details
Impact
This issue could lead to a scenario where a proposal with zero or insufficient funding votes could be executed.
Proof of Concept
Ajna's grant system allows any project to submit a proposal consisting of a desired Ajna token quantity and the recipient's address. The system uses a two-stage process, where proposals first go through a screening stage, and the top 10 most supported proposals are selected for a funding stage. Ajna token holders can vote for these proposals in this stage using a quadratic system.
https://github.com/code-423n4/2023-05-ajna/blob/fc70fb9d05b13aee2b44be2cb652478535a90edd/ajna-grants/src/grants/base/StandardFunding.sol#L300-L340
After the voting period concludes, the winning proposals are determined. The winning slate is the one that maximizes the sum of the net number of votes cast in favor of the proposals, while ensuring the total budget of the winning proposals does not exceed the Grant Budget Ceiling (GBC). These checks occur in the
validateSlate
function.https://github.com/code-423n4/2023-05-ajna/blob/fc70fb9d05b13aee2b44be2cb652478535a90edd/ajna-grants/src/grants/base/StandardFunding.sol#L421-L454
However, an issue arises when only a single proposal passed the screening period. Regardless of whether it receives enough funding votes, it will be the only one in the potential slate, and this proposal will get executed. The following solidity function,
testUnderfundedProposal
, demonstrates this issue.https://github.com/code-423n4/2023-05-ajna/blob/fc70fb9d05b13aee2b44be2cb652478535a90edd/ajna-grants/src/grants/base/StandardFunding.sol#L860-L865
So, even if a proposal has 0
fundingVotesReceived
, it will still get executed. It would be absolutely normal for a proposal to have 0 votes, since the variable that accounts for its an integer. However, having a total of 0 votes doesn't mean its supposed to get funded.Here's a PoC which showcases the issue.
It is possible to argue that the flawed proposal may enter the top-ranked slate, but it could be supplanted by an alternative top slate containing distinct proposals before the period concludes, as long as the latter slate is more optimal. Consequently, this could potentially exclude the invalid proposal from consideration.
However, if there are fewer than 10 proposals in the pool during the screening period (noting that new proposals cannot be submitted after the screening period has ended), there's nothing to replace the invalid proposal with and no way to stop it from getting executed.
Tools Used
Manual review
Recommended Mitigation Steps
To prevent under-voted proposals from being executed, the code should be adjusted to include a minimum vote threshold for proposals, irrespective of the number of proposals that pass the screening phase. This way, a proposal would require a minimum number of votes before it can be executed, ensuring that only proposals with sufficient community support are funded.
This can be achieved by changing
<
to<=
here.Assessed type
Invalid Validation