Skip to content

refactor: Replace inline auth checks with named modifiers (gas optimisation)#247

Open
Muneerali199 wants to merge 1 commit intoAOSSIE-Org:mainfrom
Muneerali199:fix/election-factory-modifier-gas-optimization
Open

refactor: Replace inline auth checks with named modifiers (gas optimisation)#247
Muneerali199 wants to merge 1 commit intoAOSSIE-Org:mainfrom
Muneerali199:fix/election-factory-modifier-gas-optimization

Conversation

@Muneerali199
Copy link

Summary

Replaces two ad-hoc inline if (...) revert ownership checks inside function bodies with dedicated named modifiers, reducing gas and improving code clarity.

Closes #231


Problem

Two contracts contained inline access-control checks embedded in function bodies instead of using modifiers:

Election.solccipVote()

function ccipVote(...) external electionInactive {
    if (userVoted[user]) revert AlreadyVoted();
    ...
    if (msg.sender != factoryContract) revert OwnerPermissioned(); // ← buried in body
    ...
}

ElectionFactory.soldeleteElection()

function deleteElection(uint _electionId) external {
    if (electionOwner[_electionId] != msg.sender) revert OnlyOwner(); // ← buried in body
    ...
}

Issues with this pattern:

  1. Gas: The check runs after the function preamble and any preceding logic. Failing early at the modifier position is cheaper.
  2. Readability: Access control intent is hidden inside the body; readers cannot see it from the function signature alone.

Fix

Election.sol — added onlyFactory modifier, applied to ccipVote():

modifier onlyFactory() {
    if (msg.sender != factoryContract) revert OwnerPermissioned();
    _;
}

function ccipVote(...) external electionInactive onlyFactory { ... }

ElectionFactory.sol — added parameterised onlyElectionOwner(uint) modifier, applied to deleteElection():

modifier onlyElectionOwner(uint _electionId) {
    if (electionOwner[_electionId] != msg.sender) revert OnlyOwner();
    _;
}

function deleteElection(uint _electionId) external onlyElectionOwner(_electionId) { ... }

Both patterns follow the conventions already established in their respective contracts (onlyOwner in Election.sol, onlyOwner in ElectionFactory.sol).


Files Changed

File Change
blockchain/contracts/Election.sol Added onlyFactory modifier; applied to ccipVote()
blockchain/contracts/ElectionFactory.sol Added onlyElectionOwner(uint) modifier; applied to deleteElection()

Checklist

  • No behaviour change — access control logic is identical, only position moves to modifier
  • Both new modifiers follow naming and style conventions of existing modifiers in the same files
  • ccipVote modifier order (electionInactive before onlyFactory) is intentional — time-gate first, then auth
  • No unrelated changes included
  • Branch created fresh from upstream/main

…ings

Two inline ownership/access-control checks were duplicated as ad-hoc
if-revert blocks inside function bodies. This pattern:
  1. Costs slightly more gas than a modifier because it runs after other
     function body setup (stack frame already allocated).
  2. Obscures the access-control intent from the function signature.

Changes:
- Election.sol: add onlyFactory modifier; apply to ccipVote() replacing
  the inline check. This also moves auth to modifier position (before
  the function body), which is the Solidity convention and fails faster.
- ElectionFactory.sol: add onlyElectionOwner(uint) modifier; apply to
  deleteElection() replacing the inline check. The parameterised modifier
  pattern follows the existing onlyOwner() in the same contract.

Closes AOSSIE-Org#231
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Warning

Rate limit exceeded

@Muneerali199 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 17 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43085c36-cbd4-4ec2-9651-5576ce977557

📥 Commits

Reviewing files that changed from the base of the PR and between e4df55f and 64b4e14.

📒 Files selected for processing (2)
  • blockchain/contracts/Election.sol
  • blockchain/contracts/ElectionFactory.sol
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Replace redundant require statements with Modifier-==>>Gas optimization

1 participant