Skip to content

Instantly share code, notes, and snippets.

@ShariqKhan2012
Created July 16, 2025 14:35
Show Gist options
  • Select an option

  • Save ShariqKhan2012/960b81b12ecbd5b30e8f28ec03e7badd to your computer and use it in GitHub Desktop.

Select an option

Save ShariqKhan2012/960b81b12ecbd5b30e8f28ec03e7badd to your computer and use it in GitHub Desktop.
A TokenShop implementation that demonstrates use of the ChainLink price feed to fetch ETH/USD prices
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {AggregatorV3Interface} from "@chainlink/contracts@1.3.0/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
import {Ownable} from "@openzeppelin/contracts@5.2.0/access/Ownable.sol";
import {MyERC20} from "./MyERC20_OpenZeppelin.sol";
contract TokenShop is Ownable {
error TokenShop__CouldNotWithdraw();
error TokenShop__ZeroETHSent();
event BalanceWithdrawn();
uint256 public constant TOKEN_DECIMALS = 18;
uint256 public constant TOKEN_PRICE_IN_USD = 2 * 10 ** TOKEN_DECIMALS;
MyERC20 private immutable i_token;
AggregatorV3Interface private immutable i_priceFeed;
constructor(address tokenAddress) Ownable(msg.sender) {
i_token = MyERC20(tokenAddress);
/**
* Network: Sepolia Testnet
* Aggregator: ETH/USD
* Address: 0x694AA1769357215DE4FAC081bf1f309aDC325306
*/
i_priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
}
function getETHPriceInUSDFromChainLink() public view returns (int256) {
(
/*uint256 roundId*/,
int256 price,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = i_priceFeed.latestRoundData();
return price;
}
function amountToMint(uint256 ethAmountInWei) public view returns(uint256) {
/**
* 1 Token = TOKEN_PRICE_IN_USD USD
* => 1 USD = 1 / TOKEN_PRICE_IN_USD Tokens
*
* 1 ETH = getETHPriceInUSDFromChainLink() USD
* => 1 ETH = ( getETHPriceInUSDFromChainLink() / TOKEN_PRICE_IN_USD ) Tokens
* => N ETH = (N * getETHPriceInUSDFromChainLink() ) / TOKEN_PRICE_IN_USD ) Tokens
*
* Now, N (ethAmountInWei) has 18 decimals, as it is in Wei (1 ETH = 10**18 Wei)
* TOKEN_PRICE_IN_USD too has 18 decimals
* So, we need to normalize the result of getETHPriceInUSDFromChainLink as well to 18
* ChainLink returns the results with 8 decimals, so we need to multiply by 10**10
*
* => N ETH = (N * getETHPriceInUSDFromChainLink() * 10 ** 10 ) / TOKEN_PRICE_IN_USD ) Tokens
*/
uint256 ethPriceInUSD = uint256( getETHPriceInUSDFromChainLink());
return (ethAmountInWei * ethPriceInUSD * 10**10) / TOKEN_PRICE_IN_USD;
}
receive() external payable {
if(msg.value <= 0) {
revert TokenShop__ZeroETHSent();
}
uint256 numTokensToMint = amountToMint(msg.value);
i_token.mint(msg.sender, numTokensToMint);
}
function withdraw() external onlyOwner {
(bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
if(!success) {
revert TokenShop__CouldNotWithdraw();
}
emit BalanceWithdrawn();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment