Ajna Protocol - 0xStalin's results

A peer to peer, oracleless, permissionless lending protocol with no governance, accepting both fungible and non fungible tokens as collateral.

General Information

Platform: Code4rena

Start Date: 03/05/2023

Pot Size: $60,500 USDC

Total HM: 25

Participants: 114

Period: 8 days

Judge: Picodes

Total Solo HM: 6

Id: 234

League: ETH

Ajna Protocol

Findings Distribution

Researcher Performance

Rank: 21/114

Findings: 2

Award: $570.75

🌟 Selected for report: 0

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: vakzz

Also found by: 0xStalin, 0xWaitress, SpicyMeatball

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-8

Awards

570.7462 USDC - $570.75

External Links

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-core/src/RewardsManager.sol#L310-L318

Vulnerability details

Impact

An attacker can take all the rewards (AjnaTokens) assigned to the RewardsManager by calling the updateBucketExchangeRatesAndClaim() and passing a malitious contract as the parameter for the pool_ parameter!

Proof of Concept

When the function updateBucketExchangeRatesAndClaim() is called, there is no check to enforce that only valid pools supported by the protocol can be used to go through the process of updating the rewards, even though there are a number of requisites in order to make a successful attack, all the internal calculations are dependent on data received from the pool_ contract, either to determine the execution path to follow or to update the RewardsManager contract's state.

Because of the short period the contest lasts, I didn't code a POC to create an attack, but I'm gonna point out how an attacker could abuse the lack of a check to validate that only valid pools can be used to update rewards.

The attacker will need to send two transactions, the first one will be to update the contract's state and assign a value to the storage that is read by the prevBucketExchangeRate variable, so in the next transaction, this variable will be different than 0, and the next if() statement can be bypassed, thus, proceeding to manipulate the rewards_ that will be taken by the attacker.

The attacker will basically create and deploy malitious contracts implementing the required function that are called as part of the process to update the rewards, and these functions will return specific values that will end up bypassing the checks and setting the contract's storage in a vulnerable state allowing the attacker to get away with as much rewards as he could. In example, listing the functions that will need to be implemented are:

Tools Used

Manual Review

Create a validation to verify that the pool_ parameter received it is actually a real pool supported by the protocol, and if it is not a real pool, rever the transaction!

Assessed type

Invalid Validation

#0 - c4-judge

2023-05-18T10:26:52Z

Picodes marked the issue as duplicate of #207

#1 - c4-judge

2023-05-30T19:15:11Z

Picodes changed the severity to 3 (High Risk)

#2 - c4-judge

2023-05-30T19:17:08Z

Picodes 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