Created
March 22, 2024 05:06
-
-
Save kennethhutw/bf7451106ecfc220094a30a9799ab68c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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"
];