Inverse Finance contest - shark's results

Rethink the way you borrow.

General Information

Platform: Code4rena

Start Date: 25/10/2022

Pot Size: $50,000 USDC

Total HM: 18

Participants: 127

Period: 5 days

Judge: 0xean

Total Solo HM: 9

Id: 175

League: ETH

Inverse Finance

Findings Distribution

Researcher Performance

Rank: 60/127

Findings: 2

Award: $55.74

QA:
grade-b
Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Use uint256 instead of uint

To be explicit, consider replacing all instances of uint with uint256.

Here is an example:

File: Market.sol Line 593

uint debt = debts[user];

The code above could be changed to:

uint256 debt = debts[user];

Here are a few more examples:

File: Market.sol Line 531-532 File: Market.sol Line 563-564 File: Market.sol Line 596-597 File: Market.sol Line 606 File: Market.sol Line 614-619

constant variables should be capitalized

Constants should be named with all capital letters with underscores separating words.

One instance found: File: DBR.sol Line 13

Insufficient NatSpec

It is recommended that Solidity contracts are fully annotated using NatSpec.

Here are some instances: File: Market.sol Line 11-14 File: Market.sol Line 16-21 File: Market.sol Line 23-30

Lines are too long

Maximum suggested line length is 120 characters.

Here is an example: File: Oracle.sol Line 12-14

Contradicting comment

File: Market.sol Line 166-175

The @dev comment states that @param _replenishmentIncentiveBps must be set between 1 and 10000:

169 @dev Must be set between 1 and 10000.

But the require() statement states that it must be less than 10000

173 require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive");

Meaning that the value cannot be set between 1 and 10000, but instead between 1 and 9999.

Typos

File: Market.sol Line 172

function setReplenismentIncentiveBps

Change "Replenisment" to "Replenishment".

File: Market.sol Line 181

@param _liquidationIncentiveBps The new liqudation incentive set in basis points. 1 = 0.01%

Change "liqudation" to "liquidation".

File: DBR.sol Line 50

@notice Sets pending operator of the contract. Operator role must be claimed by the new oprator. Only callable by Operator.

Change "oprator" to "operator".

File: DBR.sol Line 87

@notice Removes a minter from the set of addresses allowe to mint DBR tokens. Only callable by Operator.

Change "allowe" to "allowed"

File: BorrowController.sol Line 36

@param deniedContract The addres of the denied contract

Change "addres" to "address"

#0 - c4-judge

2022-11-07T21:29:12Z

0xean marked the issue as grade-b

x += y costs more gas than x = x + y

Here is an example:

File: DBR.sol Line 304

debts[user] += additionalDebt;

The above could be changed to:

debts[user] = debts[user] + additionalDebt;

Here are some more instances found:

File: Market.sol Line 395 File: Market.sol Line 397 File: Market.sol Line 534-535 File: Market.sol Line 565 File: Market.sol Line 568 File: Market.sol Line 598-600

Split require() statements that use && operator

Splitting require() statements up saves around 3 gas for every &&

Here is an example:

File: Market.sol Line 184

require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps + liquidationFeeBps < 10000, "Invalid liquidation incentive");

The above should be changed to:

require(_liquidationIncentiveBps > 0, "Invalid liquidation incentive"); require(_liquidationIncentiveBps + liquidationFeeBps < 10000, "Invalid liquidation incentive");

Here are some more instances found:

File: Market.sol Line 75 File: Market.sol Line 162 File: Market.sol Line 173

> costs less gas than >= (same for <, <=)

The reason > and < costs less gas is because in the EVM, there is no opcode for >= or <=

Here is an example:

File: Market.sol Line 582

if(credit >= debt) return 0;

The above can be replaced with

if(credit > debt - 1) return 0;

Here are some additional instances found:

File: Fed.sol Line 123 File: Fed.sol Line 107 File: Market.sol Line 378 File: Market.sol Line 396

abi.encodePacked() is more gas-efficient than abi.encode()

The reason abi.encode() isn't as gas-efficient is because it pads extra null bytes at the end of the calldata while abi.encodePacked() does not.

Here is an example:

File: Market.sol Line 104-110

abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes("DBR MARKET")), keccak256("1"), block.chainid, address(this) )

The above could be replaced to:

abi.encodePacked( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes("DBR MARKET")), keccak256("1"), block.chainid, address(this) )

External visibility costs less gas that public visibility

Functions not called internally can have its visibility set to external.

Here is an example:

File: Market.sol Line 118

function setOracle(IOracle _oracle) public onlyGov { oracle = _oracle; }

The function above could have its visibility set to external:

function setOracle(IOracle _oracle) external onlyGov { oracle = _oracle; }

Here are a few instances of this issue:

File: Market.sol Line 124 File: Market.sol Line 130 File: Market.sol Line 136 File: Market.sol Line 142 File: Market.sol Line 149

#0 - c4-judge

2022-11-05T23:56:16Z

0xean marked the issue as grade-b

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