Shell Protocol - T1MOH's results

A set of EVM-based smart contracts on Arbitrum One. In a nutshell it is DeFi made simple.

General Information

Platform: Code4rena

Start Date: 21/08/2023

Pot Size: $36,500 USDC

Total HM: 1

Participants: 43

Period: 7 days

Judge: Dravee

Id: 277

League: ETH

Shell Protocol

Findings Distribution

Researcher Performance

Rank: 10/43

Findings: 1

Award: $1,933.59

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Mirror

Also found by: ItsNio, T1MOH, Testerbot, Udsen, d3e4, ktg, markus_ether, mert_eren, oakcobalt, pontifex, prapandey031, skodi

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
sufficient quality report
duplicate-57

Awards

1933.5938 USDC - $1,933.59

External Links

Lines of code

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L563

Vulnerability details

Impact

_checkBalances() is performed to ensure the balances of X and Y tokens are above MIN_BALANCE, and to ensure that Y/X ratio in [MIN_M; MAX_M) boundary. This check is performed in both swaps, depositGivenOutputAmount(), withdrawGivenInputAmount(). However there is no such a check in depositGivenInputAmount() and withdrawGivenOutputAmount() That is how implemented checks can be bypassed.

Proof of Concept

Main issue is that _checkBalances() is not invoked in _reserveTokenSpecified(). _reserveTokenSpecified() is used in calculations of depositGivenInputAmount() and withdrawGivenOutputAmount()

This test returns required amount of LP to withdraw whole token X reserve, paste to EvolvingProteusProperties.t.sol

    function testPOC_withdrawGivenOutputAmount() public {
        uint256 result = DUT.withdrawGivenOutputAmount(3000e18, 1000e18, 1000 ether, 3000e18, SpecifiedToken.X);
        console.log(result);
    }

Tools Used

Manual Review

Add this check:

    function _reserveTokenSpecified(
        SpecifiedToken specifiedToken,
        int256 specifiedAmount,
        bool feeDirection,
        int256 si,
        int256 xi,
        int256 yi
    ) internal view returns (int256 computedAmount) {
        ...

        // apply fee to the computed amount
        computedAmount = _applyFeeByRounding(sf - si, feeDirection);

+       _checkBalances(xf, yf);
    }

Assessed type

Invalid Validation

#0 - c4-pre-sort

2023-08-29T05:39:45Z

0xRobocop marked the issue as duplicate of #268

#1 - c4-pre-sort

2023-08-29T05:39:49Z

0xRobocop marked the issue as sufficient quality report

#2 - c4-judge

2023-09-11T19:20:47Z

JustDravee changed the severity to 3 (High Risk)

#3 - c4-judge

2023-09-11T19:23:33Z

JustDravee 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