Popcorn contest - 7siech's results

A multi-chain regenerative yield-optimizing protocol.

General Information

Platform: Code4rena

Start Date: 31/01/2023

Pot Size: $90,500 USDC

Total HM: 47

Participants: 169

Period: 7 days

Judge: LSDan

Total Solo HM: 9

Id: 211

League: ETH

Popcorn

Findings Distribution

Researcher Performance

Rank: 15/169

Findings: 4

Award: $1,430.07

🌟 Selected for report: 1

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: 7siech

Also found by: fs0c, imare

Labels

bug
3 (High Risk)
primary issue
satisfactory
selected for report
sponsor acknowledged
H-05

Awards

1357.6447 USDC - $1,357.64

External Links

Lines of code

https://github.com/code-423n4/2023-01-popcorn/blob/main/src/vault/adapter/abstracts/AdapterBase.sol#L444

Vulnerability details

Impact

A malicious strategy has access to the adapter's storage and can therefore freely change any values.

Proof of Concept

Because AdapterBase calls the Strategy using delegatecall, the Strategy has access to the calling contract's storage and can be manipulated directly.

In the following proof of concept, a MaliciousStrategy is paired with the BeefyAdapter and when called will manipulate the performanceFee and highWaterMark values. Of course, any other storage slots of the adapter could also be manipulated or any other calls to external contracts on behalf of the msg.sender could be performed.

MaliciousStrategy implementation showing the exploit - https://gist.github.com/alpeware/e0b1c9f330419986142711e814bfdc7b#file-beefyadapter-t-sol-L18

Adapter helper used to determine the storage slots - https://gist.github.com/alpeware/e0b1c9f330419986142711e814bfdc7b#file-beefyadapter-t-sol-L65

BeefyAdapterTest changes made to tests -

Adding the malicious strategy - https://gist.github.com/alpeware/e0b1c9f330419986142711e814bfdc7b#file-beefyadapter-t-sol-L123

Adding new test test__StrategyHarvest() executing harvest() - https://gist.github.com/alpeware/e0b1c9f330419986142711e814bfdc7b#file-beefyadapter-t-sol-L132

Log output - https://gist.github.com/alpeware/e0b1c9f330419986142711e814bfdc7b#file-log-txt

Tools Used

Foundry

From chatting with the devs, the goal is to mix and match adapters and strategies. I don't think delegatecall should be used and adapters and strategies should be treated as separate contracts. Relevant approvals should be given individually instead.

#0 - c4-judge

2023-02-16T06:53:04Z

dmvt marked the issue as primary issue

#1 - c4-sponsor

2023-02-17T10:01:41Z

RedVeil marked the issue as sponsor acknowledged

#2 - c4-judge

2023-02-25T16:21:59Z

dmvt marked the issue as selected for report

#3 - c4-judge

2023-03-01T23:28:18Z

dmvt marked issue #475 as primary and marked this issue as a duplicate of 475

#4 - c4-judge

2023-03-01T23:28:32Z

dmvt marked the issue as not a duplicate

#5 - c4-judge

2023-03-01T23:28:38Z

dmvt marked the issue as unsatisfactory: Invalid

#6 - c4-judge

2023-03-01T23:29:15Z

dmvt marked the issue as duplicate of #475

#7 - c4-judge

2023-03-01T23:29:26Z

dmvt marked the issue as selected for report

#8 - c4-judge

2023-03-03T19:50:32Z

dmvt marked the issue as satisfactory

Findings Information

Awards

14.932 USDC - $14.93

Labels

bug
2 (Med Risk)
satisfactory
sponsor confirmed
duplicate-558

External Links

Lines of code

https://github.com/code-423n4/2023-01-popcorn/blob/main/src/vault/adapter/abstracts/AdapterBase.sol#L438

Vulnerability details

Impact

AdapterBase implements a cooldown period that's supposed to limit the Strategy from harvesting. However, the lastHarvest time is never updated resulting in every call to harvest() to call the underlying strategy despite there potentially being a cooldown period.

Proof of Concept

Since lastHarvest time is never updated, as soon as (lastHarvest + harvestCooldown) is > block.timestamp, any subsequent calls to harvest will call the strategy since (lastHarvest + harvestCooldown) will always be less than block.timestamp.

function harvest() public takeFees { if ( address(strategy) != address(0) && ((lastHarvest + harvestCooldown) < block.timestamp) ) { // solhint-disable address(strategy).delegatecall( abi.encodeWithSignature("harvest()") ); } emit Harvested(); }

Tools Used

Foundry

Update lastHarvest time -

function harvest() public takeFees { if ( address(strategy) != address(0) && ((lastHarvest + harvestCooldown) < block.timestamp) ) { // *** Update last harvest time *** lastHarvest = block.timestamp; // *** Update last harvest time *** // solhint-disable address(strategy).delegatecall( abi.encodeWithSignature("harvest()") ); } emit Harvested(); }

#0 - c4-judge

2023-02-16T04:25:50Z

dmvt marked the issue as duplicate of #199

#1 - c4-sponsor

2023-02-18T12:00:32Z

RedVeil marked the issue as sponsor confirmed

#2 - c4-judge

2023-02-23T22:30:13Z

dmvt marked the issue as satisfactory

Findings Information

🌟 Selected for report: aashar

Also found by: 0xmuxyz, 7siech, Aymen0909, hashminer0725, rbserver, supernova

Labels

bug
2 (Med Risk)
disagree with severity
downgraded by judge
partial-25
sponsor confirmed
duplicate-396

Awards

22.0241 USDC - $22.02

External Links

Lines of code

https://github.com/code-423n4/2023-01-popcorn//blob/main/src/vault/Vault.sol#L88

Vulnerability details

Impact

It is possible to deploy a vault with 1e18 deposit, withdraw, management, performance fees locking up user assets.

Proof of Concept

https://gist.github.com/alpeware/bf3bf78112f3106d667c0f2dca25679e#file-vaultmaxfee-t-sol https://gist.github.com/alpeware/bf3bf78112f3106d667c0f2dca25679e#file-log-txt

Tools Used

Foundry

In the constructor, call proposeFees(fees) [0] and changeFees() [1] instead.

[0] https://github.com/code-423n4/2023-01-popcorn//blob/main/src/vault/Vault.sol#L525 [1] https://github.com/code-423n4/2023-01-popcorn//blob/main/src/vault/Vault.sol#L540

#0 - c4-judge

2023-02-16T04:18:58Z

dmvt marked the issue as duplicate of #198

#1 - c4-sponsor

2023-02-18T12:00:06Z

RedVeil marked the issue as disagree with severity

#2 - c4-sponsor

2023-02-18T12:00:11Z

RedVeil marked the issue as sponsor confirmed

#3 - c4-judge

2023-02-23T16:19:42Z

dmvt changed the severity to 2 (Med Risk)

#4 - c4-judge

2023-02-23T23:03:00Z

dmvt marked the issue as partial-25

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