diff --git a/packages/hardhat/contracts/Vendor.sol b/packages/hardhat/contracts/Vendor.sol index 242bacf..0acb4e8 100644 --- a/packages/hardhat/contracts/Vendor.sol +++ b/packages/hardhat/contracts/Vendor.sol @@ -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); + } } diff --git a/packages/hardhat/contracts/YourToken.sol b/packages/hardhat/contracts/YourToken.sol index 4bacb86..45db876 100644 --- a/packages/hardhat/contracts/YourToken.sol +++ b/packages/hardhat/contracts/YourToken.sol @@ -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)); + } } diff --git a/packages/hardhat/deploy/01_deploy_vendor.ts b/packages/hardhat/deploy/01_deploy_vendor.ts index 17c542a..59f84a5 100644 --- a/packages/hardhat/deploy/01_deploy_vendor.ts +++ b/packages/hardhat/deploy/01_deploy_vendor.ts @@ -27,14 +27,14 @@ const deployVendor: DeployFunction = async function (hre: HardhatRuntimeEnvironm * Student TODO: * - Put the address you’re 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; diff --git a/packages/hardhat/deployments/sepolia/.chainId b/packages/hardhat/deployments/sepolia/.chainId new file mode 100644 index 0000000..bd8d1cd --- /dev/null +++ b/packages/hardhat/deployments/sepolia/.chainId @@ -0,0 +1 @@ +11155111 \ No newline at end of file diff --git a/packages/hardhat/deployments/sepolia/Vendor.json b/packages/hardhat/deployments/sepolia/Vendor.json new file mode 100644 index 0000000..423a3df --- /dev/null +++ b/packages/hardhat/deployments/sepolia/Vendor.json @@ -0,0 +1,363 @@ +{ + "address": "0x7CfE3306c5172f5245036f29A9c9f4aCe2b0DF73", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EthTransferFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "required", + "type": "uint256" + } + ], + "name": "InsufficientVendorEthBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "required", + "type": "uint256" + } + ], + "name": "InsufficientVendorTokenBalance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEthAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAmount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "buyer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfETH", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfTokens", + "type": "uint256" + } + ], + "name": "BuyTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "seller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfETH", + "type": "uint256" + } + ], + "name": "SellTokens", + "type": "event" + }, + { + "inputs": [], + "name": "buyTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "sellTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokensPerEth", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "yourToken", + "outputs": [ + { + "internalType": "contract YourToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xce83ab657ff40e2dfcb534fbcd13900572489b7da0d530c19fbc6c877891c22e", + "receipt": { + "to": null, + "from": "0x339cDeFD985b9A94Dd7d79A850A8ed3e6b88bE35", + "contractAddress": "0x7CfE3306c5172f5245036f29A9c9f4aCe2b0DF73", + "transactionIndex": 5, + "gasUsed": "485583", + "logsBloom": "0x00000000000000004000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000020000000400000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0e008b28eafb1a34cea6a2826b6bd83f924d5c8d4e31c4cc437b6d2338606d39", + "transactionHash": "0xce83ab657ff40e2dfcb534fbcd13900572489b7da0d530c19fbc6c877891c22e", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 10049176, + "transactionHash": "0xce83ab657ff40e2dfcb534fbcd13900572489b7da0d530c19fbc6c877891c22e", + "address": "0x7CfE3306c5172f5245036f29A9c9f4aCe2b0DF73", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000339cdefd985b9a94dd7d79a850a8ed3e6b88be35" + ], + "data": "0x", + "logIndex": 130, + "blockHash": "0x0e008b28eafb1a34cea6a2826b6bd83f924d5c8d4e31c4cc437b6d2338606d39" + } + ], + "blockNumber": 10049176, + "cumulativeGasUsed": "4337204", + "status": 1, + "byzantium": true + }, + "args": [ + "0x981B997C64Aef1316392167c4cC5879e4A5cf7f6" + ], + "numDeployments": 1, + "solcInputHash": "7b8c02112ef40e5ee2ab15c64b581f41", + "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"InsufficientVendorEthBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"InsufficientVendorTokenBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidEthAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"buyer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfETH\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"BuyTokens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"seller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfTokens\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfETH\",\"type\":\"uint256\"}],\"name\":\"SellTokens\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"buyTokens\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"sellTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokensPerEth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"yourToken\",\"outputs\":[{\"internalType\":\"contract YourToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}]},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidEthAmount()\":[{\"notice\":\"Errors //////\"}]},\"events\":{\"BuyTokens(address,uint256,uint256)\":{\"notice\":\"Events /////\"}},\"kind\":\"user\",\"methods\":{\"buyTokens()\":{\"notice\":\"Functions /////\"},\"constructor\":{\"notice\":\"Constructor ///\"},\"yourToken()\":{\"notice\":\"State Variables //\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Vendor.sol\":\"Vendor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n constructor(address initialOwner) {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"./IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"./extensions/IERC20Metadata.sol\\\";\\nimport {Context} from \\\"../../utils/Context.sol\\\";\\nimport {IERC20Errors} from \\\"../../interfaces/draft-IERC6093.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n */\\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\\n mapping(address account => uint256) private _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n _totalSupply += value;\\n } else {\\n uint256 fromBalance = _balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n _balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n _totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n _balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n _allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"contracts/Vendor.sol\":{\"content\":\"pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\\n// SPDX-License-Identifier: MIT\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./YourToken.sol\\\";\\n\\ncontract Vendor is Ownable {\\n /////////////////\\n /// Errors //////\\n /////////////////\\n\\n // Errors go here...\\n error InvalidEthAmount();\\n error InsufficientVendorTokenBalance(uint256 available, uint256 required);\\n error EthTransferFailed(address to, uint256 amount);\\n error InvalidTokenAmount();\\n error InsufficientVendorEthBalance(uint256 available, uint256 required);\\n\\n //////////////////////\\n /// State Variables //\\n //////////////////////\\n\\n YourToken public immutable yourToken;\\n uint256 public constant tokensPerEth = 100;\\n\\n ////////////////\\n /// Events /////\\n ////////////////\\n\\n // Events go here...\\n event BuyTokens(address indexed buyer, uint256 amountOfETH, uint256 amountOfTokens);\\n event SellTokens(address indexed seller, uint256 amountOfTokens, uint256 amountOfETH);\\n\\n ///////////////////\\n /// Constructor ///\\n ///////////////////\\n\\n constructor(address tokenAddress) Ownable(msg.sender) {\\n yourToken = YourToken(tokenAddress);\\n }\\n\\n ///////////////////\\n /// Functions /////\\n ///////////////////\\n\\n function buyTokens() external payable {\\n if (msg.value == 0) revert InvalidEthAmount();\\n uint256 receivedToken = msg.value * tokensPerEth;\\n uint256 availableToken = yourToken.balanceOf(address(this));\\n if (availableToken < receivedToken) revert InsufficientVendorTokenBalance(availableToken, receivedToken);\\n yourToken.transfer(msg.sender, receivedToken);\\n emit BuyTokens(msg.sender, msg.value, receivedToken);\\n }\\n\\n function withdraw() public onlyOwner {\\n address ownerAddr = payable(owner());\\n (bool sent,) = ownerAddr.call{value: address(this).balance}(\\\"\\\"); \\n if (!sent) revert EthTransferFailed(ownerAddr, address(this).balance);\\n }\\n\\n function sellTokens(uint256 amount) public {\\n if (amount == 0) revert InvalidTokenAmount();\\n yourToken.transferFrom(msg.sender, address(this), amount);\\n uint256 receivedEth = amount / tokensPerEth;\\n uint256 contractEth = address(this).balance;\\n if (contractEth < receivedEth) revert InsufficientVendorEthBalance(contractEth, receivedEth);\\n (bool sent,) = payable(msg.sender).call{value: receivedEth}(\\\"\\\");\\n if (!sent) revert EthTransferFailed(msg.sender, receivedEth);\\n emit SellTokens(msg.sender, amount, receivedEth);\\n }\\n}\\n\",\"keccak256\":\"0x681d3ee01246dff05c686ad19f0f3bf472e2b77a8ac7367bb4752e48a73c6897\",\"license\":\"MIT\"},\"contracts/YourToken.sol\":{\"content\":\"pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\\n// SPDX-License-Identifier: MIT\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// learn more: https://docs.openzeppelin.com/contracts/5.x/erc20\\n\\ncontract YourToken is ERC20 {\\n constructor() ERC20(\\\"Gold\\\", \\\"GLD\\\") {\\n _mint(msg.sender, 1000 * (10 ** 18));\\n }\\n}\\n\",\"keccak256\":\"0x65cc5561c7c709702234f80cd1776b2b34cde63584cbff0d12354254dfdff022\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161087538038061087583398101604081905261002f916100c0565b338061005557604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61005e81610070565b506001600160a01b03166080526100f0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100d257600080fd5b81516001600160a01b03811681146100e957600080fd5b9392505050565b60805161075661011f6000396000818160de015281816102620152818161042b01526104df01526107566000f3fe60806040526004361061007b5760003560e01c80638da5cb5b1161004e5780638da5cb5b1461011d578063cbdd69b51461013b578063d0febe4c1461015e578063f2fde38b1461016657600080fd5b80633ccfd60b146100805780636c11bcd314610097578063715018a6146100b75780637879e84b146100cc575b600080fd5b34801561008c57600080fd5b50610095610186565b005b3480156100a357600080fd5b506100956100b236600461064f565b61021f565b3480156100c357600080fd5b506100956103c6565b3480156100d857600080fd5b506101007f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012957600080fd5b506000546001600160a01b0316610100565b34801561014757600080fd5b50610150606481565b604051908152602001610114565b6100956103da565b34801561017257600080fd5b50610095610181366004610668565b610594565b61018e6105d2565b600080546040516001600160a01b039091169190829047908381818185875af1925050503d80600081146101de576040519150601f19603f3d011682016040523d82523d6000602084013e6101e3565b606091505b505090508061021b57604051636f54afdd60e11b81526001600160a01b03831660048201524760248201526044015b60405180910390fd5b5050565b8060000361024057604051632160733960e01b815260040160405180910390fd5b6040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303816000875af11580156102b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d79190610698565b5060006102e56064836106ba565b905047818110156103135760405163e74e064960e01b81526004810182905260248101839052604401610212565b604051600090339084908381818185875af1925050503d8060008114610355576040519150601f19603f3d011682016040523d82523d6000602084013e61035a565b606091505b505090508061038557604051636f54afdd60e11b815233600482015260248101849052604401610212565b604080518581526020810185905233917fa24838acd4af5195a2396965dae5abf54e84e8c19f5698bb966ae64e29994ee5910160405180910390a250505050565b6103ce6105d2565b6103d860006105ff565b565b346000036103fb57604051630772327b60e01b815260040160405180910390fd5b60006104086064346106dc565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610472573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104969190610707565b9050818110156104c3576040516322bba6db60e11b81526004810182905260248101839052604401610212565b60405163a9059cbb60e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015610530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105549190610698565b50604080513481526020810184905233917f0a37b72bb67eee30e09084cf386f8a17817c57f620c3ab95fb25d6a20356ec77910160405180910390a25050565b61059c6105d2565b6001600160a01b0381166105c657604051631e4fbdf760e01b815260006004820152602401610212565b6105cf816105ff565b50565b6000546001600160a01b031633146103d85760405163118cdaa760e01b8152336004820152602401610212565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561066157600080fd5b5035919050565b60006020828403121561067a57600080fd5b81356001600160a01b038116811461069157600080fd5b9392505050565b6000602082840312156106aa57600080fd5b8151801515811461069157600080fd5b6000826106d757634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761070157634e487b7160e01b600052601160045260246000fd5b92915050565b60006020828403121561071957600080fd5b505191905056fea2646970667358221220e08f86c0e27e36f4ce35b11c77ca75b37c105ff1b1f6ea55fefe83096ad183d864736f6c63430008140033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80638da5cb5b1161004e5780638da5cb5b1461011d578063cbdd69b51461013b578063d0febe4c1461015e578063f2fde38b1461016657600080fd5b80633ccfd60b146100805780636c11bcd314610097578063715018a6146100b75780637879e84b146100cc575b600080fd5b34801561008c57600080fd5b50610095610186565b005b3480156100a357600080fd5b506100956100b236600461064f565b61021f565b3480156100c357600080fd5b506100956103c6565b3480156100d857600080fd5b506101007f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012957600080fd5b506000546001600160a01b0316610100565b34801561014757600080fd5b50610150606481565b604051908152602001610114565b6100956103da565b34801561017257600080fd5b50610095610181366004610668565b610594565b61018e6105d2565b600080546040516001600160a01b039091169190829047908381818185875af1925050503d80600081146101de576040519150601f19603f3d011682016040523d82523d6000602084013e6101e3565b606091505b505090508061021b57604051636f54afdd60e11b81526001600160a01b03831660048201524760248201526044015b60405180910390fd5b5050565b8060000361024057604051632160733960e01b815260040160405180910390fd5b6040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303816000875af11580156102b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d79190610698565b5060006102e56064836106ba565b905047818110156103135760405163e74e064960e01b81526004810182905260248101839052604401610212565b604051600090339084908381818185875af1925050503d8060008114610355576040519150601f19603f3d011682016040523d82523d6000602084013e61035a565b606091505b505090508061038557604051636f54afdd60e11b815233600482015260248101849052604401610212565b604080518581526020810185905233917fa24838acd4af5195a2396965dae5abf54e84e8c19f5698bb966ae64e29994ee5910160405180910390a250505050565b6103ce6105d2565b6103d860006105ff565b565b346000036103fb57604051630772327b60e01b815260040160405180910390fd5b60006104086064346106dc565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610472573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104969190610707565b9050818110156104c3576040516322bba6db60e11b81526004810182905260248101839052604401610212565b60405163a9059cbb60e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015610530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105549190610698565b50604080513481526020810184905233917f0a37b72bb67eee30e09084cf386f8a17817c57f620c3ab95fb25d6a20356ec77910160405180910390a25050565b61059c6105d2565b6001600160a01b0381166105c657604051631e4fbdf760e01b815260006004820152602401610212565b6105cf816105ff565b50565b6000546001600160a01b031633146103d85760405163118cdaa760e01b8152336004820152602401610212565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561066157600080fd5b5035919050565b60006020828403121561067a57600080fd5b81356001600160a01b038116811461069157600080fd5b9392505050565b6000602082840312156106aa57600080fd5b8151801515811461069157600080fd5b6000826106d757634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761070157634e487b7160e01b600052601160045260246000fd5b92915050565b60006020828403121561071957600080fd5b505191905056fea2646970667358221220e08f86c0e27e36f4ce35b11c77ca75b37c105ff1b1f6ea55fefe83096ad183d864736f6c63430008140033", + "devdoc": { + "errors": { + "OwnableInvalidOwner(address)": [ + { + "details": "The owner is not a valid owner account. (eg. `address(0)`)" + } + ], + "OwnableUnauthorizedAccount(address)": [ + { + "details": "The caller account is not authorized to perform an operation." + } + ] + }, + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidEthAmount()": [ + { + "notice": "Errors //////" + } + ] + }, + "events": { + "BuyTokens(address,uint256,uint256)": { + "notice": "Events /////" + } + }, + "kind": "user", + "methods": { + "buyTokens()": { + "notice": "Functions /////" + }, + "constructor": { + "notice": "Constructor ///" + }, + "yourToken()": { + "notice": "State Variables //" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8, + "contract": "contracts/Vendor.sol:Vendor", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/sepolia/YourToken.json b/packages/hardhat/deployments/sepolia/YourToken.json new file mode 100644 index 0000000..4fac890 --- /dev/null +++ b/packages/hardhat/deployments/sepolia/YourToken.json @@ -0,0 +1,530 @@ +{ + "address": "0x981B997C64Aef1316392167c4cC5879e4A5cf7f6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x86ffb44c389d5440dcf1e38cdbfd216e8e1d64ae1af1f8d1610565067ba048c8", + "receipt": { + "to": null, + "from": "0x339cDeFD985b9A94Dd7d79A850A8ed3e6b88bE35", + "contractAddress": "0x981B997C64Aef1316392167c4cC5879e4A5cf7f6", + "transactionIndex": 24, + "gasUsed": "552567", + "logsBloom": "0x00000000000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800000000000000000000000000000000000000020000000000000000000800000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000004000000000000000000020000000000000000000000000000080000000000000000080000000000000000000", + "blockHash": "0x5457f3aacec954e1bdd7e623c26b07dd0ff5c793310be10e366384bfbcc93813", + "transactionHash": "0x86ffb44c389d5440dcf1e38cdbfd216e8e1d64ae1af1f8d1610565067ba048c8", + "logs": [ + { + "transactionIndex": 24, + "blockNumber": 10049162, + "transactionHash": "0x86ffb44c389d5440dcf1e38cdbfd216e8e1d64ae1af1f8d1610565067ba048c8", + "address": "0x981B997C64Aef1316392167c4cC5879e4A5cf7f6", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000339cdefd985b9a94dd7d79a850a8ed3e6b88be35" + ], + "data": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "logIndex": 586, + "blockHash": "0x5457f3aacec954e1bdd7e623c26b07dd0ff5c793310be10e366384bfbcc93813" + } + ], + "blockNumber": 10049162, + "cumulativeGasUsed": "18373415", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "b30a1ed2b1d3e3c06d1589ed16c9a78c", + "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"ERC20InsufficientAllowance(address,uint256,uint256)\":[{\"details\":\"Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\",\"params\":{\"allowance\":\"Amount of tokens a `spender` is allowed to operate with.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ERC20InsufficientBalance(address,uint256,uint256)\":[{\"details\":\"Indicates an error related to the current `balance` of a `sender`. Used in transfers.\",\"params\":{\"balance\":\"Current balance for the interacting account.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidApprover(address)\":[{\"details\":\"Indicates a failure with the `approver` of a token to be approved. Used in approvals.\",\"params\":{\"approver\":\"Address initiating an approval operation.\"}}],\"ERC20InvalidReceiver(address)\":[{\"details\":\"Indicates a failure with the token `receiver`. Used in transfers.\",\"params\":{\"receiver\":\"Address to which tokens are being transferred.\"}}],\"ERC20InvalidSender(address)\":[{\"details\":\"Indicates a failure with the token `sender`. Used in transfers.\",\"params\":{\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidSpender(address)\":[{\"details\":\"Indicates a failure with the `spender` to be approved. Used in approvals.\",\"params\":{\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}]},\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/YourToken.sol\":\"YourToken\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"./IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"./extensions/IERC20Metadata.sol\\\";\\nimport {Context} from \\\"../../utils/Context.sol\\\";\\nimport {IERC20Errors} from \\\"../../interfaces/draft-IERC6093.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n */\\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\\n mapping(address account => uint256) private _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n _totalSupply += value;\\n } else {\\n uint256 fromBalance = _balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n _balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n _totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n _balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n _allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"contracts/YourToken.sol\":{\"content\":\"pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\\n// SPDX-License-Identifier: MIT\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// learn more: https://docs.openzeppelin.com/contracts/5.x/erc20\\n\\ncontract YourToken is ERC20 {\\n constructor() ERC20(\\\"Gold\\\", \\\"GLD\\\") {\\n _mint(msg.sender, 1000 * (10 ** 18));\\n }\\n}\\n\",\"keccak256\":\"0x65cc5561c7c709702234f80cd1776b2b34cde63584cbff0d12354254dfdff022\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506040518060400160405280600481526020016311dbdb1960e21b8152506040518060400160405280600381526020016211d31160ea1b81525081600390816200005c9190620002a9565b5060046200006b8282620002a9565b5050506200008933683635c9adc5dea000006200008f60201b60201c565b6200039d565b6001600160a01b038216620000bf5760405163ec442f0560e01b8152600060048201526024015b60405180910390fd5b620000cd60008383620000d1565b5050565b6001600160a01b03831662000100578060026000828254620000f4919062000375565b90915550620001749050565b6001600160a01b03831660009081526020819052604090205481811015620001555760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401620000b6565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166200019257600280548290039055620001b1565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620001f791815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200022f57607f821691505b6020821081036200025057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002a457600081815260208120601f850160051c810160208610156200027f5750805b601f850160051c820191505b81811015620002a0578281556001016200028b565b5050505b505050565b81516001600160401b03811115620002c557620002c562000204565b620002dd81620002d684546200021a565b8462000256565b602080601f831160018114620003155760008415620002fc5750858301515b600019600386901b1c1916600185901b178555620002a0565b600085815260208120601f198616915b82811015620003465788860151825594840194600190910190840162000325565b5085821015620003655787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200039757634e487b7160e01b600052601160045260246000fd5b92915050565b61072080620003ad6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce567146100fe57806370a082311461010d57806395d89b4114610136578063a9059cbb1461013e578063dd62ed3e1461015157600080fd5b806306fdde0314610098578063095ea7b3146100b657806318160ddd146100d957806323b872dd146100eb575b600080fd5b6100a061018a565b6040516100ad919061056a565b60405180910390f35b6100c96100c43660046105d4565b61021c565b60405190151581526020016100ad565b6002545b6040519081526020016100ad565b6100c96100f93660046105fe565b610236565b604051601281526020016100ad565b6100dd61011b36600461063a565b6001600160a01b031660009081526020819052604090205490565b6100a061025a565b6100c961014c3660046105d4565b610269565b6100dd61015f36600461065c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101999061068f565b80601f01602080910402602001604051908101604052809291908181526020018280546101c59061068f565b80156102125780601f106101e757610100808354040283529160200191610212565b820191906000526020600020905b8154815290600101906020018083116101f557829003601f168201915b5050505050905090565b60003361022a818585610277565b60019150505b92915050565b600033610244858285610289565b61024f85858561030c565b506001949350505050565b6060600480546101999061068f565b60003361022a81858561030c565b610284838383600161036b565b505050565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461030657818110156102f757604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b6103068484848403600061036b565b50505050565b6001600160a01b03831661033657604051634b637e8f60e11b8152600060048201526024016102ee565b6001600160a01b0382166103605760405163ec442f0560e01b8152600060048201526024016102ee565b610284838383610440565b6001600160a01b0384166103955760405163e602df0560e01b8152600060048201526024016102ee565b6001600160a01b0383166103bf57604051634a1406b160e11b8152600060048201526024016102ee565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561030657826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161043291815260200190565b60405180910390a350505050565b6001600160a01b03831661046b57806002600082825461046091906106c9565b909155506104dd9050565b6001600160a01b038316600090815260208190526040902054818110156104be5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016102ee565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166104f957600280548290039055610518565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161055d91815260200190565b60405180910390a3505050565b600060208083528351808285015260005b818110156105975785810183015185820160400152820161057b565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146105cf57600080fd5b919050565b600080604083850312156105e757600080fd5b6105f0836105b8565b946020939093013593505050565b60008060006060848603121561061357600080fd5b61061c846105b8565b925061062a602085016105b8565b9150604084013590509250925092565b60006020828403121561064c57600080fd5b610655826105b8565b9392505050565b6000806040838503121561066f57600080fd5b610678836105b8565b9150610686602084016105b8565b90509250929050565b600181811c908216806106a357607f821691505b6020821081036106c357634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561023057634e487b7160e01b600052601160045260246000fdfea2646970667358221220b5d904ff268ef9cf4d17f43579b34609661d28e1f80b0b97869af04c5bd8a9d764736f6c63430008140033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce567146100fe57806370a082311461010d57806395d89b4114610136578063a9059cbb1461013e578063dd62ed3e1461015157600080fd5b806306fdde0314610098578063095ea7b3146100b657806318160ddd146100d957806323b872dd146100eb575b600080fd5b6100a061018a565b6040516100ad919061056a565b60405180910390f35b6100c96100c43660046105d4565b61021c565b60405190151581526020016100ad565b6002545b6040519081526020016100ad565b6100c96100f93660046105fe565b610236565b604051601281526020016100ad565b6100dd61011b36600461063a565b6001600160a01b031660009081526020819052604090205490565b6100a061025a565b6100c961014c3660046105d4565b610269565b6100dd61015f36600461065c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101999061068f565b80601f01602080910402602001604051908101604052809291908181526020018280546101c59061068f565b80156102125780601f106101e757610100808354040283529160200191610212565b820191906000526020600020905b8154815290600101906020018083116101f557829003601f168201915b5050505050905090565b60003361022a818585610277565b60019150505b92915050565b600033610244858285610289565b61024f85858561030c565b506001949350505050565b6060600480546101999061068f565b60003361022a81858561030c565b610284838383600161036b565b505050565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461030657818110156102f757604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b6103068484848403600061036b565b50505050565b6001600160a01b03831661033657604051634b637e8f60e11b8152600060048201526024016102ee565b6001600160a01b0382166103605760405163ec442f0560e01b8152600060048201526024016102ee565b610284838383610440565b6001600160a01b0384166103955760405163e602df0560e01b8152600060048201526024016102ee565b6001600160a01b0383166103bf57604051634a1406b160e11b8152600060048201526024016102ee565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561030657826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161043291815260200190565b60405180910390a350505050565b6001600160a01b03831661046b57806002600082825461046091906106c9565b909155506104dd9050565b6001600160a01b038316600090815260208190526040902054818110156104be5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016102ee565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166104f957600280548290039055610518565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161055d91815260200190565b60405180910390a3505050565b600060208083528351808285015260005b818110156105975785810183015185820160400152820161057b565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146105cf57600080fd5b919050565b600080604083850312156105e757600080fd5b6105f0836105b8565b946020939093013593505050565b60008060006060848603121561061357600080fd5b61061c846105b8565b925061062a602085016105b8565b9150604084013590509250925092565b60006020828403121561064c57600080fd5b610655826105b8565b9392505050565b6000806040838503121561066f57600080fd5b610678836105b8565b9150610686602084016105b8565b90509250929050565b600181811c908216806106a357607f821691505b6020821081036106c357634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561023057634e487b7160e01b600052601160045260246000fdfea2646970667358221220b5d904ff268ef9cf4d17f43579b34609661d28e1f80b0b97869af04c5bd8a9d764736f6c63430008140033", + "devdoc": { + "errors": { + "ERC20InsufficientAllowance(address,uint256,uint256)": [ + { + "details": "Indicates a failure with the `spender`’s `allowance`. Used in transfers.", + "params": { + "allowance": "Amount of tokens a `spender` is allowed to operate with.", + "needed": "Minimum amount required to perform a transfer.", + "spender": "Address that may be allowed to operate on tokens without being their owner." + } + } + ], + "ERC20InsufficientBalance(address,uint256,uint256)": [ + { + "details": "Indicates an error related to the current `balance` of a `sender`. Used in transfers.", + "params": { + "balance": "Current balance for the interacting account.", + "needed": "Minimum amount required to perform a transfer.", + "sender": "Address whose tokens are being transferred." + } + } + ], + "ERC20InvalidApprover(address)": [ + { + "details": "Indicates a failure with the `approver` of a token to be approved. Used in approvals.", + "params": { + "approver": "Address initiating an approval operation." + } + } + ], + "ERC20InvalidReceiver(address)": [ + { + "details": "Indicates a failure with the token `receiver`. Used in transfers.", + "params": { + "receiver": "Address to which tokens are being transferred." + } + } + ], + "ERC20InvalidSender(address)": [ + { + "details": "Indicates a failure with the token `sender`. Used in transfers.", + "params": { + "sender": "Address whose tokens are being transferred." + } + } + ], + "ERC20InvalidSpender(address)": [ + { + "details": "Indicates a failure with the `spender` to be approved. Used in approvals.", + "params": { + "spender": "Address that may be allowed to operate on tokens without being their owner." + } + } + ] + }, + "events": { + "Approval(address,address,uint256)": { + "details": "Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance." + }, + "Transfer(address,address,uint256)": { + "details": "Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero." + } + }, + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "name()": { + "details": "Returns the name of the token." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 307, + "contract": "contracts/YourToken.sol:YourToken", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 313, + "contract": "contracts/YourToken.sol:YourToken", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 315, + "contract": "contracts/YourToken.sol:YourToken", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 317, + "contract": "contracts/YourToken.sol:YourToken", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 319, + "contract": "contracts/YourToken.sol:YourToken", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/sepolia/solcInputs/7b8c02112ef40e5ee2ab15c64b581f41.json b/packages/hardhat/deployments/sepolia/solcInputs/7b8c02112ef40e5ee2ab15c64b581f41.json new file mode 100644 index 0000000..dc19e78 --- /dev/null +++ b/packages/hardhat/deployments/sepolia/solcInputs/7b8c02112ef40e5ee2ab15c64b581f41.json @@ -0,0 +1,57 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n constructor(address initialOwner) {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n * ```\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "contracts/Vendor.sol": { + "content": "pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\n// SPDX-License-Identifier: MIT\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./YourToken.sol\";\n\ncontract Vendor is Ownable {\n /////////////////\n /// Errors //////\n /////////////////\n\n // Errors go here...\n error InvalidEthAmount();\n error InsufficientVendorTokenBalance(uint256 available, uint256 required);\n error EthTransferFailed(address to, uint256 amount);\n error InvalidTokenAmount();\n error InsufficientVendorEthBalance(uint256 available, uint256 required);\n\n //////////////////////\n /// State Variables //\n //////////////////////\n\n YourToken public immutable yourToken;\n uint256 public constant tokensPerEth = 100;\n\n ////////////////\n /// Events /////\n ////////////////\n\n // Events go here...\n event BuyTokens(address indexed buyer, uint256 amountOfETH, uint256 amountOfTokens);\n event SellTokens(address indexed seller, uint256 amountOfTokens, uint256 amountOfETH);\n\n ///////////////////\n /// Constructor ///\n ///////////////////\n\n constructor(address tokenAddress) Ownable(msg.sender) {\n yourToken = YourToken(tokenAddress);\n }\n\n ///////////////////\n /// Functions /////\n ///////////////////\n\n function buyTokens() external payable {\n if (msg.value == 0) revert InvalidEthAmount();\n uint256 receivedToken = msg.value * tokensPerEth;\n uint256 availableToken = yourToken.balanceOf(address(this));\n if (availableToken < receivedToken) revert InsufficientVendorTokenBalance(availableToken, receivedToken);\n yourToken.transfer(msg.sender, receivedToken);\n emit BuyTokens(msg.sender, msg.value, receivedToken);\n }\n\n function withdraw() public onlyOwner {\n address ownerAddr = payable(owner());\n (bool sent,) = ownerAddr.call{value: address(this).balance}(\"\"); \n if (!sent) revert EthTransferFailed(ownerAddr, address(this).balance);\n }\n\n function sellTokens(uint256 amount) public {\n if (amount == 0) revert InvalidTokenAmount();\n yourToken.transferFrom(msg.sender, address(this), amount);\n uint256 receivedEth = amount / tokensPerEth;\n uint256 contractEth = address(this).balance;\n if (contractEth < receivedEth) revert InsufficientVendorEthBalance(contractEth, receivedEth);\n (bool sent,) = payable(msg.sender).call{value: receivedEth}(\"\");\n if (!sent) revert EthTransferFailed(msg.sender, receivedEth);\n emit SellTokens(msg.sender, amount, receivedEth);\n }\n}\n" + }, + "contracts/YourToken.sol": { + "content": "pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\n// SPDX-License-Identifier: MIT\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n// learn more: https://docs.openzeppelin.com/contracts/5.x/erc20\n\ncontract YourToken is ERC20 {\n constructor() ERC20(\"Gold\", \"GLD\") {\n _mint(msg.sender, 1000 * (10 ** 18));\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/sepolia/solcInputs/b30a1ed2b1d3e3c06d1589ed16c9a78c.json b/packages/hardhat/deployments/sepolia/solcInputs/b30a1ed2b1d3e3c06d1589ed16c9a78c.json new file mode 100644 index 0000000..5e59c54 --- /dev/null +++ b/packages/hardhat/deployments/sepolia/solcInputs/b30a1ed2b1d3e3c06d1589ed16c9a78c.json @@ -0,0 +1,57 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n constructor(address initialOwner) {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n * ```\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "contracts/Vendor.sol": { + "content": "pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\n// SPDX-License-Identifier: MIT\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./YourToken.sol\";\n\ncontract Vendor is Ownable {\n /////////////////\n /// Errors //////\n /////////////////\n\n // Errors go here...\n error InvalidEthAmount();\n error InsufficientVendorTokenBalance(uint256 available, uint256 required);\n\n //////////////////////\n /// State Variables //\n //////////////////////\n\n YourToken public immutable yourToken;\n uint256 public constant tokensPerEth = 100;\n\n ////////////////\n /// Events /////\n ////////////////\n\n // Events go here...\n event BuyTokens(address indexed buyer, uint256 amountOfETH, uint256 amountOfTokens);\n\n ///////////////////\n /// Constructor ///\n ///////////////////\n\n constructor(address tokenAddress) Ownable(msg.sender) {\n yourToken = YourToken(tokenAddress);\n }\n\n ///////////////////\n /// Functions /////\n ///////////////////\n\n function buyTokens() external payable {\n if (msg.value == 0) revert InvalidEthAmount();\n uint256 receivedToken = msg.value / tokensPerEth;\n uint256 availableToken = address(this).balance;\n if (availableToken < receivedToken) revert InsufficientVendorTokenBalance(availableToken, receivedToken);\n yourToken.transfer(msg.sender, receivedToken);\n emit BuyTokens(msg.sender, msg.value, receivedToken);\n }\n\n function withdraw() public onlyOwner {}\n\n function sellTokens(uint256 amount) public {}\n}\n" + }, + "contracts/YourToken.sol": { + "content": "pragma solidity 0.8.20; //Do not change the solidity version as it negatively impacts submission grading\n// SPDX-License-Identifier: MIT\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n// learn more: https://docs.openzeppelin.com/contracts/5.x/erc20\n\ncontract YourToken is ERC20 {\n constructor() ERC20(\"Gold\", \"GLD\") {\n _mint(msg.sender, 1000 * (10 ** 18));\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/hardhat/hardhat.config.ts b/packages/hardhat/hardhat.config.ts index 782b36b..62651d7 100644 --- a/packages/hardhat/hardhat.config.ts +++ b/packages/hardhat/hardhat.config.ts @@ -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 diff --git a/packages/nextjs/app/events/page.tsx b/packages/nextjs/app/events/page.tsx index 288a020..6b80c0b 100644 --- a/packages/nextjs/app/events/page.tsx +++ b/packages/nextjs/app/events/page.tsx @@ -12,11 +12,11 @@ const Events: NextPage = () => { eventName: "BuyTokens", }); - // // SellTokens Events - // const { data: sellTokenEvents, isLoading: isSellEventsLoading } = useScaffoldEventHistory({ - // contractName: "Vendor", - // eventName: "SellTokens", - // }); + // SellTokens Events + const { data: sellTokenEvents, isLoading: isSellEventsLoading } = useScaffoldEventHistory({ + contractName: "Vendor", + eventName: "SellTokens", + }); return (
@@ -66,7 +66,7 @@ const Events: NextPage = () => {
{/* SellTokens Events */} - {/*
+
Sell Token Events
@@ -108,7 +108,7 @@ const Events: NextPage = () => {
)} -
*/} + ); }; diff --git a/packages/nextjs/app/token-vendor/page.tsx b/packages/nextjs/app/token-vendor/page.tsx index d8c3983..d17424b 100644 --- a/packages/nextjs/app/token-vendor/page.tsx +++ b/packages/nextjs/app/token-vendor/page.tsx @@ -33,18 +33,18 @@ const TokenVendor: NextPage = () => { const { writeContractAsync: writeVendorAsync } = useScaffoldWriteContract({ contractName: "Vendor" }); const { writeContractAsync: writeYourTokenAsync } = useScaffoldWriteContract({ contractName: "YourToken" }); - // const { data: vendorTokenBalance } = useScaffoldReadContract({ - // contractName: "YourToken", - // functionName: "balanceOf", - // args: [vendorContractData?.address], - // }); + const { data: vendorTokenBalance } = useScaffoldReadContract({ + contractName: "YourToken", + functionName: "balanceOf", + args: [vendorContractData?.address], + }); - // const { data: vendorEthBalance } = useWatchBalance({ address: vendorContractData?.address }); + const { data: vendorEthBalance } = useWatchBalance({ address: vendorContractData?.address }); - // const { data: tokensPerEth } = useScaffoldReadContract({ - // contractName: "Vendor", - // functionName: "tokensPerEth", - // }); + const { data: tokensPerEth } = useScaffoldReadContract({ + contractName: "Vendor", + functionName: "tokensPerEth", + }); return ( <> @@ -57,8 +57,7 @@ const TokenVendor: NextPage = () => { {yourTokenSymbol} - {/* Vendor Balances */} - {/*
+
Vendor token balance:{" "}
@@ -69,11 +68,10 @@ const TokenVendor: NextPage = () => {
Vendor eth balance: {Number(formatEther(vendorEthBalance?.value || 0n)).toFixed(4)} ETH -
*/} +
- {/* Buy Tokens */} - {/*
+
Buy tokens
{tokensPerEth?.toString() || 0} tokens per ETH
@@ -98,7 +96,7 @@ const TokenVendor: NextPage = () => { > Buy Tokens -
*/} +
{!!yourTokenBalance && (
@@ -132,7 +130,7 @@ const TokenVendor: NextPage = () => { )} {/* Sell Tokens */} - {/* {!!yourTokenBalance && ( + {!!yourTokenBalance && (
Sell tokens
{tokensPerEth?.toString() || 0} tokens per ETH
@@ -180,7 +178,7 @@ const TokenVendor: NextPage = () => {
- )} */} + )} ); diff --git a/packages/nextjs/contracts/deployedContracts.ts b/packages/nextjs/contracts/deployedContracts.ts index 008d4eb..dfe1622 100644 --- a/packages/nextjs/contracts/deployedContracts.ts +++ b/packages/nextjs/contracts/deployedContracts.ts @@ -4,6 +4,1185 @@ */ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract"; -const deployedContracts = {} as const; +const deployedContracts = { + 31337: { + Vendor: { + address: "0x59b670e9fA9D0A427751Af201D676719a970857b", + abi: [ + { + inputs: [ + { + internalType: "address", + name: "tokenAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "EthTransferFailed", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "available", + type: "uint256", + }, + { + internalType: "uint256", + name: "required", + type: "uint256", + }, + ], + name: "InsufficientVendorEthBalance", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "available", + type: "uint256", + }, + { + internalType: "uint256", + name: "required", + type: "uint256", + }, + ], + name: "InsufficientVendorTokenBalance", + type: "error", + }, + { + inputs: [], + name: "InvalidEthAmount", + type: "error", + }, + { + inputs: [], + name: "InvalidTokenAmount", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + ], + name: "OwnableInvalidOwner", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "OwnableUnauthorizedAccount", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "buyer", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfTokens", + type: "uint256", + }, + ], + name: "BuyTokens", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "seller", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfTokens", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + ], + name: "SellTokens", + type: "event", + }, + { + inputs: [], + name: "buyTokens", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "sellTokens", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "tokensPerEth", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "yourToken", + outputs: [ + { + internalType: "contract YourToken", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + ], + inheritedFunctions: { + owner: "@openzeppelin/contracts/access/Ownable.sol", + renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol", + transferOwnership: "@openzeppelin/contracts/access/Ownable.sol", + }, + deployedOnBlock: 36, + }, + YourToken: { + address: "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", + abi: [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "allowance", + type: "uint256", + }, + { + internalType: "uint256", + name: "needed", + type: "uint256", + }, + ], + name: "ERC20InsufficientAllowance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "uint256", + name: "balance", + type: "uint256", + }, + { + internalType: "uint256", + name: "needed", + type: "uint256", + }, + ], + name: "ERC20InsufficientBalance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "approver", + type: "address", + }, + ], + name: "ERC20InvalidApprover", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "receiver", + type: "address", + }, + ], + name: "ERC20InvalidReceiver", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + name: "ERC20InvalidSender", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "ERC20InvalidSpender", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + ], + inheritedFunctions: { + allowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + approve: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + balanceOf: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + decimals: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + name: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + symbol: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + totalSupply: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transfer: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transferFrom: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + }, + deployedOnBlock: 34, + }, + }, + 11155111: { + Vendor: { + address: "0x7CfE3306c5172f5245036f29A9c9f4aCe2b0DF73", + abi: [ + { + inputs: [ + { + internalType: "address", + name: "tokenAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "EthTransferFailed", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "available", + type: "uint256", + }, + { + internalType: "uint256", + name: "required", + type: "uint256", + }, + ], + name: "InsufficientVendorEthBalance", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "available", + type: "uint256", + }, + { + internalType: "uint256", + name: "required", + type: "uint256", + }, + ], + name: "InsufficientVendorTokenBalance", + type: "error", + }, + { + inputs: [], + name: "InvalidEthAmount", + type: "error", + }, + { + inputs: [], + name: "InvalidTokenAmount", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + ], + name: "OwnableInvalidOwner", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "OwnableUnauthorizedAccount", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "buyer", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfTokens", + type: "uint256", + }, + ], + name: "BuyTokens", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "seller", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfTokens", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + ], + name: "SellTokens", + type: "event", + }, + { + inputs: [], + name: "buyTokens", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "sellTokens", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "tokensPerEth", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "yourToken", + outputs: [ + { + internalType: "contract YourToken", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + ], + inheritedFunctions: { + owner: "@openzeppelin/contracts/access/Ownable.sol", + renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol", + transferOwnership: "@openzeppelin/contracts/access/Ownable.sol", + }, + deployedOnBlock: 10049176, + }, + YourToken: { + address: "0x981B997C64Aef1316392167c4cC5879e4A5cf7f6", + abi: [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "allowance", + type: "uint256", + }, + { + internalType: "uint256", + name: "needed", + type: "uint256", + }, + ], + name: "ERC20InsufficientAllowance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "uint256", + name: "balance", + type: "uint256", + }, + { + internalType: "uint256", + name: "needed", + type: "uint256", + }, + ], + name: "ERC20InsufficientBalance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "approver", + type: "address", + }, + ], + name: "ERC20InvalidApprover", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "receiver", + type: "address", + }, + ], + name: "ERC20InvalidReceiver", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + name: "ERC20InvalidSender", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "ERC20InvalidSpender", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + ], + inheritedFunctions: { + allowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + approve: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + balanceOf: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + decimals: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + name: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + symbol: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + totalSupply: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transfer: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transferFrom: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + }, + deployedOnBlock: 10049162, + }, + }, +} as const; export default deployedContracts satisfies GenericContractsDeclaration; diff --git a/packages/nextjs/next-env.d.ts b/packages/nextjs/next-env.d.ts index 830fb59..1b3be08 100644 --- a/packages/nextjs/next-env.d.ts +++ b/packages/nextjs/next-env.d.ts @@ -1,6 +1,5 @@ /// /// -/// // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index 171a50d..3cf5576 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -15,7 +15,7 @@ export const DEFAULT_ALCHEMY_API_KEY = "cR4WnXePioePZ5fFrnSiR"; const scaffoldConfig = { // The networks on which your DApp is live - targetNetworks: [chains.hardhat], + targetNetworks: [chains.sepolia], //[chains.hardhat], // The interval at which your front-end polls the RPC servers for new data (it has no effect if you only target the local network (default is 4000)) pollingInterval: 30000, // This is ours Alchemy's default API key. @@ -34,7 +34,7 @@ const scaffoldConfig = { // It's recommended to store it in an env variable: // .env.local for local testing, and in the Vercel/system env config for live apps. walletConnectProjectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID || "3a8170812b534d0ff9d794f19a901d64", - onlyLocalBurnerWallet: true, + onlyLocalBurnerWallet: false, } as const satisfies ScaffoldConfig; export default scaffoldConfig;