BeatToken.setFestivalContract can be called exactly once and can never be changed. The BEAT token is therefore permanently bound to a single FestivalPass deployment. If the pass contract needs to be replaced (bug fix, migration, new festival season), the existing BEAT cannot be repointed, and a new festival requires a brand-new BEAT token with no carry-over of balances. The code flags this itself with an //@audit comment.
The paired write in FestivalPass (beatToken = _beatToken, :47) has no setter either, so the binding is two-sided and immutable.
Likelihood: Low. It only matters if the festival contract must be migrated or the initial binding is wrong (see L-2).
Impact: If the festival contract is compromised or must be upgraded, a new BEAT token must be deployed and all balances/allowances abandoned. Users holding BEAT against the old festival lose the ability to redeem memorabilia through a new deployment. Not exploitable by an external attacker; a design limitation.
The existing test suite already covers this. Setting the festival contract twice (to different addresses) reverts on the second call.
If migration is a real requirement, allow the owner to repoint the festival contract under a delay or with the old contract's consent, and guard against zero. If immutability is intended, document it explicitly and ensure the binding is correct at deployment.
(If migration must remain impossible, keep the latch and add NatSpec stating the one-shot lifetime binding so integrators do not assume upgradability. If migration is allowed, gate it behind a timelock or the old contract's consent.)
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.