Omniscia Steer Protocol Audit
SushiManagementFeeAlm Manual Review Findings
SushiManagementFeeAlm Manual Review Findings
SMF-01M: Improperly Compounding Management Fee
| Type | Severity | Location |
|---|---|---|
| Mathematical Operations | ![]() | SushiManagementFeeAlm.sol:L162-L174 |
Description:
The management fee that is accrued through the SushiManagementFeeAlm::_accrueManagementFee function will automatically compound as the fee is proportionate to the total shares in the system and a single accrual operation will result in new shares being minted to the management fee recipient.
This infers that the higher the frequency at which fee accruals occur, the higher the net fee that the management recipient will capture.
Impact:
We consider the current fee accrual mechanism to be slightly unfair due to generating fees on the management fee recipient's own position.
Example:
176function _computePendingManagementFee(177 uint256 currentTimestamp178) internal view returns (uint256) {179 uint256 feeBps = managementFeeBps;180 if (feeBps == 0) {181 return 0;182 }183
184 uint256 lastAccrual = lastFeeAccrual;185 if (currentTimestamp <= lastAccrual) {186 return 0;187 }188
189 uint256 supply = totalSupply();190 if (supply == 0) {191 return 0;192 }193
194 uint256 elapsed = currentTimestamp.sub(lastAccrual);195 uint256 base = FullMath.mulDiv(supply, feeBps, DIVISOR);196 return FullMath.mulDiv(base, elapsed, YEAR);197}Recommendation:
We advise the Steer Protocol team to evaluate this trait and potentially exclude the management fee recipient's balance from accruing a fee itself as it is unfair and erroneously dilutes existing shareholders even further.
Alleviation:
The Steer Protocol team evaluated this exhibit and clarified that they consider it an acceptable shortfall of the current design as they intend to frequently burn their shares so as to avoid compounding and thus mitigating the issue's effect to a great degree.
As the Steer Protocol team aims to consistently claim their shares and will adequately inform users of this behaviour, we consider this exhibit to be acknowledged safely.
SMF-02M: Inexistent Distinction of Vault Deployments
| Type | Severity | Location |
|---|---|---|
| Standard Conformity | ![]() | SushiManagementFeeAlm.sol:L84 |
Description:
All SushiManagementFeeAlm deployments will retain the same EIP-20 name and symbol which we consider incorrect.
Impact:
Although the Steer Protocol team appears to have consciously removed name distinction to save on bytecode size, we advise it to be reinstated and other means of reducing bytecode size to be utilized such as delegatecall libraries.
Example:
83// Minimal token name/symbol to reduce bytecode size84__ERC20_init("STEER_UV3", "SUV3");Recommendation:
We advise a distinct name and symbol to be used per address, preventing an account holding units of multiple SushiManagementFeeAlm contracts from being confused.
Alleviation:
The name utilized for the EIP-20 asset initialization has been updated to be unique per deployment, addressing this exhibit.
SMF-03M: Bypass of Management Fee
| Type | Severity | Location |
|---|---|---|
| Logical Fault | ![]() | SushiManagementFeeAlm.sol:L210-L218 |
Description:
The SushiBaseLiquidityManager::withdraw function will snapshot the total supply to use for withdrawal calculations prior to the burn operation. This means that the SushiManagementFeeAlm::_accrueManagementFee function will be invoked after this measurement, permitting the withdrawal to be unaffected by the management fee dilution.
In turn, this permits users to bypass management fees entirely through withdrawals and permits users who wish to increase their deposit to withdraw and then re-deposit to avoid the management fee.
Impact:
Management fees can be bypassed via withdrawals as they are not reflected in the withdrawal function's execution.
Example:
199function _beforeTokenTransfer(200 address from,201 address to,202 uint256 amount203) internal virtual override {204 super._beforeTokenTransfer(from, to, amount);205
206 if (amount == 0) {207 return;208 }209
210 // Burn (withdraw): accrue management fee and restrict sender211 if (to == address(0)) {212 _accrueManagementFee();213 require(214 from == singleDepositor || from == managementFeeRecipient,215 "NA"216 );217 return;218 }219
220 // Mint (deposit or fee mint): restrict recipient221 if (from == address(0)) {222 require(223 to == singleDepositor || to == managementFeeRecipient,224 "IR"225 );226 return;227 }228
229 // Regular transfer: only allowed between depositor and fee recipient230 require(231 (from == singleDepositor || from == managementFeeRecipient) &&232 (to == singleDepositor || to == managementFeeRecipient),233 "TR"234 );235}Recommendation:
We advise the code to accrue the management fee before the withdraw function is executed similarly to the SushiManagementFeeAlm::deposit override.
Alleviation:
The code was updated to properly override the parent SushiBaseLiquidityManager::withdraw function implementation ensuring that the total supply utilized for performing the withdrawal is indeed the one after fees have been captured.

