when execute Vault.settle(address(0)) ,since account=address(0), context.local actually takes the value of global, but performs the logical calculation of local, and then overwrites global with local at the end, which results in the misaligned value of global.
Vulnerability Detail
Anyone can call Vault.settle(address(0)) to settle global
The register()updateMarket()updateParameter methods also call settle(address(0)) internally
bin2chen
high
settle(address(0)) global overwritten by local
Summary
when execute
Vault.settle(address(0))
,sinceaccount=address(0)
,context.local
actually takes the value ofglobal
, but performs the logical calculation oflocal
, and then overwritesglobal
withlocal
at the end, which results in the misaligned value ofglobal
.Vulnerability Detail
Anyone can call
Vault.settle(address(0))
to settle global Theregister()
updateMarket()
updateParameter
methods also callsettle(address(0))
internallyThe code implementation is as follows.
The first step is to call the
_loadContext(account)
Since
account=address(0)
,context.local
is getting the same value asglobal
, both are_accounts[address(0)]
The second step calls
_settle()
, which calculates both global and local, and sincelocal
is currently taken fromglobal
it is the wrongThe third step calls
_saveContext()
, and thewrong
local
calculated in the second step will be used asglobal
, overriding the realglobal
.Since
account
is equal toaddress(0)
,local
overridesglobal
.This results in an incorrect value in
global
, and an incorrectlatestCheckpoint
calculated in the second_settle(context)
step.Impact
global
values were incorrectly calculated and overwritten, resulting in multiple dependencies onglobal
being calculated incorrectlyCode Snippet
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-vault/contracts/Vault.sol#L190-L197
Tool used
Manual Review
Recommendation
_settle(context)
and_saveContext()
Ignoring the handling ofaccount=address(0)
Duplicate of #62