/**
*Submitted for verification at Etherscan.io on 2023-08-06
*/
pragma solidity ^0.8.4;
// SPDX-License-Identifier: MIT
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount)
external
returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
}
contract PinkyExchange {
IERC20 public pinkyToken;
IERC20 public usdtToken;
uint256 public exchangeRateEth;
uint256 public exchangeRateUsdt;
address public admin;
event TokensPurchasedWithEth(address buyer, uint256 amount);
event TokensPurchasedWithUsdt(address buyer, uint256 amount);
event ExchangeRateEthUpdated(uint256 oldRate, uint256 newRate);
event ExchangeRateUsdtUpdated(uint256 oldRate, uint256 newRate);
event OwnershipTransferred(address oldAdmin, address newAdmin);
constructor(
IERC20 _pinkyToken,
IERC20 _usdtToken,
uint256 _exchangeRateEth,
uint256 _exchangeRateUsdt
) {
pinkyToken = _pinkyToken;
usdtToken = _usdtToken;
exchangeRateEth = _exchangeRateEth;
exchangeRateUsdt = _exchangeRateUsdt;
admin = msg.sender;
}
function buyTokensWithETH() public payable {
uint256 amountToBuy = msg.value * exchangeRateEth;
require(
pinkyToken.balanceOf(address(this)) >= amountToBuy,
"Not enough tokens in the reserve"
);
pinkyToken.transfer(msg.sender, amountToBuy);
emit TokensPurchasedWithEth(msg.sender, amountToBuy);
}
function buyTokensWithUSDT(uint256 _usdtAmount) public {
uint256 amountToBuy = _usdtAmount * exchangeRateUsdt;
require(
pinkyToken.balanceOf(address(this)) >= amountToBuy,
"Not enough tokens in the reserve"
);
require(
usdtToken.allowance(msg.sender, address(this)) >= _usdtAmount,
"Not enough USDT approved for transfer"
);
usdtToken.transferFrom(msg.sender, address(this), _usdtAmount);
pinkyToken.transfer(msg.sender, amountToBuy);
emit TokensPurchasedWithUsdt(msg.sender, amountToBuy);
}
function getETHExchangeRate() public view returns (uint256) {
return exchangeRateEth;
}
function getUSDTExchangeRate() public view returns (uint256) {
return exchangeRateUsdt;
}
function setETHExchangeRate(uint256 newRate) public {
require(msg.sender == admin, "Only admin can set exchange rate");
emit ExchangeRateEthUpdated(exchangeRateEth, newRate);
exchangeRateEth = newRate;
}
function setUSDTExchangeRate(uint256 newRate) public {
require(msg.sender == admin, "Only admin can set exchange rate");
emit ExchangeRateUsdtUpdated(exchangeRateUsdt, newRate);
exchangeRateUsdt = newRate;
}
function withdrawETH(uint256 _amount) public {
require(msg.sender == admin, "Only admin can withdraw ETH");
require(
address(this).balance >= _amount,
"Contract does not have enough balance"
);
payable(admin).transfer(_amount);
}
function withdrawPinkyTokens(uint256 _amount) public {
require(msg.sender == admin, "Only admin can withdraw tokens");
require(
pinkyToken.balanceOf(address(this)) >= _amount,
"Not enough tokens in the contract"
);
pinkyToken.transfer(admin, _amount);
}
function withdrawUsdtTokens(uint256 _amount) public {
require(msg.sender == admin, "Only admin can withdraw USDT tokens");
require(
usdtToken.balanceOf(address(this)) >= _amount,
"Not enough USDT tokens in the contract"
);
usdtToken.transfer(admin, _amount);
}
function transferOwnership(address newAdmin) public {
require(msg.sender == admin, "Only admin can transfer ownership");
emit OwnershipTransferred(admin, newAdmin);
admin = newAdmin;
}
}
{
"compilationTarget": {
"PinkyExchange.sol": "PinkyExchange"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IERC20","name":"_pinkyToken","type":"address"},{"internalType":"contract IERC20","name":"_usdtToken","type":"address"},{"internalType":"uint256","name":"_exchangeRateEth","type":"uint256"},{"internalType":"uint256","name":"_exchangeRateUsdt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"ExchangeRateEthUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"ExchangeRateUsdtUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensPurchasedWithEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensPurchasedWithUsdt","type":"event"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyTokensWithETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_usdtAmount","type":"uint256"}],"name":"buyTokensWithUSDT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchangeRateEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangeRateUsdt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getETHExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUSDTExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pinkyToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"setETHExchangeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"setUSDTExchangeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdtToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawPinkyTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawUsdtTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]