Streaming Protocol contest - pedroais's results

General Information

Platform: Code4rena

Start Date: 30/11/2021

Pot Size: $100,000 USDC

Total HM: 15

Participants: 36

Period: 7 days

Judge: 0xean

Total Solo HM: 4

Id: 62

League: ETH

Streaming Protocol

Findings Distribution

Researcher Performance

Rank: 11/36

Findings: 5

Award: $2,731.09

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: cmichel

Also found by: GeekyLumberjack, hyh, kenzo, pedroais

Labels

bug
duplicate
3 (High Risk)

Awards

1057.3907 USDC - $1,057.39

External Links

Handle

pedroais

Vulnerability details

Impact

The recoverTokens function will become unusable with reward tokens if they are withdrawn first.

Proof of Concept

With reward tokens excess is defined as balance - (rewardTokenAmount + rewardTokenFeeAmount) https://github.com/code-423n4/2021-11-streaming/blob/5a87fce1190e0da1cf881919ded3573ca9ec4b08/Streaming/src/Locke.sol#L672

The variable rewardTokenAmount never gets updated when rewards are withdrawn so after a withdrawal the balance will decrease while rewardTokenAmount is still the same. As a result, the function will revert and the excess tokens will be lost.

Tools Used

Manual

Add a variable called redeemed reward tokens and define excess as balance - (rewardTokenAmount + rewardTokenFeeAmount-redeemedRewards)

#0 - 0xean

2022-01-14T21:13:00Z

dupe of #214

Findings Information

🌟 Selected for report: toastedsteaksandwich

Also found by: Meta0xNull, Omik, ScopeLift, bitbopper, gzeon, pedroais, wuwe1

Labels

bug
duplicate
3 (High Risk)
sponsor confirmed

Awards

481.7736 USDC - $481.77

External Links

Handle

pedroais

Vulnerability details

Impact

Detailed description of the impact of this finding.

Proof of Concept

The arbitrary call function checks (incentives[who] == 0, "inc") to disallow calling the incentive token contract. https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/Locke.sol#L735

This can be front runned by calling the contract before the token is sent. The governance could use the arbitrary call to front-run an incentive deposit and call the allowance function of the token on behalf of the contract effectively stealing all tokens.

steps :

-Stream is created -The arbitrary call function is used to set allowance on some token (this could be done by watching the mempool and front running incentive deposits) -User deposits incentive tokens -The incentive tokens can be drained by however got the allowance

Tools Used

Manual

Check allowance stays 0 in the arbitrary call function

#0 - brockelmore

2021-12-08T22:29:18Z

#199 is probably better worded

Findings Information

🌟 Selected for report: harleythedog

Also found by: hyh, kenzo, pauliax, pedroais

Labels

bug
duplicate
3 (High Risk)

Awards

1057.3907 USDC - $1,057.39

External Links

Handle

pedroais

Vulnerability details

Impact

If the stream is a sale recover tokens function won't work.

Proof of Concept

Context : The function recover tokens uses balance - (depositTokenAmount- redeemedDepositTokens) to compute excess deposit tokens. RedeemedDepositTokens keeps track of tokens that were redeemed using the claimDepositTokens function.

https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/Locke.sol#L654

Problem : If the stream is a sale the tokens are redeemed using creatorClaimSoldTokens and redeemedDepositTokens won't be updated.

Consequence : If the stream is a sale redeemedDepositTokens will be 0. The function will become unusable because if tokens are claimed (with function to claim sales) the contract's balance will decrease. As a result ERC20(token).balanceOf(address(this)) - (depositTokenAmount - 0) will revert and excess tokens will be locked.

Tools Used

Manual

Update redeemedDepositTokens in creatorClaimSoldTokens .

#0 - 0xean

2022-01-15T01:31:06Z

dupe of #121

Findings Information

🌟 Selected for report: gpersoon

Also found by: GiveMeTestEther, Meta0xNull, bitbopper, hack3r-0m, pauliax, pedroais, wuwe1

Labels

bug
duplicate
1 (Low Risk)

Awards

48.1774 USDC - $48.18

External Links

Handle

pedroais

Vulnerability details

Proof of Concept

The function update stream internal uses an address "who" as input but it's never used inside the function.

#0 - 0xean

2022-01-16T14:13:19Z

dupe of #125

Findings Information

🌟 Selected for report: WatchPug

Also found by: Jujic, cyberboy, defsec, pedroais, robee

Labels

bug
duplicate
G (Gas Optimization)

Awards

9.8622 USDC - $9.86

External Links

Handle

pedroais

Vulnerability details

Impact

Public functions that aren't used inside the contract can be declared external to save gas

#0 - 0xean

2022-01-16T14:26:45Z

dupe of #260

Findings Information

🌟 Selected for report: ye0lde

Also found by: 0x0x0x, Jujic, pedroais, pmerkleplant

Labels

bug
duplicate
G (Gas Optimization)

Awards

13.1496 USDC - $13.15

External Links

Handle

pedroais

Vulnerability details

Impact

!= 0 is a cheaper operation compared to > 0, when dealing with uint.

Occurences

Streaming/src/Locke.sol: 226: if (acctTimeDelta > 0 && ts.tokens > 0) { Streaming/src/Locke.sol: 236: if (tdelta > 0 && unstreamed > 0) { Streaming/src/Locke.sol: 378: require(amount > 0, "amt"); Streaming/src/Locke.sol: 418: require(amount > 0, "amt"); Streaming/src/Locke.sol: 456: require(amount > 0, "amt"); Streaming/src/Locke.sol: 522: require(amount > 0, "amt"); Streaming/src/Locke.sol: 572: require(rewardAmt > 0, "amt"); Streaming/src/Locke.sol: 612: if (fees > 0) { Streaming/src/Locke.sol: 226: if (fees > 0) { Streaming/src/Locke.sol: 612: if (incentives[token] > 0) { Streaming/src/Locke.sol: 679: if (acctTimeDelta > 0 && ts.tokens > 0) {

#0 - 0xean

2022-01-16T14:20:07Z

dupe of #143

Findings Information

🌟 Selected for report: pedroais

Also found by: 0x1f8b

Labels

bug
G (Gas Optimization)
sponsor confirmed

Awards

45.0947 USDC - $45.09

External Links

Handle

pedroais

Vulnerability details

Impact

Useless checks that cost gas

Proof of Concept

Since the Flashloan function has the lock modifier reentrancy is not possible so checking both tokens is useless.

Proposed new function with less code :

function flashloan(address token, address to, uint112 amount, bytes memory data) public lock { require(token == depositToken || token == rewardToken, "erc"); uint256 preTokenBalance = ERC20(token).balanceOf(address(this)); ERC20(token).safeTransfer(to, amount); // the `to` contract should have a public function with the signature: // function lockeCall(address initiator, address token, uint256 amount, bytes memory data); LockeCallee(to).lockeCall(msg.sender, token, amount, data); uint256 postTokenBalance = ERC20(token).balanceOf(address(this)); uint112 feeAmt = amount * 10 / 10000; // 10bps fee require(preTokenBalance + feeAmt <= postTokenBalance, "f1"); if (token == depositToken) { depositTokenFlashloanFeeAmount += feeAmt; } else { rewardTokenFeeAmount += feeAmt; } emit Flashloaned(token, msg.sender, amount, feeAmt); }

Findings Information

🌟 Selected for report: WatchPug

Also found by: pauliax, pedroais, robee

Labels

bug
duplicate
G (Gas Optimization)
sponsor disputed

Awards

18.2633 USDC - $18.26

External Links

Handle

pedroais

Vulnerability details

Impact

Save gas

#0 - brockelmore

2021-12-02T09:40:49Z

Adds to bytecode size and we are basically at the 24kb limit.

#1 - 0xean

2022-01-17T12:08:16Z

dupe of #231

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