Closed sherlock-admin closed 11 months ago
1 comment(s) were left on this issue during the judging contest.
141345 commented:
m
Escalate
This issue is marked as won't fixed in the v1 version of the audit here: https://github.com/sherlock-audit/2023-05-perennial-judging/issues/46
According to sherlocks rules:
In an update contest, issues from the previous contest with wont fix labels are not considered valid.
According to sponsor comment:
We won't be adding a solidity level fix at this time, but we will update our deploy scripts to create an initial deposit
Can you confirm @arjun-io ?
Escalate
This issue is marked as won't fixed in the v1 version of the audit here: https://github.com/sherlock-audit/2023-05-perennial-judging/issues/46
According to sherlocks rules:
In an update contest, issues from the previous contest with wont fix labels are not considered valid.
According to sponsor comment:
We won't be adding a solidity level fix at this time, but we will update our deploy scripts to create an initial deposit
Can you confirm @arjun-io ?
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
Escalate
Inflation of shares is not possible.
During settlement, pending deposits will be converted to shares in the following way: Vault#_settle->Account#processLocal->Checkpoint#toSharesLocal->Checkpoint#_toShares
As we can see, shares is calculated as depositedAssets*checkpoint.shares/checkpoint.assets.
checkpoint.assets is updated here, which calls this.
First depositor bug would have been possible if shares was calculated as: depositedAssets*checkpoint.shares/assets.balanceOf(address(this)).
The _socialize function basically does this: If the amount that user wants to claim is more than total assets available in vault, the user should receive a pro-rata share of the total assets available, so that other users will be able to claim assets as well. Similarly, if the total assets available is greater than the totalAssets legally deposited, _socialize will allow each user to be able to claim more assets because the unaccounted assets will be distributed to legal depositors proportionately.
So if an "attacker" transfers 10000e18 - 1
of asset token as described in the report, and another user legally deposits 1 wei, 1 wei of shares will be minted to user, and _socialize will allow attacker to claim (1/2)10000e18 asset tokens, and the other user will also claim (1/2)10000e18 asset tokens, which means loss for the attacker.
Escalate
Inflation of shares is not possible.
During settlement, pending deposits will be converted to shares in the following way: Vault#_settle->Account#processLocal->Checkpoint#toSharesLocal->Checkpoint#_toShares
As we can see, shares is calculated as depositedAssets*checkpoint.shares/checkpoint.assets.
checkpoint.assets is updated here, which calls this.
First depositor bug would have been possible if shares was calculated as: depositedAssets*checkpoint.shares/assets.balanceOf(address(this)).
The _socialize function basically does this: If the amount that user wants to claim is more than total assets available in vault, the user should receive a pro-rata share of the total assets available, so that other users will be able to claim assets as well. Similarly, if the total assets available is greater than the totalAssets legally deposited, _socialize will allow each user to be able to claim more assets because the unaccounted assets will be distributed to legal depositors proportionately.
So if an "attacker" transfers
10000e18 - 1
of asset token as described in the report, and another user legally deposits 1 wei, 1 wei of shares will be minted to user, and _socialize will allow attacker to claim (1/2)10000e18 asset tokens, and the other user will also claim (1/2)10000e18 asset tokens, which means loss for the attacker.
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
@141345
Result:
Low
Unique
Considering this generic issue related to vaults was already rewarded in the previous contest and has a Wont fix
label, this is a low issue.
Escalations have been resolved successfully!
Escalation status:
Note for the fix review: the above fix had a slight bug which is fixed here: https://github.com/equilibria-xyz/perennial-v2/pull/101#pullrequestreview-1630111017
tives
medium
Early Vault depositor can manipulate exchange rates to steal funds from later depositors
Summary
An early user can manipulate the price per share and profit from late users' deposits because of the precision loss caused by the large value of price per share.****
Vulnerability Detail
Part 1: deposit
A malicious early user can deposit
1 wei
of token as the first depositor to the Vault, and get1 wei
of shares.User shares are set in processLocal/processGlobal. These are called in _settle, which is also called in
Vault.update(... depositAssets ...)
_withSpread
sets the shares amount to 1 wei (return totalAmount.isZero() ? amount : …
)Now, the attacker has 1 share for 1 wei of tokens.
Part 2: share value inflation
Then the attacker can send
10000e18 - 1
ofasset
token to the Vault and inflate the price per share from 1.0000 to an extreme value of 1.0000e22 ( from(1 + 10000e18 - 1) / 1
) .Part 3: redeeming for inflated share price
The
_socialize
function returns the claim amount._socialize
in turn calls_collateral
, which usesasset.balanceOf()
to return the collateral amountThis means that the
claimAmount
is calculated according to asset.balanceOf(). This means that adversary has retained her initial shares but inflated the share price via sending in tokens manually.She can now receive more tokens than her shares are worth. These tokens come from the later depositors.
Impact
Initial depositor steals from late depositors due to inflated share price.
Code Snippet
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-vault/contracts/Vault.sol/#L486
Tool used
Manual Review
Recommendation
Require a bigger initial deposit or premint some shares and burn them before the first deposit. This is a well known attack vector for ERC4626 vaults. You can read more about it here