feat: finish challenge
Some checks failed
Lint / ci (lts/*, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
han
2026-01-21 11:14:11 +07:00
parent fd53a8187a
commit 6702feefe4
14 changed files with 2250 additions and 36 deletions

View File

@@ -10,18 +10,26 @@ contract Vendor is Ownable {
/////////////////
// 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 ///
@@ -35,9 +43,29 @@ contract Vendor is Ownable {
/// Functions /////
///////////////////
function buyTokens() external payable {}
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 {}
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 {}
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);
}
}

View File

@@ -6,5 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// learn more: https://docs.openzeppelin.com/contracts/5.x/erc20
contract YourToken is ERC20 {
constructor() ERC20("Gold", "GLD") {}
constructor() ERC20("Gold", "GLD") {
_mint(msg.sender, 1000 * (10 ** 18));
}
}

View File

@@ -27,14 +27,14 @@ const deployVendor: DeployFunction = async function (hre: HardhatRuntimeEnvironm
* Student TODO:
* - Put the address youre using in the frontend here (leave "" to default to the deployer)
*/
const FRONTEND_ADDRESS: string = "";
const FRONTEND_ADDRESS: string = "0x253F67DF832aBADb8A54aAA9b4A2635fbeDa4Ccf";
/**
* Mode switch:
* - If true: deploy Vendor and seed it with the token balance
* - If false: send tokens to your frontend address (or deployer if unset)
*/
const SEND_TOKENS_TO_VENDOR = false; // Don't switch until Checkpoint 2!
const SEND_TOKENS_TO_VENDOR = true; // Don't switch until Checkpoint 2!
const recipientAddress = FRONTEND_ADDRESS && FRONTEND_ADDRESS.trim().length > 0 ? FRONTEND_ADDRESS : deployer;

View File

@@ -0,0 +1 @@
11155111

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -37,7 +37,7 @@ const config: HardhatUserConfig = {
},
],
},
defaultNetwork: "localhost",
defaultNetwork: "sepolia", //"localhost",
namedAccounts: {
deployer: {
// By default, it will take the first Hardhat account as the deployer