Omniscia Tren Finance Audit

TRENStaking Code Style Findings

TRENStaking Code Style Findings

TRN-01C: Ineffectual Usage of Safe Arithmetics

Description:

The linked mathematical operation is guaranteed to be performed safely by logical inference, such as surrounding conditionals evaluated in require checks or if-else constructs.

Example:

contracts/TREN/TRENStaking.sol
167uint256 trenToWithdraw = TrenMath._min(_TRENamount, currentStake);
168uint256 newStake = currentStake - trenToWithdraw;

Recommendation:

Given that safe arithmetics are toggled on by default in pragma versions of 0.8.X, we advise the linked statement to be wrapped in an unchecked code block thereby optimizing its execution cost.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

The Tren Finance team evaluated this exhibit but opted to acknowledge it in the current iteration of the codebase.

TRN-02C: Inefficient Handling of Debt Token Gains

Description:

The referenced code blocks will evaluate whether the i iterator is 0 on each iteration redundantly.

Example:

contracts/TREN/TRENStaking.sol
150for (uint256 i = 0; i < assetLength;) {
151 asset = assetsList[i];
152
153 if (i == 0) {
154 checkDebtTokenGain();
155 }
156
157 checkAssetGain(asset);
158
159 _updateUserSnapshots(asset, msg.sender);
160
161 unchecked {
162 ++i;
163 }
164}

Recommendation:

We advise the TRENStaking::checkDebtTokenGain function call to be performed before each loop's body, ensuring it is executed once at the beginning efficiently.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

The code was optimized per our recommendation, ensuring that debt token gains are evaluated before each loop begins.

TRN-03C: Inefficient Update of Debt Token Snapshots

Description:

The debtTokenFeeSnapshot data entry of a user's snapshot will be written to once per asset in the system's asset list which is inefficient.

Example:

contracts/TREN/TRENStaking.sol
229function _updateUserSnapshots(address _asset, address _user) private {
230 snapshots[_user].assetsFeeSnapshot[_asset] = assetsFee[_asset];
231 snapshots[_user].debtTokenFeeSnapshot = totalDebtTokenFee;
232
233 emit StakerSnapshotsUpdated(_user, assetsFee[_asset], totalDebtTokenFee);
234}

Recommendation:

We advise the value to be written once via a separate function, optimizing the code's gas cost significantly.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

The code was optimized as advised, splitting the relevant entry updates to two distinct functions that are optimally invoked.

TRN-04C: Inefficient mapping Lookups

Description:

The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.

Example:

contracts/TREN/TRENStaking.sol
230snapshots[_user].assetsFeeSnapshot[_asset] = assetsFee[_asset];
231snapshots[_user].debtTokenFeeSnapshot = totalDebtTokenFee;

Recommendation:

As the lookups internally perform an expensive keccak256 operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping in case of primitive types or holds a storage pointer to the struct contained.

As the compiler's optimizations may take care of these caching operations automatically at-times, we advise the optimization to be selectively applied, tested, and then fully adopted to ensure that the proposed caching model indeed leads to a reduction in gas costs.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

The exhibit is no longer applicable due to the application of TRN-03C.