Lucene search

K
code423n4Code4renaCODE423N4:2023-05-AJNA-FINDINGS-ISSUES-470
HistoryMay 11, 2023 - 12:00 a.m.

stake() function: The provided stake function lacks checks to prevent a lender from staking multiple NFTs in the same Ajna pool. The function allows any owned position NFT to be staked without considering whether the lender has already staked in the pool. This potentially opens up the system to an abuse where a lender stakes multiple NFTs for the same liquidity position.

2023-05-1100:00:00
Code4rena
github.com
6
stake function
nft staking
ajna pool
lender abuse
reward distribution
system integrity

Lines of code

Vulnerability details

Impact

The current stake function lacks checks to prevent a lender from staking multiple NFTs in the same Ajna pool. This could lead to an abuse of the system where a lender stakes multiple NFTs for the same liquidity position, potentially earning more rewards than they are entitled to. This could disrupt the fairness of reward distribution and harm the integrity of the system.

Proof of Concept

The stake function currently does not check whether a lender has already staked an NFT in the same Ajna pool. This allows a lender to stake multiple NFTs in the same pool.

Here’s an example of how a rogue lender could exploit this:

// First stake
stake(nftId1);
// Second stake for the same pool
stake(nftId2);

The lender can repeat this process and stake multiple NFTs in the same pool, which is not the intended behavior.

Tools Used

VSC.

Recommended Mitigation Steps

To prevent a lender from staking multiple NFTs in the same Ajna pool, it is recommended to introduce a mapping (stakedPools) to track staked pools per lender. When staking, check this mapping to verify the lender hasn’t staked in the pool. If they have, revert the transaction. If they haven’t, mark the pool as staked.

Here’s a simple example of how such a check could be implemented:

// Mapping to track whether a lender has already staked in a pool
mapping(address => mapping(address => bool)) private stakedPools;

function stake(uint256 tokenId_) external override {
address ajnaPool = PositionManager(address(positionManager)).poolKey(tokenId_);
require(IERC721(address(positionManager)).ownerOf(tokenId_) == msg.sender, “NotOwnerOfDeposit”);
require(!stakedPools[msg.sender][ajnaPool], “Already staked for this pool”);

// ... rest of the stake function ...

// Mark the pool as staked
stakedPools[msg.sender][ajnaPool] = true;

}

Additionally, during the unstake operation, unset the stakedPools flag:

function unstake(uint256 tokenId_) external override {
// … rest of the unstake function …

// Unset the stakedPools flag
stakedPools[msg.sender][ajnaPool] = false;

}

This way, a lender can only stake one NFT per Ajna pool, as intended. This will prevent the staking of multiple NFTs in/for the same pool.

Assessed type

Other


The text was updated successfully, but these errors were encountered:

All reactions