Platform: Code4rena
Start Date: 10/02/2022
Pot Size: $30,000 USDC
Total HM: 5
Participants: 24
Period: 3 days
Judge: harleythedog
Total Solo HM: 3
Id: 86
League: ETH
Rank: 10/24
Findings: 1
Award: $1,024.84
π Selected for report: 0
π Solo Findings: 0
https://github.com/code-423n4/2022-02-nested/blob/main/contracts/FeeSplitter.sol#L155
addOperator/removeOperator
being run alone don't have any effect, as the cache is used in operations, which is only updated when an implementation is added or removed via importOperators
.
If an operation is added via addOperator
, but importOperators
isn't yet called, the cache doesn't include new operation and it's not usable.
More dangerously, when operator is removed with removeOperator
, it is still can be used, even if rebuildCaches
was called after that, as an operator is removed from cache only when implementation is zero, so until that is done via importOperators
, the deleted operator can be still called by user facing functions.
If operator removal was linked to security considerations this opens up an attack surface, when a malicious user front runs importOperators
, invoking the operator to be deleted as itβs still in the cache and can be accessed with callOperator
.
This dependency was described among other points in https://github.com/code-423n4/2021-11-nested-findings/issues/139, but isn't yet addressed, as the need of atomic run and now corrected removeOperator
implementation were independent issues.
NestedFactory.addOperator/removeOperator only manage the operators
array:
https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L100-122
rebuildCaches
remove operator from cache only after its implementation is set to zero:
https://github.com/code-423n4/2022-02-nested/blob/main/contracts/OperatorResolver.sol#L74
importOperators
is effectively adds and removes operators by changing their implementation:
https://github.com/code-423n4/2022-02-nested/blob/main/contracts/OperatorResolver.sol#L52-70
This way addOperator/removeOperator
should only be run atomically with importOperators
within one transaction to prevent front running.
As both addOperator/removeOperator
aren't effective alone, while addOperator/removeOperator
and importOperators
are both only owner run, and, given that this functions are basically two parts of one operation, consider add importOperators
call to addOperator/removeOperator
.
addOperator/removeOperator
arguments to be expanded to include Operator
structure to be set for the operator via importOperators
.
#0 - maximebrugel
2022-02-14T12:36:20Z