Closed code423n4 closed 2 years ago
This is not an issue as users can just use the official interface
This is invalid. As with several other reports, this requires a user to be sophisticated enough to interact with the contracts directly but not sophisticated enough to check that the contracts they're interacting with are valid. A normal user, as described by the warden, can't really get themselves into this situation.
Lines of code
https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/farming/yVaultLPFarming.sol#L147 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/farming/yVaultLPFarming.sol#L169 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/yVault.sol#L78 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/yVault.sol#L83 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/yVault.sol#L132 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/yVault.sol#L179 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/Controller.sol#L103 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/Controller.sol#L112 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/Controller.sol#L118 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/strategies/StrategyPUSDConvex.sol#L220 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/strategies/StrategyPUSDConvex.sol#L226 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/strategies/StrategyPUSDConvex.sol#L244 https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/strategies/StrategyPUSDConvex.sol#L249
Vulnerability details
Impact
Balance functions within
YVaultLPFarming
,YVault
andController
rely on related contracts to calculate and feedback their supposedly held balances. The relation of those contracts will be illustrated in the POC section, but TLDR of the problem is that none of the upstream contracts check whether a contract requesting balance calculation is benign. This allows attackers to deploy impersonating contracts that have "false balances" displayed.Combined with the lack of check in deposit related functions, users can be easily misguided by impersonating contracts instead of benign one. Any deposit into impersonating contracts can then be automatically claimed by the original benign instance, thus leading to monetary loss of users.
The key point of this attack is lack of checks makes it hard to spot fake contracts. The only difference between a real contract and a fake one would be its deployer, and it is not reasonable to expect everyday users to be tech savvy enough to examine deployment transactions just to check if a contract is legal.
Thus we conclude it is highly possible that attackers can adopt this contract impersonating technique to trick users into depositing tokens into evil contracts. Attackers can then profit by simply using the benign contract.
Proof of Concept
Balance calculation can be summarized into the diagram shown below
Theoretically, when handling a balance calculation request from a lower level in the hierarchy, handlers should check the identity of requester, and proceed to respond to the balance of(and only of) the requester.
However, this check is not present in the
JPEGED
system.We examine the interaction between
YVaultLPFarming
andYVault
to get an overview of the systematic flaw.YVaultLPFarming
calculatesJPEG
balance in_computeUpdate
by addingvault.balanceOfJPEG()
andjpeg.balanceOf(address(this))
, andYVault
forwards the balance calculation toController
without ever checking address ofYVaultLPFarming
This creates the problem where when a malicious
YVaultLPFarming
has a vault pointed to the sameYVault
as some benignYVaultLPFarming
, it will have incorrect estimation of currentBalance. In fact, sinceJPEG
are never intended to stay inYVaultLPFarming
for a long time, thecurrentBalance
will most likely be synchronized to the benignYVaultLPFarming
.Incorrect display of balance in a fake
YVaultLPFarming
itself is already a problem, given that the malicious contract can be set up with storage exactly the same as a benign contract. The only difference will be transaction history, an aspect most users won't dig too much into. And users can easily be misled into believing that the fake contract is actually legitimate.Now we carry on to see how tricking users into using fake contracts can further benefit attackers.
It turns out that the lack of checks does not stop at balance calculation functions, all
deposit
related functions also lack checks. While theYVaultLPFarming
andYVault
pair is still susceptible to attack, we shift our focus to the slightly more complex pair ofYVault
andController
to demonstrate the problem more clearly.YVault.earn
is called to transferCRV
token toController
for yield, andController.earn
will be called inYVault.earn
to handle the part of sendingCRV
tokens into strategy. Once again, we can see that whileController
has the ability to check whethermsg.sender
is a benign vault throughvaults[_token]
, it chooses not to do so.Combined with the previous incorrect balance displacement, we can see that attackers can likely trick users into trusting fake contract instances and deposit their tokens from those.
Finally, let's see why deposit of tokens in fake contracts will lead to monetary loss. We focus on the
YVault
andController
pair again.While balance calculation and token deposit does not check the identity of the requester, withdraw does. The
YVault.withdraw
function attempts to full tokens fromYVault
when required by callingController.withdraw
.However, since
Controller.withdraw
checks the requester ofwithdraw
againstvaults[_token]
, thus the call will always revert for fakeYVault
.This causes any tokens deposited through fake contracts to become un-withdrawable, and since fake instances and benign instances share the same upstream contract, the depossited tokens will actually be assigned to the benign contract.
Thus if an attacker managed to trick users to use malicious contracts(which we have argued earlier to be highly probable), he can enjoy the profit by simply using benign contracts and collecting victim deposited tokens.
While we only illustrated the concept for specific pairs, any two linked components in the relation chain shown above suffers from this problem and can be targeted by attackers.
Tools Used
vim, ganache-cli
Recommended Mitigation Steps
Check before balance calculation and depositing. This can drastically lower the authenticness of fake contracts and make it unlikely for users to be tricked by attackers.
An example fix of the
YVault
toController
contract is shown below