Canto v2 contest - TerrierLover's results

Execution layer for original work.

General Information

Platform: Code4rena

Start Date: 28/06/2022

Pot Size: $25,000 USDC

Total HM: 14

Participants: 50

Period: 4 days

Judge: GalloDaSballo

Total Solo HM: 7

Id: 141

League: ETH

Canto

Findings Distribution

Researcher Performance

Rank: 25/50

Findings: 2

Award: $67.18

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

43.2289 USDC - $43.23

Labels

bug
QA (Quality Assurance)
sponsor confirmed

External Links

Lines of code

https://github.com/Plex-Engineer/lending-market-v2/blob/443a8c0fed3c5018e95f3881a31b81a555c42b2d/contracts/NoteInterest.sol#L145-L147

Vulnerability details

Impact

When casting to int from uint, the overflow might happen.

Proof of Concept

https://github.com/Plex-Engineer/lending-market-v2/blob/443a8c0fed3c5018e95f3881a31b81a555c42b2d/contracts/NoteInterest.sol#L145-L147

uint twapMantissa = oracle.getUnderlyingPrice(cNote); // returns price as mantissa //uint ir = (1 - twapMantissa).mul(adjusterCoefficient).add(baseRatePerYear); int diff = BASE - int(twapMantissa); //possible annoyance if 1e18 - twapMantissa > 2**255, differ

int(twapMantissa) can overflow depending on the value of uint twapMantissa. Even if this is not expected, handling this case should be good.

Tools Used

Static analysis

Consider using the logic of toInt256 provided by OpenZeppelin.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol#L1130-L1134

#0 - GalloDaSballo

2022-08-13T23:08:35Z

I think the warden has shown code where theoretically a potential overflow could happen.

However, both the oracle and the Router will return a uint

Because the pattern is a code smell, I'll downgrade to QA - NC. However I believe the overflow cannot ever happen in the in-scope codebase

Awards

23.9548 USDC - $23.95

Labels

bug
G (Gas Optimization)

External Links

Summary

TitleCounts
[Gas-1] Use != 0 instead of > 0 on uint variables32
[Gas-2] No need to set 0 on uint variables23
[Gas-3] Potential usage of unchecked4
[Gas-4] Gas cost of ++i/--i is smaller than i++/i--11
[Gas-5] Use custom errors102
[Gas-6] Can simplify the logic when setting name and symbol1
[Gas-7] Call block.number directly instead of calling getBlockNumber() function5
[Gas-8] Proposal.canceled seems not needed1
[Gas-9] Unnecessary console import and usage of console.log1
[Gas-10] Unnecessary usage of SafeMath at NoteInterest.sol1

[Gas-1] Use != 0 instead of > 0 on uint variables

uint variables will never be lower than 0. Therefore, > 0 and != 0 have same meanings. Using != 0 can reduce the gas deployment cost, so it is worth using != 0 wherever possible.

Here are list of the gas improvements by using != 0.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-core.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-core.sol 159,25: if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { 256,27: require(liquidity > 0, 'ILM'); // BaseV1: INSUFFICIENT_LIQUIDITY_MINTED 275,25: require(amount0 > 0 && amount1 > 0, 'ILB'); // BaseV1: INSUFFICIENT_LIQUIDITY_BURNED 275,40: require(amount0 > 0 && amount1 > 0, 'ILB'); // BaseV1: INSUFFICIENT_LIQUIDITY_BURNED 289,28: require(amount0Out > 0 || amount1Out > 0, 'IOA'); // BaseV1: INSUFFICIENT_OUTPUT_AMOUNT 289,46: require(amount0Out > 0 || amount1Out > 0, 'IOA'); // BaseV1: INSUFFICIENT_OUTPUT_AMOUNT 298,24: if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens 299,24: if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens 300,25: if (data.length > 0) IBaseV1Callee(to).hook(msg.sender, amount0Out, amount1Out, data); // callback, used for flash loans 306,27: require(amount0In > 0 || amount1In > 0, 'IIA'); // BaseV1: INSUFFICIENT_INPUT_AMOUNT 306,44: require(amount0In > 0 || amount1In > 0, 'IIA'); // BaseV1: INSUFFICIENT_INPUT_AMOUNT 468,35: require(token.code.length > 0);

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-periphery.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-periphery.sol 122,25: require(amountA > 0, "BaseV1Router: INSUFFICIENT_AMOUNT"); 123,26: require(reserveA > 0 && reserveB > 0, "BaseV1Router: INSUFFICIENT_LIQUIDITY"); 123,42: require(reserveA > 0 && reserveB > 0, "BaseV1Router: INSUFFICIENT_LIQUIDITY"); 474,35: require(token.code.length > 0); 481,35: require(token.code.length > 0, "token code length failure");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Comptroller.sol

File: lending-market-v2/contracts/Comptroller.sol 314,23: if (shortfall > 0) { 334,47: if (redeemTokens == 0 && redeemAmount > 0) { 385,23: if (shortfall > 0) { 1134,34: if (amountToSubtract > 0) { 1199,25: if (deltaBlocks > 0 && supplySpeed > 0) { 1199,44: if (deltaBlocks > 0 && supplySpeed > 0) { 1202,48: Double memory ratio = supplyTokens > 0 ? fraction(compAccrued, supplyTokens) : Double({mantissa: 0}); 1205,32: } else if (deltaBlocks > 0) { 1220,25: if (deltaBlocks > 0 && borrowSpeed > 0) { 1220,44: if (deltaBlocks > 0 && borrowSpeed > 0) { 1223,48: Double memory ratio = borrowAmount > 0 ? fraction(compAccrued, borrowAmount) : Double({mantissa: 0}); 1226,32: } else if (deltaBlocks > 0) { 1316,25: if (deltaBlocks > 0 && compSpeed > 0) { 1316,42: if (deltaBlocks > 0 && compSpeed > 0) { 1384,20: if (amount > 0 && amount <= compRemaining) {

[Gas-2] No need to set 0 on uint variables

The default value of uint varibles are 0. Therefore, there is no need to set 0 on uint variables. Not setting 0 on uint variables can reduce the deployment gas cost.

Here are list of the gas improvements.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-core.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-core.sol 48,29: uint public totalSupply = 0; 72,30: uint constant periodSize = 0; 210,21: for (uint i = 0; i < _prices.length; i++) { 226,24: uint nextIndex = 0; 227,20: uint index = 0; 340,21: for (uint i = 0; i < 255; i++) {

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-periphery.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-periphery.sol 154,21: for (uint i = 0; i < routes.length; i++) { 176,27: uint _totalSupply = 0; 380,21: for (uint i = 0; i < routes.length; i++) { 496,20: stable = 0; // This line does not even need

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorBravoDelegate.sol

File: lending-market-v2/contracts/Governance/GovernorBravoDelegate.sol 66,21: for (uint i = 0; i < newProposal.targets.length; i++) { 88,21: for (uint i = 0; i < proposal.targets.length; i++) {

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Comptroller.sol

File: lending-market-v2/contracts/Comptroller.sol 131,21: for (uint i = 0; i < len; i++) { 211,21: for (uint i = 0; i < len; i++) { 742,21: for (uint i = 0; i < assets.length; i++) { 964,21: for (uint i = 0; i < allMarkets.length; i ++) { 1010,20: for(uint i = 0; i < numMarkets; i++) { 1111,21: for (uint i = 0; i < affectedUsers.length; ++i) { 1352,21: for (uint i = 0; i < cTokens.length; i++) { 1358,29: for (uint j = 0; j < holders.length; j++) { 1364,29: for (uint j = 0; j < holders.length; j++) { 1369,21: for (uint j = 0; j < holders.length; j++) { 1418,21: for (uint i = 0; i < numTokens; ++i) {

[Gas-3] Potential usage of unchecked

Following variables or operations can be wrapped by unchecked to reduce the gas cost.

[1] i++ or ++i used in the for loop when the end condition is uint or constant

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-core.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-core.sol 210,46: for (uint i = 0; i < _prices.length; i++) { 340,35: for (uint i = 0; i < 255; i++) {

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Comptroller.sol

File: lending-market-v2/contracts/Comptroller.sol 131,35: for (uint i = 0; i < len; i++) { 211,35: for (uint i = 0; i < len; i++) { 1010,41: for(uint i = 0; i < numMarkets; i++) {

[2] y > y_prev assures that y - y_prev in if statement, and y_prev - y in else statement will not underflow

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-core.sol#L350-L358

if (y > y_prev) { if (y - y_prev <= 1) { return y; } } else { if (y_prev - y <= 1) { return y; } }

[3] if (msg.value > amountCANTO) assures that msg.value - amountCANTO will not underflow

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-periphery.sol#L294

unchecked { if (msg.value > amountCANTO) _safeTransferCANTO(msg.sender, msg.value - amountCANTO); }

[4] require(b <= a, ...) assures that a-b will not underflow

function sub256(uint256 a, uint256 b) internal pure returns (uint) { require(b <= a, "subtraction underflow"); return a - b; }

[Gas-4] Gas cost of ++i/--i is smaller than i++/i--

Here are gas optimization opportunities.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Comptroller.sol

File: lending-market-v2/contracts/Comptroller.sol 131,35: for (uint i = 0; i < len; i++) { 211,35: for (uint i = 0; i < len; i++) { 742,45: for (uint i = 0; i < assets.length; i++) { 1010,41: for(uint i = 0; i < numMarkets; i++) { 1352,46: for (uint i = 0; i < cTokens.length; i++) {

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorBravoDelegate.sol

File: lending-market-v2/contracts/Governance/GovernorBravoDelegate.sol 66,58: for (uint i = 0; i < newProposal.targets.length; i++) { 88,55: for (uint i = 0; i < proposal.targets.length; i++) {

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-core.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-core.sol 210,46: for (uint i = 0; i < _prices.length; i++) { 340,35: for (uint i = 0; i < 255; i++) {

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-periphery.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-periphery.sol 154,45: for (uint i = 0; i < routes.length; i++) { 380,45: for (uint i = 0; i < routes.length; i++) {

[Gas-5] Use custom errors

Using custom errors can reduce the gas cost.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/CNote.sol

File: lending-market-v2/contracts/CNote.sol 17,9: require(msg.sender == admin, "CNote::_setAccountantContract:Only admin may call this function"); 94,9: require(success, "TOKEN_TRANSFER_IN_FAILED"); 105,13: require(balanceCur == 0, "Accountant has not been correctly supplied"); 147,9: require(success, "TOKEN_TRANSFER_OUT_FAILED"); 148,9: require(token.balanceOf(address(this)) == 0, "cNote::doTransferOut: TransferOut Failed"); 157,13: require(_notEntered, "re-entered");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Comptroller.sol

File: lending-market-v2/contracts/Comptroller.sol 183,9: require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code 242,9: require(!mintGuardianPaused[cToken], "mint is paused"); 348,9: require(!borrowGuardianPaused[cToken], "borrow is paused"); 356,13: require(msg.sender == cToken, "sender must be cToken"); 378,13: require(nextTotalBorrows < borrowCap, "market borrow cap reached"); 496,13: require(borrowBalance >= repayAmount, "Can not repay more than the total borrow"); 561,9: require(!seizeGuardianPaused, "seize is paused"); 619,9: require(!transferGuardianPaused, "transfer is paused"); 857,6: require(msg.sender == admin, "only admin can set close factor"); 965,13: require(allMarkets[i] != CToken(cToken), "market already added"); 1003,6: require(msg.sender == admin || msg.sender == borrowCapGuardian, "only admin or borrow cap guardian can set borrow caps"); 1008,9: require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input"); 1021,9: require(msg.sender == admin, "only admin can set borrow cap guardian"); 1056,9: require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); 1057,9: require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); 1058,9: require(msg.sender == admin || state == true, "only admin can unpause"); 1066,9: require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); 1067,9: require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); 1068,9: require(msg.sender == admin || state == true, "only admin can unpause"); 1076,9: require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); 1077,9: require(msg.sender == admin || state == true, "only admin can unpause"); 1085,9: require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); 1086,9: require(msg.sender == admin || state == true, "only admin can unpause"); 1094,9: require(msg.sender == unitroller.admin(), "only unitroller admin can change brains"); 1095,9: require(unitroller._acceptImplementation() == 0, "change not authorized"); 1100,9: require(msg.sender == admin, "Only admin can call this function"); // Only the timelock can call this function 1101,9: require(!proposal65FixExecuted, "Already executed this one-off function"); // Require that this function is only called once 1102,9: require(affectedUsers.length == amounts.length, "Invalid input"); 1163,9: require(market.isListed, "comp market is not listed"); 1354,13: require(markets[address(cToken)].isListed, "market must be listed"); 1400,9: require(adminOrInitializing(), "only admin can grant comp"); 1402,9: require(amountLeft == 0, "insufficient comp for grant"); 1413,9: require(adminOrInitializing(), "only admin can set comp speed"); 1416,9: require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, "Comptroller::_setCompSpeeds invalid input"); 1429,9: require(adminOrInitializing(), "only admin can set comp speed"); 1480,9: require(msg.sender == admin, "Only admin may initialize Weth Address");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/NoteInterest.sol

File: lending-market-v2/contracts/NoteInterest.sol 167,9: require(msg.sender == admin, "only the admin may set the base rate"); 180,9: require(msg.sender == admin, "only the admin may set the adjuster coefficient"); 193,9: require(msg.sender == admin, "only the admin may set the update frequency");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/WETH.sol

File: lending-market-v2/contracts/WETH.sol 29,9: require(_balanceOf[msg.sender] >= wamount, "sender balance insufficient for withdrawal"); 69,9: require(_balanceOf[src] >= wad, "WETH::transfeFrom"); 72,13: require(_allowance[src][msg.sender] >= wad, "WETH::transferFrom:allowance insufficient"); 89,9: require(owner != address(0), "ERC20: approve from the zero address"); 90,9: require(spender != address(0), "ERC20: approve to the zero address");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorBravoDelegate.sol

File: lending-market-v2/contracts/Governance/GovernorBravoDelegate.sol 25,9: require(address(timelock) == address(0), "GovernorBravo::initialize: can only initialize once"); 26,9: require(msg.sender == admin, "GovernorBravo::initialize: admin only"); 27,9: require(timelock_ != address(0), "GovernorBravo::initialize: invalid timelock address"); 42,9: require(unigovProposal.targets.length == unigovProposal.values.length && 46,9: require(unigovProposal.targets.length != 0, "GovernorBravo::propose: must provide actions"); 47,9: require(unigovProposal.targets.length <= proposalMaxOperations, "GovernorBravo::propose: too many actions"); 76,9: require(!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta"); 85,9: require(state(proposalId) == ProposalState.Queued, "GovernorBravo::execute: proposal can only be executed if it is queued"); 128,9: require(msg.sender == admin, "GovernorBravo::_initiate: admin only"); 129,9: require(initialProposalId == 0, "GovernorBravo::_initiate: can only initiate once"); 140,9: require(msg.sender == admin, "GovernorBravo:_setPendingAdmin: admin only"); 158,9: require(msg.sender == pendingAdmin, "GovernorBravo:_acceptAdmin: pending admin only"); 176,9: require(c >= a, "addition overflow"); 181,9: require(b <= a, "subtraction underflow");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorBravoDelegator.sol

File: lending-market-v2/contracts/Governance/GovernorBravoDelegator.sol 27,9: require(msg.sender == admin, "GovernorBravoDelegator::_setImplementation: admin only"); 28,9: require(implementation_ != address(0), "GovernorBravoDelegator::_setImplementation: invalid implementation address"); 40,9: require(msg.sender == admin, "GovernorBravoDelegator::_initiateDelegated: admin only"); 48,9: require(msg.sender == admin, "GovernorBravoDelegator::_acceptInitialAdminDelegated: admin only"); 56,9: require(msg.sender == admin, "GovernorBravoDelegator::_setPendingAdminDelegated: admin only");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-core.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-core.sol 256,9: require(liquidity > 0, 'ILM'); // BaseV1: INSUFFICIENT_LIQUIDITY_MINTED 275,9: require(amount0 > 0 && amount1 > 0, 'ILB'); // BaseV1: INSUFFICIENT_LIQUIDITY_BURNED 289,9: require(amount0Out > 0 || amount1Out > 0, 'IOA'); // BaseV1: INSUFFICIENT_OUTPUT_AMOUNT 291,9: require(amount0Out < _reserve0 && amount1Out < _reserve1, 'IL'); // BaseV1: INSUFFICIENT_LIQUIDITY 297,9: require(to != _token0 && to != _token1, 'IT'); // BaseV1: INVALID_TO 306,9: require(amount0In > 0 || amount1In > 0, 'IIA'); // BaseV1: INSUFFICIENT_INPUT_AMOUNT 312,9: require(_k(_balance0, _balance1) >= _k(_reserve0, _reserve1), 'K'); // BaseV1: K 416,9: require(deadline >= block.timestamp, 'BaseV1: EXPIRED'); 434,9: require(recoveredAddress != address(0) && recoveredAddress == owner, 'BaseV1: INVALID_SIGNATURE'); 524,9: require(tokenA != tokenB, 'IA'); // BaseV1: IDENTICAL_ADDRESSES 526,9: require(token0 != address(0), 'ZA'); // BaseV1: ZERO_ADDRESS 527,9: require(getPair[token0][token1][stable] == address(0), 'PE'); // BaseV1: PAIR_EXISTS - single check is sufficient

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Stableswap/BaseV1-periphery.sol

File: lending-market-v2/contracts/Stableswap/BaseV1-periphery.sol 104,9: require(tokenA != tokenB, "BaseV1Router: IDENTICAL_ADDRESSES"); 106,9: require(token0 != address(0), "BaseV1Router: ZERO_ADDRESS"); 122,9: require(amountA > 0, "BaseV1Router: INSUFFICIENT_AMOUNT"); 123,9: require(reserveA > 0 && reserveB > 0, "BaseV1Router: INSUFFICIENT_LIQUIDITY"); 151,9: require(routes.length >= 1, "BaseV1Router: INVALID_PATH"); 241,17: require(amountBOptimal >= amountBMin, "BaseV1Router: INSUFFICIENT_B_AMOUNT"); 246,17: require(amountAOptimal >= amountAMin, "BaseV1Router: INSUFFICIENT_A_AMOUNT"); 309,9: require(IBaseV1Pair(pair).transferFrom(msg.sender, pair, liquidity)); // send liquidity to pair 313,9: require(amountA >= amountAMin, "BaseV1Router: INSUFFICIENT_A_AMOUNT"); 314,9: require(amountB >= amountBMin, "BaseV1Router: INSUFFICIENT_B_AMOUNT"); 405,9: require(amounts[amounts.length - 1] >= amountOutMin, "BaseV1Router: INSUFFICIENT_OUTPUT_AMOUNT"); 420,9: require(amounts[amounts.length - 1] >= amountOutMin, "BaseV1Router: INSUFFICIENT_OUTPUT_AMOUNT"); 433,9: require(routes[0].from == address(wcanto), "BaseV1Router: INVALID_PATH"); 435,9: require(amounts[amounts.length - 1] >= amountOutMin, "BaseV1Router: INSUFFICIENT_OUTPUT_AMOUNT"); 446,9: require(routes[routes.length - 1].to == address(wcanto), "BaseV1Router: INVALID_PATH"); 448,9: require(amounts[amounts.length - 1] >= amountOutMin, "BaseV1Router: INSUFFICIENT_OUTPUT_AMOUNT"); 470,9: require(success, "TransferHelper: ETH_TRANSFER_FAILED"); 481,9: require(token.code.length > 0, "token code length failure");

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Treasury/TreasuryDelegator.sol

File: lending-market-v2/contracts/Treasury/TreasuryDelegator.sol 31,9: require(msg.sender == admin, "GovernorBravoDelegator::setImplementation: admin only"); 32,9: require(implementation_ != address(0), "GovernorBravoDelegator::setImplementation: invalid implementation address"); 121,9: require(msg.value == 0, "TreasuryDelegator::fallback:cannot send value to fallback");

[Gas-6] Can simplify the logic when setting name and symbol

if (_stable) { name = string(abi.encodePacked("StableV1 AMM - ", erc20(_token0).symbol(), "/", erc20(_token1).symbol())); symbol = string(abi.encodePacked("sAMM-", erc20(_token0).symbol(), "/", erc20(_token1).symbol())); } else { name = string(abi.encodePacked("VolatileV1 AMM - ", erc20(_token0).symbol(), "/", erc20(_token1).symbol())); symbol = string(abi.encodePacked("vAMM-", erc20(_token0).symbol(), "/", erc20(_token1).symbol())); }

This part can be written as follows:

string memory namePrefix; string memory symbolPrefix; if (_stable) { namePrefix = "StableV1 AMM - "; symbolPrefix = "sAMM-"; } else { namePrefix = "VolatileV1 AMM - "; symbolPrefix = "vAMM-"; } name = string(abi.encodePacked(namePrefix, erc20(_token0).symbol(), "/", erc20(_token1).symbol())); symbol = string(abi.encodePacked(symbolPrefix, erc20(_token0).symbol(), "/", erc20(_token1).symbol()));

[Gas-7] Call block.number directly instead of calling getBlockNumber() function

Calling block.number directly instead of getBlockNumber() function can reduce the gas cost.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Comptroller.sol

File: lending-market-v2/contracts/Comptroller.sol 971,37: uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); 1197,37: uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); 1218,37: uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); 1314,28: uint blockNumber = getBlockNumber(); 1437,49: lastContributorBlock[contributor] = getBlockNumber();

[Gas-8] Proposal.canceled seems not needed

Proposal.canceled seems not needed so it can be deleted to reduce the gas cost.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorBravoInterfaces.sol#L90-L91


[Gas-9] Unnecessary console import and usage of console.log

In the codebase, console.log is used but this should not be needed.

https://github.com/Plex-Engineer/lending-market-v2/blob/2646a7676b721db8a7754bf5503dcd712eab2f8a/contracts/Accountant/AccountantDelegate.sol#L7

https://github.com/Plex-Engineer/lending-market-v2/blob/89212fb4c5b999a21447c7a1bd1a6c4c1527353a/contracts/Stableswap/BaseV1-core.sol#L4

https://github.com/Plex-Engineer/lending-market-v2/blob/89212fb4c5b999a21447c7a1bd1a6c4c1527353a/contracts/Stableswap/BaseV1-core.sol#L207

https://github.com/Plex-Engineer/lending-market-v2/blob/2646a7676b721db8a7754bf5503dcd712eab2f8a/contracts/CErc20.sol#L5


[Gas-10] Unnecessary usage of SafeMath at NoteInterest.sol

In NoteInterest.sol, sub() function of SafeMath is only used. From solidity 8.0 version, underflow/overflow does not happen for subtraction - as a default.

https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/NoteInterest.sol#L139

It can reduce the usage of SafeMath itself from NoteInterest.sol.


#0 - GalloDaSballo

2022-08-14T22:32:46Z

Report is very nice, however it missed the SLOADs and immutables that would have saved way more.

This will save around 500 gas in total

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter