Skip to content

Instantly share code, notes, and snippets.

@kennethhutw
Created March 22, 2024 05:06
Show Gist options
  • Save kennethhutw/bf7451106ecfc220094a30a9799ab68c to your computer and use it in GitHub Desktop.
Save kennethhutw/bf7451106ecfc220094a30a9799ab68c to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Example oracle AMM powered by Pyth price feeds.
//
// The contract holds a pool of two ERC-20 tokens, the BASE and the QUOTE, and allows users to swap tokens
// for the pair BASE/QUOTE. For example, the base could be WETH and the quote could be USDC, in which case you can
// buy WETH for USDC and vice versa. The pool offers to swap between the tokens at the current Pyth exchange rate for
// BASE/QUOTE, which is computed from the BASE/USD price feed and the QUOTE/USD price feed.
//
// This contract only implements the swap functionality. It does not implement any pool balancing logic (e.g., skewing the
// price to reflect an unbalanced pool) or depositing / withdrawing funds. When deployed, the contract needs to be sent
// some quantity of both the base and quote token in order to function properly (using the ERC20 transfer function to
// the contract's address).
contract PythQueryPrice {
IPyth pyth;
// Price
int64 public price;
// Confidence interval around the price
uint64 public conf;
// Price exponent
int32 public expo;
// Unix timestamp describing when the price was published
uint public publishTime;
uint256 public currentPrice;
bytes[] public priceUpdateData;
event tokenPriceTesting(PythStructs.Price price);
constructor(
address _pyth,
bytes[] memory _priceUpdateData
) {
pyth = IPyth(_pyth);
priceUpdateData = _priceUpdateData;
}
function tokenPrice(bytes32 priceID) public payable returns (uint256){
uint fee = pyth.getUpdateFee(priceUpdateData);
pyth.updatePriceFeeds{value: fee}(priceUpdateData);
emit tokenPriceTesting(pyth.getPrice(priceID));
PythStructs.Price memory currentBasePrice = pyth.getPrice(priceID);
price = currentBasePrice.price;
expo = currentBasePrice.expo;
conf = currentBasePrice.conf;
//return pyth.getPrice(priceID);
currentPrice = convertToUint(currentBasePrice, 18);
return currentPrice;
}
function changePriceUpdateData(
bytes[] memory _priceUpdateData
) public returns (bool) {
priceUpdateData = _priceUpdateData;
return true;
}
function changeIPyth(
address _pyth
) public returns (bool) {
pyth = IPyth(_pyth);
return true;
}
function getUpdateFee() public payable {
uint fee = pyth.getUpdateFee(priceUpdateData);
pyth.updatePriceFeeds{value: fee}(priceUpdateData);
}
function getUpdateFee2(bytes32 priceID ) public payable {
uint fee = pyth.getUpdateFee(priceUpdateData);
pyth.updatePriceFeeds{value: fee}(priceUpdateData);
emit tokenPriceTesting(pyth.getPrice(priceID));
}
// TODO: we should probably move something like this into the solidity sdk
function convertToUint(
PythStructs.Price memory _price,
uint8 targetDecimals
) private pure returns (uint256) {
if (_price.price < 0 || _price.expo > 0 || _price.expo < -255) {
revert();
}
uint8 priceDecimals = uint8(uint32(-1 * _price.expo));
if (targetDecimals >= priceDecimals) {
return
uint(uint64(_price.price)) *
10 ** uint32(targetDecimals - priceDecimals);
} else {
return
uint(uint64(_price.price)) /
10 ** uint32(priceDecimals - targetDecimals);
}
}
receive() external payable {}
function withdraw() public {
payable(msg.sender).transfer(address(this).balance);
}
function getBalance() external view returns (uint) {
return address(this).balance;
}
}
@kennethhutw
Copy link
Author

const priceIds = [
// You can find the ids of prices at https://pyth.network/developers/price-feed-ids#pyth-evm-stable
"0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", // BTC/USD price id
"0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", // USDT/USD price id
"0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a", // USDC/USD price id
"0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace", // ETH/USD price id
"0x9d4294bbcd1174d6f2003ec365831e64cc31d9f6f15a2b85399db8d5000960f6"
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment