Closed code423n4 closed 1 year ago
ith-harvey marked the issue as sponsor acknowledged
will do this MEV protection.
Downgrading to Low as it is the usual severity within C4 for misconfiguration issues like "initializer can be front run", etc.
Picodes changed the severity to QA (Quality Assurance)
Lines of code
https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-grants/src/grants/base/StandardFunding.sol#L119-L164 https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-grants/src/grants/GrantFund.sol#L58-L68
Vulnerability details
Impact
The deployment of GrandFund.sol and the transfer of
AJNA
tokens to the treasury can be executed separately on different blocks if not deployed through another smart contract function.There is a risk that someone could front-run the treasury funding transaction to
startNewDistributionPeriod()
with an empty treasury, wasting the first period and delaying the start of a new period with proper settings by 90 days.This risk also exists in subsequent periods if fund transfers occur after the current period has ended. In such cases, anyone could front-run the transaction to start the new period with the leftover amount from the last period. However, this is unlikely as deposits can be made in advance.
Proof of Concept
According to the deployment script and testing contract, the contract deployment and
fundTreasury()
are likely to be executed separately. In this case, someone could callstartNewDistributionPeriod()
between these two transactions to start the first granting period before thetreasury
is set.This would result in a 0 reward start, which cannot be restarted or reset with a new
treasury
amount. Each period is set to end roughly 90 days in the future, and any attempts to callstartNewDistributionPeriod()
whileblock.number
is within the current period will revert.dizzy#6247 confirmed that the contracts are immutable and not behind any upgradeable proxy. As a result, the team cannot reset the storage value with a new implementation. Additionally, there is no way to withdraw the treasury once it has been deposited unless the team realizes they are being front-run and cancels the
fundTreasury()
call in time.The following PoC code can be appended to the file
ajna-grants/test/unit/GrantFund.t.sol
. The test should pass without errors.Tools Used
Recommended Mitigation Steps
To ensure a minimum required treasury before starting a new distribution period, add a check at the beginning of the
startNewDistributionPeriod()
function. For example, verify thattreasury > 0
.The deploying process can mitigate this issue by either:
Fixing this issue in the code is strongly recommended as it mitigates not only the first period but also any other periods that require a minimum amount of
AJNA
in the treasury.Assessed type
MEV