LP tokens are permanently burned if they are transferred to the same account
name: Audit item
about: These are the audit items that end up in the report
title: LP tokens are permanently burned if they are transferred to the same account
labels: "High"
assignees: ""
Summary
Depositors' LP tokens can be transferred between accounts by first approving the transfer with approveLpOwnership() and then by calling the transferLPs() function. It is reasonable to assume that some users would use this function to transfer LP tokens between their own accounts to, for example, keep them in cold storage. If a user approves a transfer to the account holding the LP tokens instead of the one they wish to transfer it to anybody will be able to permanently burn their LP tokens by calling transferLPs().
This can be deemed a user mistake BUT it is a mistake that is allowed to happen in many interactions on EVM chains. Transferring ETH or an ERC20 to the same account has no consequences, it is even a viable way of canceling a transaction (for ETH transfers). Since the consequences are so grave and since it is likely to happen I deem it a severe vulnerability that would likely be blamed on the Ajna contract logic.
There is an incentive to burn any user's LP tokens if they approve ownership to the same account by mistake since it would essentially lock the tokens on the market for a fixed price in perpetuity.
Vulnerability Detail
If a user approves the transfer of LP tokens to the same account anybody can call transferLPs() and burn the approved tokens. In the LenderActions library from L543-L550 we can see that the newOwner_ balance is first incremented and that the balance of owner_ is then deleted. If those addresses are the same the user's balance is first increased and then permanently deleted.
POC
Add the following test to the ERC20TransferLPTokens.t.sol test file.
Tajobin
high
LP tokens are permanently burned if they are transferred to the same account
name: Audit item about: These are the audit items that end up in the report title: LP tokens are permanently burned if they are transferred to the same account labels: "High" assignees: ""
Summary
Depositors' LP tokens can be transferred between accounts by first approving the transfer with
approveLpOwnership()
and then by calling thetransferLPs()
function. It is reasonable to assume that some users would use this function to transfer LP tokens between their own accounts to, for example, keep them in cold storage. If a user approves a transfer to the account holding the LP tokens instead of the one they wish to transfer it to anybody will be able to permanently burn their LP tokens by callingtransferLPs()
.This can be deemed a user mistake BUT it is a mistake that is allowed to happen in many interactions on EVM chains. Transferring ETH or an ERC20 to the same account has no consequences, it is even a viable way of canceling a transaction (for ETH transfers). Since the consequences are so grave and since it is likely to happen I deem it a severe vulnerability that would likely be blamed on the Ajna contract logic.
There is an incentive to burn any user's LP tokens if they approve ownership to the same account by mistake since it would essentially lock the tokens on the market for a fixed price in perpetuity.
Vulnerability Detail
If a user approves the transfer of LP tokens to the same account anybody can call
transferLPs()
and burn the approved tokens. In the LenderActions library from L543-L550 we can see that thenewOwner_
balance is first incremented and that the balance ofowner_
is then deleted. If those addresses are the same the user's balance is first increased and then permanently deleted.POC
Add the following test to the ERC20TransferLPTokens.t.sol test file.
Impact
All LP tokens approved are permanently burned and the underlying funds are unrecoverable.
Code Snippet
https://github.com/sherlock-audit/2023-01-ajna/blob/main/contracts/src/base/Pool.sol#L238
https://github.com/sherlock-audit/2023-01-ajna/blob/main/contracts/src/libraries/external/LenderActions.sol#L543-L550
https://github.com/sherlock-audit/2023-01-ajna/blob/main/contracts/src/base/Pool.sol#L164
Tool used
foundry test
Recommendation
Add a check that
owner_ != newOwner_
in thetransferLPs()
function in the LenderActions library.