58 lines
2.0 KiB
Solidity
58 lines
2.0 KiB
Solidity
// SPDX-License-Identifier: UNLICENSED
|
|
pragma solidity ^0.8.0;
|
|
|
|
import "./IPyth.sol";
|
|
import "forge-std/console2.sol";
|
|
|
|
abstract contract PythMulticall {
|
|
function pythAddress() internal virtual returns (address pyth);
|
|
|
|
// Approach #1: this kind of sucks because it forces the payable modifier on all called functions
|
|
function updateFeedsAndCall(
|
|
bytes[] calldata priceUpdateData,
|
|
bytes calldata data
|
|
) public payable returns (bytes memory response) {
|
|
console2.log(msg.sender);
|
|
updatePythPriceFeeds(priceUpdateData);
|
|
|
|
bool success;
|
|
(success, response) = address(this).delegatecall(data);
|
|
|
|
// Check if the call was successful or not.
|
|
if (!success) {
|
|
// If there is return data, the delegate call reverted with a reason or a custom error, which we bubble up.
|
|
if (response.length > 0) {
|
|
assembly {
|
|
let returndata_size := mload(response)
|
|
revert(add(32, response), returndata_size)
|
|
}
|
|
} else {
|
|
// FIXME
|
|
revert("TODO");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Approach #2: requires more code modification but seems nicer
|
|
modifier withPyth(bytes[] calldata pythPrices) {
|
|
updatePythPriceFeeds(pythPrices);
|
|
_;
|
|
}
|
|
|
|
function updatePythPriceFeeds(
|
|
bytes[] calldata priceUpdateData
|
|
) public payable {
|
|
console2.log("updatePythPriceFeeds");
|
|
console2.log(msg.sender);
|
|
console2.log(msg.value);
|
|
|
|
IPyth pyth = IPyth(pythAddress());
|
|
|
|
// Update the prices to the latest available values and pay the required fee for it. The `priceUpdateData` data
|
|
// should be retrieved from our off-chain Price Service API using the `pyth-evm-js` package.
|
|
// See section "How Pyth Works on EVM Chains" below for more information.
|
|
uint fee = pyth.getUpdateFee(priceUpdateData);
|
|
pyth.updatePriceFeeds{value: fee}(priceUpdateData);
|
|
}
|
|
}
|