72 lines
2.5 KiB
Solidity
72 lines
2.5 KiB
Solidity
pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
import "./YourToken.sol";
|
|
|
|
contract Vendor is Ownable {
|
|
/////////////////
|
|
/// Errors //////
|
|
/////////////////
|
|
|
|
// Errors go here...
|
|
error InvalidEthAmount();
|
|
error InsufficientVendorTokenBalance(uint256 available, uint256 required);
|
|
error EthTransferFailed(address to, uint256 amount);
|
|
error InvalidTokenAmount();
|
|
error InsufficientVendorEthBalance(uint256 available, uint256 required);
|
|
|
|
//////////////////////
|
|
/// State Variables //
|
|
//////////////////////
|
|
|
|
YourToken public immutable yourToken;
|
|
uint256 public constant tokensPerEth = 100;
|
|
|
|
////////////////
|
|
/// Events /////
|
|
////////////////
|
|
|
|
// Events go here...
|
|
event BuyTokens(address indexed buyer, uint256 amountOfETH, uint256 amountOfTokens);
|
|
event SellTokens(address indexed seller, uint256 amountOfTokens, uint256 amountOfETH);
|
|
|
|
///////////////////
|
|
/// Constructor ///
|
|
///////////////////
|
|
|
|
constructor(address tokenAddress) Ownable(msg.sender) {
|
|
yourToken = YourToken(tokenAddress);
|
|
}
|
|
|
|
///////////////////
|
|
/// Functions /////
|
|
///////////////////
|
|
|
|
function buyTokens() external payable {
|
|
if (msg.value == 0) revert InvalidEthAmount();
|
|
uint256 receivedToken = msg.value * tokensPerEth;
|
|
uint256 availableToken = yourToken.balanceOf(address(this));
|
|
if (availableToken < receivedToken) revert InsufficientVendorTokenBalance(availableToken, receivedToken);
|
|
yourToken.transfer(msg.sender, receivedToken);
|
|
emit BuyTokens(msg.sender, msg.value, receivedToken);
|
|
}
|
|
|
|
function withdraw() public onlyOwner {
|
|
address ownerAddr = payable(owner());
|
|
(bool sent,) = ownerAddr.call{value: address(this).balance}("");
|
|
if (!sent) revert EthTransferFailed(ownerAddr, address(this).balance);
|
|
}
|
|
|
|
function sellTokens(uint256 amount) public {
|
|
if (amount == 0) revert InvalidTokenAmount();
|
|
yourToken.transferFrom(msg.sender, address(this), amount);
|
|
uint256 receivedEth = amount / tokensPerEth;
|
|
uint256 contractEth = address(this).balance;
|
|
if (contractEth < receivedEth) revert InsufficientVendorEthBalance(contractEth, receivedEth);
|
|
(bool sent,) = payable(msg.sender).call{value: receivedEth}("");
|
|
if (!sent) revert EthTransferFailed(msg.sender, receivedEth);
|
|
emit SellTokens(msg.sender, amount, receivedEth);
|
|
}
|
|
}
|