Omniscia Beanstalk Audit
GovernanceFacet Code Style Findings
GovernanceFacet Code Style Findings
GFT-01C: Code Duplication
Type | Severity | Location |
---|---|---|
Gas Optimization | GovernanceFacet.sol:L106-L112, L127-L133, L146-L151 |
Description:
The linked code commits a particular BIP using the same statements and a single literal value difference.
Example:
97function commit(uint32 bip) external {98 require(isNominated(bip), "Governance: Not nominated.");99 require(!isActive(bip), "Governance: Not ended.");100 require(!isExpired(bip), "Governance: Expired.");101 require(102 endedBipVotePercent(bip).greaterThanOrEqualTo(C.getGovernancePassThreshold()),103 "Governance: Must have majority."104 );105
106 s.g.bips[bip].executed = true;107
108 cutBip(bip);109 pauseOrUnpauseBip(bip);110
111 incentivize(msg.sender, true, bip, C.getCommitIncentive());112 emit Commit(msg.sender, bip);113}114
115function emergencyCommit(uint32 bip) external {116 require(isNominated(bip), "Governance: Not nominated.");117 require(118 block.timestamp >= timestamp(bip).add(C.getGovernanceEmergencyPeriod()),119 "Governance: Too early.");120 require(isActive(bip), "Governance: Ended.");121 require(122 bipVotePercent(bip).greaterThanOrEqualTo(C.getGovernanceEmergencyThreshold()),123 "Governance: Must have super majority."124 );125
126 endBip(bip);127 s.g.bips[bip].executed = true;128
129 cutBip(bip);130 pauseOrUnpauseBip(bip);131
132 incentivize(msg.sender, false, bip, C.getCommitIncentive());133 emit Commit(msg.sender, bip);134}135
136function pauseOrUnpause(uint32 bip) external {137 require(isNominated(bip), "Governance: Not nominated.");138 require(diamondCutIsEmpty(bip),"Governance: Has diamond cut.");139 require(isActive(bip), "Governance: Ended.");140 require(141 bipVotePercent(bip).greaterThanOrEqualTo(C.getGovernanceEmergencyThreshold()),142 "Governance: Must have super majority."143 );144
145 endBip(bip);146 s.g.bips[bip].executed = true;147
148 pauseOrUnpauseBip(bip);149
150 incentivize(msg.sender, false, bip, C.getCommitIncentive());151 emit Commit(msg.sender, bip);152}
Recommendation:
We advise the code to be refactored to utilise a single internal
or private
function that accepts the literal changed as an argument instead, greatly optimising the bytecode size of the contract.
Alleviation:
The linked duplicate statements were refactored to a single _execute
private function thereby alleviating this exhibit.
GFT-02C: Inefficient First Vote
Type | Severity | Location |
---|---|---|
Gas Optimization | GovernanceFacet.sol:L61 |
Description:
The first vote cast to a BIP by the proposer themselves is inefficiently done so as it invokes the vote
function performing 4 redundant require
checks.
Example:
31/**32 * Proposition33**/34
35function propose(36 IDiamondCut.FacetCut[] calldata _diamondCut,37 address _init,38 bytes calldata _calldata,39 uint8 _pauseOrUnpause40)41 external42{43 require(canPropose(msg.sender), "Governance: Not enough Stalk.");44 require(notTooProposed(msg.sender), "Governance: Too many active BIPs.");45 require(46 _init != address(0) || _diamondCut.length > 0 || _pauseOrUnpause > 0,47 "Governance: Proposition is empty."48 );49
50 uint32 bipId = createBip(51 _diamondCut,52 _init,53 _calldata,54 _pauseOrUnpause,55 C.getGovernancePeriod(),56 msg.sender57 );58
59 emit Proposal(msg.sender, bipId, season(), C.getGovernancePeriod());60
61 vote(bipId);62}63
64/**65 * Voting66**/67
68function vote(uint32 bip) public {69 require(isNominated(bip), "Governance: Not nominated.");70 require(balanceOfRoots(msg.sender) > 0, "Governance: Must have Stalk.");71 require(isActive(bip), "Governance: Ended.");72 require(!voted(msg.sender, bip), "Governance: Already voted.");73
74 recordVote(msg.sender, bip);75 placeLock(msg.sender, bip);76
77 emit Vote(msg.sender, bip, balanceOfRoots(msg.sender));78}
Recommendation:
We advise the propose
function to instead cast the vote directly by only using the recordVote
and placeLock
functions. If bytecode efficiency is desired, both functions can utilise a shared _vote
function that is internally / privately available.
Alleviation:
The code was optimized as advised with a shared internal _vote
function in the VotingBooth
contract implementation.