diff --git a/src/Geld.sol b/src/Geld.sol new file mode 100644 index 0000000..6cefff1 --- /dev/null +++ b/src/Geld.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract Geld is ERC20, Ownable { + + struct Raider { + uint16 level; + } + + struct Army { + Raider moloch_denier; + Raider apprentice; + Raider annointed; + Raider champion; + } + + struct Player { + uint256 total_minted; + uint256 created_at; + uint256 last_minted_at; + } + + uint8 constant DECIMALS = 4; + uint256 public constant BUY_IN_AMOUNT = 0.0005 ether; + uint256 public constant GELD_PER_PURCHASE = 50 * 10 ** DECIMALS; + uint256 public constant MINT_TIME = 15; + uint256 public total_minted = 0; + + mapping(address => Player) private players; + mapping(address => Army) private armies; + + // Modifier for functions that should only be available to registered players + modifier onlyPlayer() { + require(players[msg.sender].created_at != 0, "Not an initiated player"); + _; + } + + constructor() ERC20("Geld", "GELD") Ownable(msg.sender) {} + + // This effectively registers the user + receive() external payable { + require(players[msg.sender].created_at != 0, "Whoops, player already exists :)"); + require(msg.value == BUY_IN_AMOUNT, "Incorrect buy in amount"); + _mint(msg.sender, GELD_PER_PURCHASE); + players[msg.sender] = Player({ + total_minted: GELD_PER_PURCHASE, + created_at: block.timestamp, + last_minted_at: 0 + }); + armies[msg.sender] = Army({ + moloch_denier: Raider({ level: 0 }), + apprentice: 0, + annointed: 0, + champion: 0 + }) + + total_minted += GELD_PER_PURCHASE; + } + + // Override for default number of decimals + function decimals() public view virtual override returns (uint8) { + return DECIMALS; + } + + // Allows the owner to withdraw + function withdraw() external onlyOwner { + payable(owner()).transfer(address(this).balance); + } + + // Manual minting for itchy fingers + function manualMint() external onlyPlayer { + require(block.timestamp >= players[msg.sender].last_minted_at + MINT_TIME, "Tried minting too soon"); + + // TODO: Make real calculation based on army + _mint(msg.sender, 50); + + players[msg.sender].last_minted_at = block.timestamp; + } + + // Function to get Player struct + function getPlayer() public view onlyPlayer returns (Player memory) { + return players[msg.sender]; + } + + // Function to get Army struct + function getArmy() public view onlyPlayer returns (Army memory) { + return armies[msg.sender]; + } +} diff --git a/test/Geld.t.sol b/test/Geld.t.sol new file mode 100644 index 0000000..5e78870 --- /dev/null +++ b/test/Geld.t.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import { Test, console } from "forge-std/Test.sol"; +import { Geld } from "../src/Geld.sol"; + +contract Gels is Test { + Geld public geld; + + function setUp() public { + geld = new Geld(); + } + + + +}