Omniscia Alliance Block Audit
ThrottledExit Code Style Findings
ThrottledExit Code Style Findings
TET-01C: Data Mutability Optimization
Type | Severity | Location |
---|---|---|
Gas Optimization | Informational | ThrottledExit.sol:L16, L17, L30-L37 |
Description:
The setThrottleParams
function is meant to sanitize the input configuration of the ThrottledExit
contract and assign them to contract-level variables only once as it is invoked solely within constructor
s in the codebase of the project.
Example:
30function setThrottleParams(uint256 _throttleRoundBlocks, uint256 _throttleRoundCap, uint256 throttleStart) internal {31 require(_throttleRoundBlocks > 0, "setThrottle::throttle round blocks must be more than 0");32 require(_throttleRoundCap > 0, "setThrottle::throttle round cap must be more than 0");33 require(throttleRoundBlocks == 0 && throttleRoundCap == 0, "setThrottle::throttle parameters were already set");34 throttleRoundBlocks = _throttleRoundBlocks;35 throttleRoundCap = _throttleRoundCap;36 nextAvailableExitBlock = throttleStart.add(throttleRoundBlocks);37}
Recommendation:
As the variables are only assigned to once during derivative contract constructor
s, we advise that the code block within setThrottleParams
is instead set to be of a constructor
that performs the exact same statements, permitting the introduction of the immutable
mutability specifier in the variable declarations of L16 and L17, greatly optimizing the codebase.
Alleviation:
The codebase has remained unaltered, inferring that the Alliance Block team preferred to retain the current scheme so as to not require code changes in the other segments that depend upon it.
TET-02C: Redundant Array Argument
Type | Severity | Location |
---|---|---|
Gas Optimization | Informational | ThrottledExit.sol:L39-L51 |
Description:
The signature of the initiateExit
function accepts an array of address
type variables as the second argument, however, they remain unutilized within the contract barring for the length
member of the array that can be passed in as a uint256
argument.
Example:
39function initiateExit(uint256 amountStaked, address[] memory _rewardsTokens, uint256[] memory _tokensOwed) virtual internal {40 initialiseExitInfo(msg.sender, _rewardsTokens.length);4142 ExitInfo storage info = exitInfo[msg.sender];43 info.exitBlock = getAvailableExitTime(amountStaked);44 info.exitStake = info.exitStake.add(amountStaked);4546 for (uint256 i = 0; i < _rewardsTokens.length; i++) {47 info.rewards[i] = info.rewards[i].add(_tokensOwed[i]);48 }4950 emit ExitRequested(msg.sender, info.exitBlock);51}
Recommendation:
We advise the omission of the array argument to optimize the gas cost involved in invoking the function.
Alleviation:
The array argument was replaced by its length
directly optimizing the gas cost of this function.
TET-03C: Redundant while
Loop
Type | Severity | Location |
---|---|---|
Mathematical Operations | Informational | ThrottledExit.sol:L70-L73 |
Description:
The linked code segment performs a while
loop to attempt and identify how many throttleRoundBlocks
can fit between the nextAvailableExitBlock
and the current block number.
Example:
68function getAvailableExitTime(uint256 exitAmount) internal returns(uint256 exitBlock) {69 if(block.number > nextAvailableExitBlock) { // We've passed the next available block and need to readjust70 uint i = nextAvailableExitBlock; // Using i instead of nextAvailableExitBlock to avoid SSTORE71 while(i < block.number) { // Find the next future round72 i = i.add(throttleRoundBlocks);73 }74 nextAvailableExitBlock = i;75 nextAvailableRoundExitVolume = exitAmount; // Reset volume76 return i;77 } else { // We are still before the next available block78 nextAvailableRoundExitVolume = nextAvailableRoundExitVolume.add(exitAmount); // Add volume79 }8081 exitBlock = nextAvailableExitBlock;8283 if (nextAvailableRoundExitVolume >= throttleRoundCap) { // If cap reached84 nextAvailableExitBlock = nextAvailableExitBlock.add(throttleRoundBlocks); // update next exit block85 nextAvailableRoundExitVolume = 0; // Reset volume86 }87}
Recommendation:
Instead of conducting additions sequentially within a loop, a calculation can be performed instead optimizing the gas cost of the function. The calculation block.number - ((block.number - nextAvailableExitBlock) % throttleRoundBlocks)
will yield the correct next available exit block.
Alleviation:
The segment was optimized to use a calculation instead of an iteration greatly optimizing its gas cost.