Lybra Finance - jnrlouis's results

A protocol building the first interest-bearing omnichain stablecoin backed by LSD.

General Information

Platform: Code4rena

Start Date: 23/06/2023

Pot Size: $60,500 USDC

Total HM: 31

Participants: 132

Period: 10 days

Judge: 0xean

Total Solo HM: 10

Id: 254

League: ETH

Lybra Finance

Findings Distribution

Researcher Performance

Rank: 36/132

Findings: 2

Award: $282.51

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: ktg

Also found by: Co0nan, Kaysoft, dacian, jnrlouis, kutugu, n1punp

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-106

Awards

281.1877 USDC - $281.19

External Links

Lines of code

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/token/EUSD.sol#L411-L428

Vulnerability details

Impact

Wrong assumption on the mint function assumes that if sharesAmount == 0, totalSupply == 0.

        if (sharesAmount == 0) {
            //EUSD totalSupply is 0: assume that shares correspond to EUSD 1-to-1
            sharesAmount = _mintAmount;
        }

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/token/EUSD.sol#L415-L418

Meanwhile this is NOT the case.

Proof of Concept

If you look at the mint function,

    function mint(address _recipient, uint256 _mintAmount) external onlyMintVault MintPaused returns (uint256 newTotalShares) {
        require(_recipient != address(0), "MINT_TO_THE_ZERO_ADDRESS");


        uint256 sharesAmount = getSharesByMintedEUSD(_mintAmount);
        if (sharesAmount == 0) {
            //EUSD totalSupply is 0: assume that shares correspond to EUSD 1-to-1
            sharesAmount = _mintAmount;
        }


        newTotalShares = _totalShares.add(sharesAmount);
        _totalShares = newTotalShares;


        shares[_recipient] = shares[_recipient].add(sharesAmount);


        _totalSupply += _mintAmount;


        emit Transfer(address(0), _recipient, _mintAmount);
    }

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/token/EUSD.sol#L411-L428

The sharesAmount is gotten from the getSharesByMintedEUSD function.

    function getSharesByMintedEUSD(uint256 _EUSDAmount) public view returns (uint256) {
        uint256 totalMintedEUSD = _totalSupply;
        if (totalMintedEUSD == 0) {
            return 0;
        } else {
            return _EUSDAmount.mul(_totalShares).div(totalMintedEUSD);
        }
    }

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/token/EUSD.sol#L299-L306

Assuming _totalSupply = 1000; _totalShares = 800; calling the mint function with _mintAmount = 1; would give sharesAmount = 0; As 1 * 800/100 = 0.8 = 0 (Rounded down to 0).

In this case, a non-zero _totalSupply would still give a sharesAmount of 0.

Tools Used

Manual Review

Assessed type

Other

#0 - c4-pre-sort

2023-07-08T20:21:37Z

JeffCX marked the issue as duplicate of #106

#1 - c4-judge

2023-07-28T15:32:20Z

0xean marked the issue as satisfactory

#2 - c4-judge

2023-07-28T19:44:38Z

0xean changed the severity to 3 (High Risk)

Awards

1.3247 USDC - $1.32

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
edited-by-warden
duplicate-27

External Links

Lines of code

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/LybraRETHVault.sol#L9-L11 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/LybraRETHVault.sol#L46-L48 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L58-L70 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L96-L100 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L125-L128 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L157-L168 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L212-L220 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L269-L270

Vulnerability details

Impact

Most of the critical functions would be broken in the RETH vault due to an error with a function name in the interface.

Proof of Concept

The error is from:

interface IRETH {
    function getExchangeRatio() external view returns (uint256);
}

https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/LybraRETHVault.sol#L9-L11

The main issue is the function name in the interface declaration getExchangeRatio(). Looking at the RocketTokenRETH contract on etherscan: https://etherscan.io/address/0xae78736cd615f374d3085123a210448e74fc6393#code, the correct function name should be getExchangeRate() as getExchangeRatio() doesn't exist. This can be further seen in the RocketTokenRETHInterface.sol.

This would mean most of the critical functions would be broken as getAssetPrice() uses this broken function here - This would in turn affect functions like depositAssetToMint(), mint(), liquidation(), rigidRedemption() and withdraw().

Tools Used

Manual review

Correct the spelling error in the interface to:

function getExchangeRate() external view returns (uint256);

Assessed type

Error

#0 - c4-pre-sort

2023-07-04T13:20:20Z

JeffCX marked the issue as duplicate of #27

#1 - c4-judge

2023-07-28T17:14:13Z

0xean changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-07-28T17:15:44Z

0xean marked the issue as satisfactory

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