PoolTogether Aave v3 contest - 0xDjango's results

A protocol for no loss prize savings on Ethereum.

General Information

Platform: Code4rena

Start Date: 29/04/2022

Pot Size: $22,000 USDC

Total HM: 6

Participants: 40

Period: 3 days

Judge: Justin Goro

Total Solo HM: 2

Id: 114

League: ETH

PoolTogether

Findings Distribution

Researcher Performance

Rank: 11/40

Findings: 3

Award: $603.76

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: WatchPug

Also found by: 0xDjango, CertoraInc, Tadashi, berndartmueller, kebabsec, leastwood, unforgiven

Labels

bug
duplicate
3 (High Risk)

Awards

500.8447 USDC - $500.84

External Links

Lines of code

https://github.com/pooltogether/aave-v3-yield-source/blob/e63d1b0e396a5bce89f093630c282ca1c6627e44/contracts/AaveV3YieldSource.sol#L232 https://github.com/pooltogether/aave-v3-yield-source/blob/e63d1b0e396a5bce89f093630c282ca1c6627e44/contracts/AaveV3YieldSource.sol#L361

Vulnerability details

Impact

A malicious, but generous, early depositor can DOS all future deposits. This is accomplished by directly sending aTokens to the AaveV3YieldSource.sol contract after making their first deposit. The amount of aTokens sent to the contract will manipulate the share distribution for future depositors. Future depositors will need to deposit at least the amount of aTokens sent directly to the contract to receive even a single share.

The griefer could be assumed to be motivated by a desire to undermine the success of PoolTogether by DOSing contract interactions.

Proof of Concept

Steps to exploit:

  • Griefer deposits 1 wei USDC
  • Griefer receives 1 wei share based on the following formula:

return _supply == 0 ? _tokens : _tokens.mul(_supply).div(aToken.balanceOf(address(this)));

Since supply==0, 1 wei shares is minted to the griefer.

  • Next, the griefer directly sends 10,000 ether of USDC to AaveV3YieldSource contract. This artificially inflates the denominator of the above function: aToken.balanceOf(address(this)
  • A prospective user attempts to deposit 5,000 ether USDC but the transaction will revert because of the following check: require(_shares > 0, "AaveV3YS/shares-gt-zero"); Calculation below without safeMath for ease of understanding:

shares = 5,000 ether * 1 wei / 10,000 ether = 0 shares due to precision loss

Therefore, any depositor that attempts to deposit less than 10,000 ether USDC will be unable. Please note that 10,000 USDC is arbitrary. The griefer can send any value.

Finally, it should be noted that the AaveV3YieldSource contract does not have any way to transfer out aTokens to correct the issue.

Tools Used

Manual Review

Instead of relying on aToken.balanceOf(address(this), use internal accounting variables to keep track of the protocol's aToken balance.

In the transferERC20() function, the owner is not allowed to send aTokens. Removing this restriction would help out in this situation.

#0 - PierrickGT

2022-05-03T16:03:48Z

Findings Information

🌟 Selected for report: MaratCerby

Also found by: 0x52, 0xDjango, 0xf15ers, Dravee, GimelSec, IllIllI, Picodes, delfin454000, gzeon, hake, kebabsec, pauliax, reassor, z3s

Labels

bug
QA (Quality Assurance)

Awards

68.2909 USDC - $68.29

External Links

Issue #1 - Code Consistency: Use _requireNotAToken function everywhere

This modifier checks that the input token is not aToken. The check is manually performed in the transferERC20() function. If the purpose of the manual check is to provide a different require message, consider parameterizing the require message in the _requireNotAToken() function.

https://github.com/pooltogether/aave-v3-yield-source/blob/e63d1b0e396a5bce89f093630c282ca1c6627e44/contracts/AaveV3YieldSource.sol#L337

#0 - PierrickGT

2022-05-03T16:49:11Z

Awards

34.6316 USDC - $34.63

Labels

bug
G (Gas Optimization)

External Links

Issue #1 - aToken can be set to immuatable

Since the contract is compiled with Solidity version 0.8.10, aToken can be declared as immutable and set in the constructor, similar to _decimals. There is no setter function for the aToken address other than the constructor.

https://github.com/pooltogether/aave-v3-yield-source/blob/e63d1b0e396a5bce89f093630c282ca1c6627e44/contracts/AaveV3YieldSource.sol#L127

#0 - PierrickGT

2022-05-02T19:38:19Z

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