Fraxlend (Frax Finance) contest - minhquanym's results

Fraxlend: A permissionless lending platform and the final piece of the Frax Finance Defi Trinity.

General Information

Platform: Code4rena

Start Date: 12/08/2022

Pot Size: $50,000 USDC

Total HM: 15

Participants: 120

Period: 5 days

Judge: Justin Goro

Total Solo HM: 6

Id: 153

League: ETH

Frax Finance

Findings Distribution

Researcher Performance

Rank: 23/120

Findings: 2

Award: $238.34

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

Findings Information

๐ŸŒŸ Selected for report: auditor0517

Also found by: 0xA5DF, _Adam, cccz, minhquanym, minhtrng, zzzitron

Labels

bug
duplicate
2 (Med Risk)
downgraded by judge

Awards

192.5076 USDC - $192.51

External Links

Lines of code

https://github.com/code-423n4/2022-08-frax/blob/c4189a3a98b38c8c962c5ea72f1a322fbc2ae45f/src/contracts/FraxlendPairCore.sol#L194

Vulnerability details

Impact

In FraxlendPairCore.constructor() function, value of dirtyLiquidationFee should be 90% of clean fee (in comment). But actually, in implementation, itโ€™s only equal to 9% of clean fee because LIQ_PRECISION = 1e5 and 9000 is only 9% of 1e5.

This basically resulted in less amount of collateral liquidators will receive in liquidateClean() function.

Proof of Concept

Line 194 init value of dirtyLiquidationFee

dirtyLiquidationFee = (_liquidationFee * 9000) / LIQ_PRECISION; // 90% of clean fee

This variable is used to calculate amount of collateral received by liquidators in line 988-990

_collateralForLiquidator = _leftoverCollateral <= 0
    ? _userCollateralBalance
    : (_liquidationAmountInCollateralUnits * (LIQ_PRECISION + dirtyLiquidationFee)) / LIQ_PRECISION;

Tools Used

Manual Review

Fix line 194 to

dirtyLiquidationFee = (_liquidationFee * 90000) / LIQ_PRECISION;

#0 - 0xA5DF

2022-08-17T20:42:34Z

Duplicate of #132

#1 - amirnader-ghazvini

2022-08-29T18:41:20Z

Duplicate of #238

Lines of code

https://github.com/code-423n4/2022-08-frax/blob/c4189a3a98b38c8c962c5ea72f1a322fbc2ae45f/src/contracts/FraxlendPairConstants.sol#L41 https://github.com/code-423n4/2022-08-frax/blob/c4189a3a98b38c8c962c5ea72f1a322fbc2ae45f/src/contracts/LinearInterestRate.sol#L34 https://github.com/code-423n4/2022-08-frax/blob/c4189a3a98b38c8c962c5ea72f1a322fbc2ae45f/src/contracts/VariableInterestRate.sol#L40 https://github.com/code-423n4/2022-08-frax/blob/c4189a3a98b38c8c962c5ea72f1a322fbc2ae45f/src/contracts/VariableInterestRate.sol#L41

Vulnerability details

Impact

All annual rate constants in the system are calculated with an assumption that block time is 15 second (actually itโ€™s from 12 to 14 seconds as in the documentation. And these constants are used to calculate rate in rate calculator and also used to reset interest rate when there are no borrows.

But actually, the merge is really near and after the merge blocks come exactly each 12 seconds which basically makes all these constants wrong.

This resulted in wrong interest rate after reseting when there are no borrows and wrong rate returned by rate calculators.

Proof of Concept

These annual rate is calculated by solving an equation for r with an assumption 365.24 days per year and 15s blocks. For example, this is for the 0.5% annual rate

1.005 = (1 + 15*r)^(365.24 * 24 * 3600 / 15)

But actually after the merge, blocks come in exactly each 12 seconds. Check out this blog post of Tim Beiko

Line 431-433 reset interest rate when there are no borrows

if (!paused()) {
    _currentRateInfo.ratePerSec = DEFAULT_INT;
}

These constants are used in requireValidInitData() and also getNewRate() function in rate calculators and wrong constants might make getNewRate() return wrong value. For example, line 72-74 used MIN_INT as new interest rate

if (_newRatePerSec < MIN_INT) {
    _newRatePerSec = MIN_INT;
}

Tools Used

Manual Review

Consider to update these constants with an assumption that block time is 12 seconds.

#0 - 0xA5DF

2022-08-17T21:28:07Z

Seems invalid, interest rate isn't affected by the frequency of block mining.

#1 - DrakeEvans

2022-09-06T11:53:10Z

This only effects the constants like DEFAULT_RATE. The actual interest is calculated properly. The constants are meant to provide a reasonable starting point. We have confirmed because 12s is a better assumption than 15s. However, this does not effect the rate calculation.

#2 - gititGoro

2022-10-05T02:03:24Z

The warden isn't wrong about the incorrectly calculated constants but those constants are just bounding values. The actual live pairs are not dependent on assumptions about block duration. Downgrading to QA

#3 - gititGoro

2022-10-10T07:26:06Z

Duplicate of #291

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