Ajna Protocol - J4de'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: 37/114

Findings: 1

Award: $285.37

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: rvierdiiev

Also found by: J4de, SpicyMeatball, volodya

Labels

bug
3 (High Risk)
partial-50
upgraded by judge
duplicate-179

Awards

285.3731 USDC - $285.37

External Links

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-core/src/PositionManager.sol#L320-L323

Vulnerability details

Impact

File: PositionManager.sol
192             // check for previous deposits
193             if (position.depositTime != 0) {
194                 // check that bucket didn't go bankrupt after prior memorialization
195                 if (_bucketBankruptAfterDeposit(pool, index, position.depositTime)) {
196                     // if bucket did go bankrupt, zero out the LP tracked by position manager
197                     position.lps = 0;
198                 }
199             }

The memorializePositions function will check whether the previous depositTime has not yet gone bankrupt. But for the current deposit, it will not be processed, and the current deposit will be processed next time.

File: PositionManager.sol
319         // update position LP state
320         fromPosition.lps -= vars.lpbAmountFrom;
321         toPosition.lps   += vars.lpbAmountTo;
322         // update position deposit time to the from bucket deposit time
323         toPosition.depositTime = vars.depositTime;

In the moveLiquidity function, the previous depositTime of toPosition is not checked and it is directly overwritten. This allows an attacker to use this function to overwrite the depositTime that has not been bankrupted before.

Proof of Concept

  1. Alias call memorializePositions, that bucket didn't go bankrupt
  2. Alias call moveLiquidity overwritten the depositTime

Tools Used

Manual review

It is recommended that moveLiquidity function check the depositTime of toPosition

Assessed type

Invalid Validation

#0 - Picodes

2023-05-14T20:05:15Z

Partial credit has No impact is described.

#1 - c4-judge

2023-05-14T20:11:09Z

Picodes changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-05-18T14:27:06Z

Picodes marked the issue as duplicate of #179

#3 - c4-judge

2023-05-27T16:33:42Z

Picodes marked the issue as partial-50

#4 - c4-judge

2023-05-27T16:40:34Z

Picodes changed the severity to 3 (High Risk)

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