Lybra Finance - Bauchibred'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: 118/132

Findings: 1

Award: $9.93

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

9.931 USDC - $9.93

Labels

bug
downgraded by judge
grade-b
QA (Quality Assurance)
duplicate-112
Q-33

External Links

Lines of code

https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L122-L139

Vulnerability details

Impact

This could lead to users losing the eth sent with this transaction, which would be better served by reverting instead of accepting a non-zero value of msg.value

Proof of Concept

There are 2 instances of payble function in the PeUSDMainnetStableVision.sol contract, after an extensive discussion with the team we came to an understanding that unlike the convertToPeUSDAndCrossChain() function that needs to call OFT's sendFrom, which requires passing gas to lzEndpoint the payable inside executeFlashloan() can be removed.

Take a look at both functions: convertToPeUSDAndCrossChain()

    /**
     * @dev Allows users to deposit eUSD and mint PeUSD tokens, which can be directly bridged to other networks.
     * @param eusdAmount The amount of eUSD to deposit and mint PeUSD tokens.
     * @param dstChainId The chain ID of the target network.
     * @param toAddress The receiving address after cross-chain transfer.
     * @param callParams Additional parameters.
     */
    function convertToPeUSDAndCrossChain(
        uint256 eusdAmount,
        uint16 dstChainId,
        bytes32 toAddress,
        LzCallParams calldata callParams
    ) external payable {
        convertToPeUSD(_msgSender(), eusdAmount);
        sendFrom(_msgSender(), dstChainId, toAddress, eusdAmount, callParams);
    }

executeFlashloan()

    /**
     * @dev Allows users to lend out any amount of eUSD for flash loan calls.
     * @param receiver The address of the contract that will receive the borrowed eUSD.
     * @param eusdAmount The amount of eUSD to lend out.
     * @param data The data to be passed to the receiver contract for execution.
     */
    function executeFlashloan(FlashBorrower receiver, uint256 eusdAmount, bytes calldata data) public payable {
        uint256 shareAmount = EUSD.getSharesByMintedEUSD(eusdAmount);
        EUSD.transferShares(address(receiver), shareAmount);
        receiver.onFlashLoan(shareAmount, data);
        bool success = EUSD.transferFrom(address(receiver), address(this), EUSD.getMintedEUSDByShares(shareAmount));
        require(success, "TF");


        uint256 burnShare = getFee(shareAmount);
        EUSD.burnShares(address(receiver), burnShare);
        emit Flashloaned(receiver, eusdAmount, burnShare);
    }

Tool used

Manual Audit

Simple fix, remove the payable

Assessed type

Payable

#0 - c4-pre-sort

2023-07-09T13:50:22Z

JeffCX marked the issue as duplicate of #112

#1 - c4-judge

2023-07-28T18:28:55Z

0xean changed the severity to QA (Quality Assurance)

#2 - c4-judge

2023-07-28T18:29:20Z

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