Basin - pontifex's results

A composable EVM-native decentralized exchange protocol.

General Information

Platform: Code4rena

Start Date: 03/07/2023

Pot Size: $40,000 USDC

Total HM: 14

Participants: 74

Period: 7 days

Judge: alcueca

Total Solo HM: 9

Id: 259

League: ETH

Basin

Findings Distribution

Researcher Performance

Rank: 14/74

Findings: 1

Award: $271.57

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Eeyore

Also found by: Brenzee, LokiThe5th, Trust, oakcobalt, pontifex

Labels

bug
3 (High Risk)
partial-50
edited-by-warden
duplicate-136

Awards

271.5712 USDC - $271.57

External Links

Lines of code

https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L352-L377

Vulnerability details

Impact

Any user can swap tokens just transferring tokens to the contract in a batch with calling shift function. The problem is that the shift doesn't call the _updatePumps function which update oracle. This way attackers can exploit this vulnerability to manipulate the price oracle.

Proof of Concept

The shift function does not contain _updatePumps call, which returns a saved list of reserves, because it uses another flow with receiving reserves directly from current token.balanceOf(address(this)).

358:        uint256[] memory reserves = new uint256[](_tokens.length);
359:
360:        // Use the balances of the pool instead of the stored reserves.
361:        // If there is a change in token balances relative to the currently
362:        // stored reserves, the extra tokens can be shifted into `tokenOut`.
363:        for (uint256 i; i < _tokens.length; ++i) {
364:            reserves[i] = _tokens[i].balanceOf(address(this));
365:        }

Other important functions in the Well contract receive reserves from _updatePumps. This way these functions update oracle prices but shift doesn't. https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L223 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L273 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L420 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L467 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L503 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L555

At the same time,the shift function can be used for swap tokens in a batch with tokens transfering into the Well contract.

Tools Used

Manual review

I suggest calling the _updatePumps in the shift.

Assessed type

Oracle

#0 - c4-pre-sort

2023-07-11T13:31:20Z

141345 marked the issue as primary issue

#1 - c4-pre-sort

2023-07-11T14:00:08Z

141345 marked the issue as duplicate of #136

#2 - c4-judge

2023-08-03T08:01:12Z

alcueca marked the issue as partial-50

#3 - alcueca

2023-08-03T08:01:22Z

No mention of sync()

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