Inverse Finance contest - enckrish'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: 61/127

Findings: 2

Award: $55.74

QA:
grade-b
Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Low Severity

Should use two-step transfer process for BorrowController.operator

Accidently transferring operator rights to an unowned address, will freeze the allowList in its then current state. Use a two step process as in DBR.

Incorrect combination of Market.escrowImplementation and Market.callOnDepositCallback can cause deposits to revert

If callOnDepositCallback is set to true, then escrow.onDeposit() will be called, but only INVEscrow implements this function and if the implementation points to any other escrow, then deposit will revert.

Market governance transfer should be two-step as only it can unpause borrows

Division before multiplication in Market.getWithdrawalLimitInternal

https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L360

Non-Critical

Missing events for state changes in BorrowController.allow and BorrowController.deny

DBR.addMinter and DBR.removeMinter can emit incorrect event in some cases

addMinter can emit AddMinter event even if the address is already a minter. Same for removeMinter, which emits RemoveMinter for an address, even if it wasn't a minter before.

DBR.transferFrom doesn't return useful error for insufficient allowance

In case, allowance is less than the amount to transfer, DBR.transferFrom reverts due to underflow error. An end-user can not determine the reason without requiring substantial effort. https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L194

Market.dola can be marked as constant since it is not assigned to in the constructor

#0 - c4-judge

2022-11-07T21:52:25Z

0xean marked the issue as grade-b

Cache feed decimals in Oracle.FeedData

Feed decimals is accessed by viewPrice and getPrice. As feed decimals cannot change in a Chainlink feed, it can be cached in a new field in FeedData to save gas.

struct FeedData {
    IChainlinkFeed feed;
    uint8 feedDecimals;
    uint8 tokenDecimals;
}
...
function setFeed(address token, IChainlinkFeed feed, uint8 tokenDecimals) public onlyOperator { feeds[token] = FeedData(feed, feed.decimals(), tokenDecimals); }
...
uint8 feedDecimals = feeds[token].feedDecimals();

Gas Savings

-103812 (36.146%) in Forge gas comparison with original implementation.

Move require above state update in Market.borrowInternal

require(credit >= debts[borrower] + amount, "Exceeded credit limit");
debts[borrower] += amount;

Gas Savings

18289 (-5.962%) in Forge gas comparison with original implementation.

#0 - c4-judge

2022-11-05T23:50:00Z

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