The LiquidityReserve contract does not receive Reward Tokens from contract Owner when enabling the liquidity reserve. So rewardTokenBalance is 0,coolDownAmount is also zero.
This would allow anyone adding liquidity mint 1:1 liquidity reserve token (amount added is amount received).
Proof of Concept
onlyOwner calls enableLiquidityReserve() .
1000 stakingToken is transferred to LiquidityReserve contract and lrFox token is minted.
No rewardToken is transferred to contract, ERC20Upgradeable(rewardToken).balanceOf(address(this) is 0.
addLiquidity() is then called some time later by Alice with 1000 amount of USDC as _amount input.
The following are as follows:
totalLockedValue = stakingTokenBalance + rewardTokenBalance + coolDownAmount
coolDownAmount is 0 since contract has no CoolDownInfo yet.
Lines of code
https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/LiquidityReserve.sol#L104-L127 https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/LiquidityReserve.sol#L57-L86
Vulnerability details
Impact
The LiquidityReserve contract does not receive Reward Tokens from contract Owner when enabling the liquidity reserve. So
rewardTokenBalance
is 0,coolDownAmount
is also zero.This would allow anyone adding liquidity mint 1:1 liquidity reserve token (amount added is amount received).
Proof of Concept
enableLiquidityReserve()
.ERC20Upgradeable(rewardToken).balanceOf(address(this)
is 0.addLiquidity()
is then called some time later by Alice with 1000 amount of USDC as_amount
input.The following are as follows: totalLockedValue = stakingTokenBalance + rewardTokenBalance + coolDownAmount coolDownAmount is 0 since contract has no CoolDownInfo yet.
totalLockedValue = 1000 + 0 + 0 amountToMint = 1000 * 1000 / 1000 = 1000
Tools Used
Manual review
Recommended Mitigation Steps
During
enableLiquidityReserve()
, onlyOwner should also transfer rewardTokens to the contract.