Closed code423n4 closed 1 year ago
The create2
opcode (used when using Solidity's salt
keyword) takes the address of the creating contract (Factory
) and the given salt to determine the address for the new contract. Thus, Bob can not deploy a malicious Lendgine contract to an arbitrary address which would be used by the LiquidityManager
. For a more detailed explanation, see https://ethereum.stackexchange.com/a/134143
Closing as invalid.
berndartmueller marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/periphery/LiquidityManager.sol#L136 https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/core/Factory.sol#L82
Vulnerability details
Impact
Lendgine contract address is created using a
salt
that is generated by a hash of pool parameters in Factory.sol. A malicious user can create aLendgine
exploit contract that uses the salt generated by exact same encoding but this contract inherits aPair
contract with a malicious custom invariant function.Key vulnerability is that when LP deposits funds into the pool using the
addLiquidity
function inLiquidityManager
, code does not cross check if this address is in thegetLendgine
mapping in Factory.sol. If a malicious contract is compliant withILendgine
interface, it will go undetected in the LiquidityManager functions.When a user tries to add liquidity using the
addLiquidity
function inLiquidityManager
wrapper, computed address for lendgine contract points to the exploitedLendgine
contract. Note that this contract exactly can mimic the original contract with same function signatures & storage states but using a custom AMM invariant function.Proof of Concept
Factory
contractThis exploit
Lendgine
contract has its own custom AMM variant (a malicious variant that captures pool tokens) and uses the exact interface & storage state as original Lendgine contractA user deposits pool tokens into the
Lendgine
contract usingaddLiquidity
inLiquidityManager.sol
. At this point, code does not verify if the contract address is in the list of addresses held in thegetLendgine
mapping ofFactory.sol
User loses all funds to malicious pool
Tools Used
Manual
Recommended Mitigation Steps
Before using
Lendgine
address generated bycomputeAddress
function, verify if this address exists in thegetLendgine
mapping. Revert otherwise.