Summary
The contract allows fund creation with a goal amount of zero, which could be misleading to contributors.
Vulnerability Details
The fund_create function doesn't validate that the goal amount is reasonable (greater than zero), allowing the creation of funds with meaningless fundraising goals.
pub fn fund_create(ctx: Context<FundCreate>, name: String, description: String, goal: u64) -> Result<()> {
let fund = &mut ctx.accounts.fund;
fund.name = name;
fund.description = description;
fund.goal = goal;
fund.deadline = 0;
fund.creator = ctx.accounts.creator.key();
fund.amount_raised = 0;
fund.dealine_set = false;
Ok(())
}
Impact
Funds with zero goals could confuse contributors and potentially be used to trick users by making it unclear when the funding target has been reached.
POC
Add to tests/rustfund.ts:
it("Can create a fund with zero goal", async () => {
const zeroGoalFundName = "Zero Goal Fund";
const [zeroGoalFundPDA] = await PublicKey.findProgramAddress(
[Buffer.from(zeroGoalFundName), creator.publicKey.toBuffer()],
program.programId
);
ā
await program.methods
.fundCreate(zeroGoalFundName, description, new anchor.BN(0))
.accounts({
fund: zeroGoalFundPDA,
creator: creator.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
.rpc();
ā
const fund = await program.account.fund.fetch(zeroGoalFundPDA);
console.log(`Created fund with goal amount: ${fund.goal.toString()}`);
});
Output:
========================================
š BUG REPORT [LOW]: No Fund Goal Validation
----------------------------------------
Description: The program allows creating funds with zero or invalid goal amounts
Evidence: Created fund with goal amount: 0
========================================
Tools Used
Recommendations
Add validation to ensure the goal is greater than zero:
pub fn fund_create(ctx: Context<FundCreate>, name: String, description: String, goal: u64) -> Result<()> {
// Validate goal is greater than zero
+ if goal == 0 {
+ return Err(ErrorCode::InvalidGoalAmount.into());
}
let fund = &mut ctx.accounts.fund;
fund.name = name;
fund.description = description;
fund.goal = goal;
fund.deadline = 0;
fund.creator = ctx.accounts.creator.key();
fund.amount_raised = 0;
fund.dealine_set = false;
Ok(())
}