Omniscia Gamma Strategies Audit
GammaController Code Style Findings
GammaController Code Style Findings
GCR-01C: Data Location Optimization
Type | Severity | Location |
---|---|---|
Gas Optimization | ![]() | GammaController.sol:L64 |
Description:
The linked variable is declared as memory
in an external
function.
Example:
61function withdraw(62 address lpTokenAddress,63 uint256 amount,64 uint256[N_COINS] memory minAmounts65) external onlyManager {
Recommendation:
We advise it to be set as calldata
optimizing the codebase.
Alleviation:
The Gamma Strategies team considered this exhibit but opted not to apply a remediation for it in the current iteration of the codebase.
GCR-02C: Ineffectual Extraneous Approval Logic
Type | Severity | Location |
---|---|---|
Gas Optimization | ![]() | GammaController.sol:L99-L109 |
Description:
The _approve
function of the contract performs multiple contract calls redundantly as the chain of operations it performs results in the same state as a single approve
call would.
Example:
99function _approve(100 IERC20 token,101 address spender,102 uint256 amount103) internal {104 uint256 currentAllowance = token.allowance(address(this), spender);105 if (currentAllowance > 0) {106 token.safeDecreaseAllowance(spender, currentAllowance);107 }108 token.safeIncreaseAllowance(spender, amount);109}
Recommendation:
We advise the approve
function to be utilized directly as the code currently reads the allowance, sets it to zero if it is positive and then re-sets it to the new value essentially overwriting it which is the exact behaviour of approve
.
Alleviation:
The Gamma Strategies team considered this exhibit and acknowledged the gas optimization it achieves, however, they wish to support non-standard tokens such as USDT which require the allowance to be set to zero prior to a non-zero value and as such, we consider this optimization nullified.
GCR-03C: Ineffectual Hypervisor Allowance Integration
Type | Severity | Location |
---|---|---|
Gas Optimization | ![]() | GammaController.sol:L43-L44 |
Description:
The deploy
function will approve the Hypervisor with the balances it is meant to extract, however, the allowance is ineffectual in case the manager
set during construction is not the contract itself.
Example:
42// approve Hypervisor to spend amount0,1 amounts of Hypervisor.token0,143_approve(ITokeHypervisor(lpTokenAddress).token0(), lpTokenAddress, amount0);44_approve(ITokeHypervisor(lpTokenAddress).token1(), lpTokenAddress, amount1);45
46uint256 lpTokenBalanceBefore = IERC20(lpTokenAddress).balanceOf(manager);47// deposit amount0, amount1 and mint LP tokens to the manager 48// uint256 lpTokenReceived = uniProxy.deposit(amount0, amount1, manager, lpTokenAddress);49uint256 lpTokenReceived = ITokeHypervisor(lpTokenAddress).deposit(amount0, amount1, manager, manager);
Recommendation:
We advise the allowance operations to be omitted from the codebase as the deposit
function of ITokeHypervisor
will pull the tokens from the manager
rather than the caller.
Alleviation:
The Gamma Strategies team considered this exhibit and stated that in an operational context they expect the manager account to utilize delegateCall
to interact with the contract on the deploy
function and as such the msg.sender
will be the address(this)
member for the approval rendering it valid. As a result, we consider this exhibit nullified.