sherlock-audit / 2023-07-perennial-judging

2 stars 1 forks source link

KingNFT - Increasing of ````pyth.getUpdateFee()```` may cause keepers refusing to work #96

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

KingNFT

medium

Increasing of pyth.getUpdateFee() may cause keepers refusing to work

Summary

The pyth.getUpdateFee() is not compensated to keepers. Though it's a negligible 1 wei cost currently. But if the Pyth project becomes more popular, they are likely to increase the fee to a reasonable amount. Then, keeper will get less premium, or even lead to deficits.

Vulnerability Detail

Here is related source codes, please pay attention on L190 of _validateAndGetPrice() function,the pyth.getUpdateFee() is sent to Pyth's contract. And L40~57 of keep(), there is no compensation for this fee.


File: perennial-v2\packages\perennial-oracle\contracts\pyth\PythOracle.sol
124:     function commitRequested(uint256 versionIndex, bytes calldata updateData)
125:         public
126:         payable
127:         keep(KEEPER_REWARD_PREMIUM, KEEPER_BUFFER, "")
128:     {
...
135:         uint256 versionToCommit = versionList[versionIndex];
136:         PythStructs.Price memory pythPrice = _validateAndGetPrice(versionToCommit, updateData);
...
157:     }

File: perennial-v2\packages\perennial-oracle\contracts\pyth\PythOracle.sol
184:     function _validateAndGetPrice(uint256 oracleVersion, bytes calldata updateData) private returns (PythStructs.Price memory price) {
185:         bytes[] memory updateDataList = new bytes[](1);
186:         updateDataList[0] = updateData;
187:         bytes32[] memory idList = new bytes32[](1);
188:         idList[0] = id;
189: 
190:         return pyth.parsePriceFeedUpdates{value: pyth.getUpdateFee(updateDataList)}(
191:             updateDataList,
192:             idList,
193:             SafeCast.toUint64(oracleVersion + MIN_VALID_TIME_AFTER_VERSION),
194:             SafeCast.toUint64(oracleVersion + MAX_VALID_TIME_AFTER_VERSION)
195:         )[0].price;
196:     }

File: root\contracts\attribute\Kept.sol
40:     modifier keep(UFixed18 multiplier, uint256 buffer, bytes memory data) {
41:         uint256 startGas = gasleft();
42: 
43:         _;
44: 
45:         uint256 gasUsed = startGas - gasleft();
46:         UFixed18 keeperFee = UFixed18Lib.from(gasUsed)
47:             .mul(multiplier)
48:             .add(UFixed18Lib.from(buffer))
49:             .mul(_etherPrice())
50:             .mul(UFixed18.wrap(block.basefee));
51: 
52:         _raiseKeeperFee(keeperFee, data);
53: 
54:         keeperToken().push(msg.sender, keeperFee);
55: 
56:         emit KeeperCall(msg.sender, gasUsed, multiplier, buffer, keeperFee);
57:     }

Impact

Increasing of pyth.getUpdateFee() may cause keepers refusing to work

Code Snippet

https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial-oracle/contracts/pyth/PythOracle.sol#L190

Tool used

Manual Review

Recommendation

Take pyth.getUpdateFee() into consideration.

sherlock-admin commented 1 year ago

1 comment(s) were left on this issue during the judging contest.

141345 commented:

l