code-423n4 / 2023-05-ajna-findings

2 stars 0 forks source link

In getPoolAccumulators function of Ajna protocol allows for manipulation of token exchange rates and potential loss of funds #403

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-core/src/RewardsManager.sol#L636-L661

Vulnerability details

Impact

There is a function called getPoolAccumulators. This function is used to calculate the total ajna tokens burned and total interest earned by a pool since a given block.

However, the problem with this function is that it does not check whether the input values currentBurnEventEpoch_ and lastBurnEventEpoch_ are valid or not. This means that a malicious user can pass any values to the function, even if they are incorrect or manipulated.

This could result in the function returning incorrect values for the total ajna tokens burned and total interest earned. If these incorrect values are then used to calculate the exchange rate of the tokens, it could result in the transfer of more or fewer tokens than intended, which could lead to a loss of funds for the user.

In simple terms, it's like a calculator that takes two inputs and returns an output. But in this case, the calculator doesn't check whether the inputs are correct or not. This means that someone could put in the wrong numbers, and the calculator will still give an answer. If the answer is used to make important decisions, it could lead to problems.

In the getPoolAccumulators function, which takes two arguments currentBurnEventEpoch_ and lastBurnEventEpoch_ without checking if they are valid burn event epochs. This can allow an attacker to manipulate the values of these arguments, which can cause the function to return incorrect values for the total ajna tokens burned and total interest earned. https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-core/src/RewardsManager.sol#L636-L661

An attacker can exploit this vulnerability by passing invalid values for currentBurnEventEpoch and lastBurnEventEpoch. Specifically, they can pass values that are outside the valid range of burn event epochs for the given pool, or values that have not yet occurred.

For example, let's assume the valid range of burn event epochs for our pool is between 1 and 100. If the attacker passes a value of 200 for currentBurnEventEpoch and a value of 150 for lastBurnEventEpoch, the _getPoolAccumulators function will still execute without error, but the values returned for totalBurned and totalInterest will be incorrect, since they will be calculated using invalid burn event epochs.

Proof of Concept

Assume there is a decentralized exchange (DEX) contract where Alice and Bob are traders. The DEX contract uses the _getPoolAccumulators function to calculate the exchange rate between two tokens when a trade is executed. The exchange rate is calculated based on the total tokens burned and total interest earned by the DEX since the last trade.

Alice wants to buy Token A with Token B, so she sends a transaction to the DEX contract with a swap request. The DEX contract calls the _getPoolAccumulators function to calculate the exchange rate and the amount of Token A that Alice will receive in exchange for Token B. The _getPoolAccumulators function retrieves the current burn event epoch and last burn event epoch from the DEX contract and uses these values to calculate the exchange rate.

Now, let's assume that the attacker has created a malicious contract that calls the _getPoolAccumulators function with invalid values for current burn event epoch and last burn event epoch. When the malicious contract interacts with the DEX contract, it provides the invalid epoch values. The _getPoolAccumulators function retrieves the invalid epoch values and calculates the exchange rate based on incorrect values.

As a result, Alice will receive an incorrect amount of Token A, and the attacker will receive a higher amount of Token B than expected. The attacker can use this to steal funds or execute a denial-of-service attack on the smart contract. This is because the attacker can manipulate the total tokens burned and total interest earned by the DEX contract since the last trade.

Tools Used

Vscode

Recommended Mitigation Steps

The _getPoolAccumulators function should include checks to ensure that the passed burn event epochs are within the valid range of epochs for the given pool, and that currentBurnEventEpoch is not less than lastBurnEventEpoch_.

Assessed type

Error

c4-judge commented 1 year ago

Picodes marked the issue as unsatisfactory: Invalid