From a16aaf3bd01e837937e51c0d5cfbcf6cf5375098 Mon Sep 17 00:00:00 2001 From: Isaac Almanza Date: Fri, 20 Oct 2023 14:54:18 -0500 Subject: [PATCH] feat: add dirty money and dealer exercise and test --- src/DirtyMoney/Dealer.sol | 42 +++++++++++++++++++++++++++++++++++ src/DirtyMoney/DirtyMoney.sol | 36 ++++++++++++++++++++++++++++++ test/Dealer.t.sol | 37 ++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/DirtyMoney/Dealer.sol create mode 100644 src/DirtyMoney/DirtyMoney.sol create mode 100644 test/Dealer.t.sol diff --git a/src/DirtyMoney/Dealer.sol b/src/DirtyMoney/Dealer.sol new file mode 100644 index 0000000..d3e0d24 --- /dev/null +++ b/src/DirtyMoney/Dealer.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "./DirtyMoney.sol"; + +contract Dealer { + address[] public hackers; + mapping(address => DirtyMoney) public userToDineroSucioContract; + + modifier notContractCaller() { + if (msg.sender.code.length != 0) revert("Only EOA can call"); + _; + } + + event NewHacker(address indexed _newHacker); + + function getNewInstance() public notContractCaller { + address sender = msg.sender; + userToDineroSucioContract[sender] = new DirtyMoney(sender); + } + + function submitInstance() public { + address sender = msg.sender; + DirtyMoney userInstance = userToDineroSucioContract[sender]; + uint256 userBalance = userInstance.balanceOf(sender); + + if (isWinner(sender)) revert("You already won"); + if (userBalance != 0) revert("You haven't got them yet"); + + hackers.push(sender); + emit NewHacker(sender); + } + + function isWinner(address _hacker) public view returns (bool) { + return getWinner() == _hacker; + } + + function getWinner() public view returns (address) { + if (hackers.length == 0) return address(0); + return hackers[0]; + } +} \ No newline at end of file diff --git a/src/DirtyMoney/DirtyMoney.sol b/src/DirtyMoney/DirtyMoney.sol new file mode 100644 index 0000000..ec6c81d --- /dev/null +++ b/src/DirtyMoney/DirtyMoney.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract DirtyMoney is ERC20 { + uint256 public timeLock = block.timestamp + 10 * 365 days; + uint256 public INITIAL_SUPPLY; + address public player; + + constructor(address _player) ERC20("DirtyMoney", "XXX") { + player = _player; + INITIAL_SUPPLY = 10000 * (10**uint256(decimals())); + _mint(player, INITIAL_SUPPLY); + emit Transfer(address(0), player, INITIAL_SUPPLY); + } + + function transfer(address _to, uint256 _value) + public + override + lockTokens + returns (bool) + { + super.transfer(_to, _value); + return true; + } + + modifier lockTokens() { + if (msg.sender == player) { + require(block.timestamp > timeLock); + _; + } else { + _; + } + } +} \ No newline at end of file diff --git a/test/Dealer.t.sol b/test/Dealer.t.sol new file mode 100644 index 0000000..b2b5229 --- /dev/null +++ b/test/Dealer.t.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "forge-std/console.sol"; +import "forge-std/Test.sol"; + +import {Dealer} from "../src/DirtyMoney/Dealer.sol"; +import {DirtyMoney} from "../src/DirtyMoney/DirtyMoney.sol"; + +contract DealerTest is Test { + Dealer dealer; + DirtyMoney money; + + address bob = address(0x1); + address mary = address(0x22222222); + + function setUp() public { + vm.startPrank(bob); + dealer = new Dealer(); + vm.stopPrank(); + } + + function testSubmit() public { + vm.startPrank(bob); + dealer.getNewInstance(); + money = dealer.userToDineroSucioContract(bob); + uint256 balance = money.balanceOf(bob); + + money.approve(bob, balance); + money.transferFrom(bob, mary, balance); + dealer.submitInstance(); + + assertEq(money.balanceOf(bob), 0); + assertEq(money.balanceOf(mary), balance); + vm.stopPrank(); + } +}