The FundWithdraw instruction in the program contains a circular dependency in its account validation logic. The fund account's PDA is derived using fund.name, but fund.name cannot be accessed until the fund account is loaded. This causes the validation to fail unless the PDA is explicitly passed in the transaction.
The bug occurs in the #[derive(Accounts)] struct for FundWithdraw:
The seeds for the PDA derivation include fund.name.as_bytes().
However, fund.name is not accessible at the time of validation because the fund account has not yet been loaded.
This creates a circular dependency. The PDA derivation requires fund.name, but fund.name can only be accessed after the fund account is validated.
The validation works only if the PDA is explicitly passed in the transaction.
If the PDA is not passed, the validation fails because fund.name cannot be retrieved during the derivation process.
The FundWithdraw instruction will fail unless the PDA is explicitly passed in the transaction, limiting the program's flexibility and usability.
Developers and users may encounter unexpected errors when interacting with the program, leading to confusion and frustration.
Identified the circular dependency during code inspection.
To resolve this issue, pass the name as instruction to FundWithdraw struct and as a argument in withdraw function
This is actually not valid, because PDA verification is happening after the account is loaded by Anchor. Also, since this is a `withdraw` function, the `Fund` account is already initialized and contains the name field. This is different from the initial account creation scenario (`FundCreate`) where you wouldn't have access to the data yet. In the `FundWithdraw` instruction the `fund.name` is used as part of the seeds and serves as an additional verification that the correct `Fund` account is used. The PDA verification works correctly because the `Fund` account already exists and contains the required `name` field when the function is called. If the account doesn't exist, it is expected that the function will not work. This can be easily tested using the tests from the repository.
This is actually not valid, because PDA verification is happening after the account is loaded by Anchor. Also, since this is a `withdraw` function, the `Fund` account is already initialized and contains the name field. This is different from the initial account creation scenario (`FundCreate`) where you wouldn't have access to the data yet. In the `FundWithdraw` instruction the `fund.name` is used as part of the seeds and serves as an additional verification that the correct `Fund` account is used. The PDA verification works correctly because the `Fund` account already exists and contains the required `name` field when the function is called. If the account doesn't exist, it is expected that the function will not work. This can be easily tested using the tests from the repository.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.