This repository has been archived by the owner on Feb 18, 2024. It is now read-only.
Emmanuel - Vault.sol: settle
ing the 0 address will disrupt accounting
#62
Labels
Has Duplicates
A valid issue with 1+ other issues describing the same vulnerability
High
A valid High severity issue
Reward
A payout will be made for this issue
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
Emmanuel
medium
Vault.sol:
settle
ing the 0 address will disrupt accountingSummary
Due to the ability of anyone to settle the 0 address, the global assets and global shares will be wrong because lower keeper fees were deducted within the
_settle
function.Vulnerability Detail
Within
Vault#_loadContext
function, the context.global is the account of the 0 address, while context.local is the account of the address to be updated or settled:If a user settles the 0 address, the global account will be updated with wrong data.
Here is the _settle logic:
If settle is called on 0 address, _loadContext will give context.global and context.local same data.
In the _settle logic, after the global account(0 address) is updated with the correct data in the
while
loop(specifically through the processGlobal function),the global account gets reupdated with wrong data within the
if
statement through the processLocal function.Wrong assets and shares will be recorded.
The global account's assets and shares should be calculated with toAssetsGlobal and toSharesGlobal respectively, but now, they are calculated with toAssetsLocal and toSharesLocal.
toAssetsGlobal subtracts the globalKeeperFees from the global deposited assets, while toAssetsLocal subtracts globalKeeperFees/Checkpoint.count fees from the local account's assets.
So in the case of settling the 0 address, where global account and local account are both 0 address, within the while loop of _settle function, depositedAssets-globalKeeperFees is recorded for address(0), but then, in the
if
statement, depositedAssets-(globalAssets/Checkpoint.count) is recorded for address(0)And within the
Vault#_saveContext
function, context.global is saved before context.local, so in this case, context.global(which is 0 address with correct data) is overridden with context.local(which is 0 address with wrong data).Impact
The global account will be updated with wrong data, that is, global assets and shares will be higher than it should be because lower keeper fees was deducted.
Code Snippet
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-vault/contracts/Vault.sol#L190
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-vault/contracts/Vault.sol#L315
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-vault/contracts/types/Checkpoint.sol#L99
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-vault/contracts/types/Checkpoint.sol#L119
Tool used
Manual Review
Recommendation
I believe that the ability to settle the 0 address is intended, so an easy fix is to save local context before saving global context:
Before:
After:
The text was updated successfully, but these errors were encountered: