Open code423n4 opened 1 year ago
MikeHathaway marked the issue as sponsor acknowledged
This is only on the first distribution period, and can easily be handled by deploying via MEV-resistant solutions such as flashbots.
MikeHathaway marked the issue as disagree with severity
Picodes changed the severity to QA (Quality Assurance)
Lines of code
https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-grants/src/grants/base/StandardFunding.sol#L119-L164 https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-grants/src/grants/GrantFund.sol#L58-L68 https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-grants/src/grants/base/StandardFunding.sol#L366-L404
Vulnerability details
Impact
After the
GrantFund
contract, which inherits theStandardFunding
contract, is deployed,treasury
is initially 0. When someone calls theGrantFund.fundTreasury
function below to increasetreasury
, a malicious actor can frontrun thisGrantFund.fundTreasury
transaction by calling the followingStandardFunding.startNewDistributionPeriod
function. Because_currentDistributionId
and_distributions[currentDistributionId].endBlock
are both 0 at that moment, calling theStandardFunding.startNewDistributionPeriod
function would makeblock.number <= currentDistributionEndBlock
false. Then, executinguint256 gbc = Maths.wmul(treasury, GLOBAL_BUDGET_CONSTRAINT)
andnewDistributionPeriod.fundsAvailable = SafeCast.toUint128(gbc)
set bothgbc
andnewDistributionPeriod.fundsAvailable
, which isfundsAvailable
for_distributions[1]
, to 0 sincetreasury
is still 0 due to the frontrunning.https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-grants/src/grants/base/StandardFunding.sol#L119-L164
https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-grants/src/grants/GrantFund.sol#L58-L68
After the frontrunning, although
treasury
becomes positive after theGrantFund.fundTreasury
transaction is executed,fundsAvailable
for_distributions[1]
remains 0. For_distributions[_currentDistributionId]
, which is_distributions[1]
, calling the followingStandardFunding.proposeStandard
function for any proposal with a positivetokensRequested
will revert becausenewProposal.tokensRequested > (currentDistribution.fundsAvailable * 9 / 10)
, which is evaluated tonewProposal.tokensRequested > 0
, would be true. Because it is meaningless to create proposals for requesting 0 AJNA tokens, no one would use theStandardFunding
contract for_distributions[1]
. As a result, theStandardFunding
contract's functionalities for proposals with positivetokensRequested
are DOS'ed for_distributions[1]
, which lasts at least 648000 blocks or about 90 days that is not a short time.https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-grants/src/grants/base/StandardFunding.sol#L366-L404
Proof of Concept
The following steps can occur for the described scenario.
GrantFund
contract is deployed, someone calls theGrantFund.fundTreasury
function.GrantFund.fundTreasury
transaction by calling theStandardFunding.startNewDistributionPeriod
function.fundsAvailable
for_distributions[1]
remains 0._distributions[_currentDistributionId]
, which is_distributions[1]
, calling theStandardFunding.proposeStandard
function for any proposal with a positivetokensRequested
will revert.tokensRequested
for_distributions[1]
using theStandardFunding
contract, this contract's functionalities for such proposals are DOS'ed for_distributions[1]
.Tools Used
VSCode
Recommended Mitigation Steps
The
StandardFunding.startNewDistributionPeriod
function can be updated to revert iftreasury
is 0.Assessed type
DoS