Allows withdrawal of DAO tokens back to owner() account
This commit is contained in:
parent
5b0d24ccba
commit
7b9661bda7
13
README.md
13
README.md
@ -5,9 +5,10 @@ Idle game & shitcoin advanture dedicated to cohort VII of Raid Guild.
|
|||||||
## Set up for local DEV
|
## Set up for local DEV
|
||||||
|
|
||||||
### 1. Run `anvil` to setup local RPC as a fork of base mainnet
|
### 1. Run `anvil` to setup local RPC as a fork of base mainnet
|
||||||
`anvil --rpc-url <you'r base mainnet rpc url>`
|
|
||||||
|
|
||||||
you can get a free rpc url by registering with https://alchemy.com and creating and app
|
`anvil --block-time 5 --rpc-url <you'r base mainnet rpc url>`
|
||||||
|
|
||||||
|
You can get a free rpc url by registering with https://alchemy.com and creating and app
|
||||||
|
|
||||||
### 2. Deploy contract
|
### 2. Deploy contract
|
||||||
|
|
||||||
@ -21,10 +22,6 @@ Move to `app` dir, install deps via `npm install` and run `npm run dev` to start
|
|||||||
|
|
||||||
#### 3. 2. Change `app/contract_address.ts` to match your program address if needed
|
#### 3. 2. Change `app/contract_address.ts` to match your program address if needed
|
||||||
|
|
||||||
### 4. Local development requires mining blocks by hand
|
### 4. Fork tests
|
||||||
|
|
||||||
Call `cast rpc anvil_mine` to mine next block, otherwise it wont ever progress and time "stands still" as far as the game is concerned
|
forge test --rpc-url <your base mainnet rpc url>
|
||||||
|
|
||||||
|
|
||||||
### 5. Fork tests
|
|
||||||
forge test --rpc-url <you'r base mainnet rpc url>
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const contractAddress = "0xbd06B0878888bf4c6895704fa603a5ADf7e65c66";
|
const contractAddress = "0xb2fc8F28aD37290245241C6cb0E411c9fff6A1d7";
|
||||||
|
|
||||||
|
|
||||||
export default contractAddress
|
export default contractAddress
|
||||||
|
|||||||
68
broadcast/RaidGeld.s.sol/8453/run-1729970220.json
Normal file
68
broadcast/RaidGeld.s.sol/8453/run-1729970220.json
Normal file
File diff suppressed because one or more lines are too long
68
broadcast/RaidGeld.s.sol/8453/run-latest.json
Normal file
68
broadcast/RaidGeld.s.sol/8453/run-latest.json
Normal file
File diff suppressed because one or more lines are too long
@ -5,4 +5,4 @@ contract Constants {
|
|||||||
//base addresses
|
//base addresses
|
||||||
address public constant DAO_TOKEN = 0x11dC980faf34A1D082Ae8A6a883db3A950a3c6E8;
|
address public constant DAO_TOKEN = 0x11dC980faf34A1D082Ae8A6a883db3A950a3c6E8;
|
||||||
address public constant POOL = 0x27004f6d0c1bB7979367D32Ba9d6DF6d61A18926;
|
address public constant POOL = 0x27004f6d0c1bB7979367D32Ba9d6DF6d61A18926;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import "@openzeppelin/contracts/access/Ownable.sol";
|
|||||||
import {RaidGeldUtils} from "../src/RaidGeldUtils.sol";
|
import {RaidGeldUtils} from "../src/RaidGeldUtils.sol";
|
||||||
import {Army, Player, Raider} from "../src/RaidGeldStructs.sol";
|
import {Army, Player, Raider} from "../src/RaidGeldStructs.sol";
|
||||||
|
|
||||||
|
|
||||||
contract RaidGeld is ERC20, Ownable {
|
contract RaidGeld is ERC20, Ownable {
|
||||||
uint256 public constant MANTISSA = 1e4;
|
uint256 public constant MANTISSA = 1e4;
|
||||||
|
|
||||||
@ -42,7 +41,10 @@ contract RaidGeld is ERC20, Ownable {
|
|||||||
} else {
|
} else {
|
||||||
//@notice this is not safe for arbitrary tokens, which may not follow the interface eg. USDT
|
//@notice this is not safe for arbitrary tokens, which may not follow the interface eg. USDT
|
||||||
//@notice but should be fine for the DAO token
|
//@notice but should be fine for the DAO token
|
||||||
require(daoToken.transferFrom(msg.sender, address(this), BUY_IN_DAO_TOKEN_AMOUNT), "Failed to transfer DAO tokens");
|
require(
|
||||||
|
daoToken.transferFrom(msg.sender, address(this), BUY_IN_DAO_TOKEN_AMOUNT),
|
||||||
|
"Failed to transfer DAO tokens"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mint some starting tokens to the player
|
// Mint some starting tokens to the player
|
||||||
@ -70,6 +72,13 @@ contract RaidGeld is ERC20, Ownable {
|
|||||||
payable(owner()).transfer(address(this).balance);
|
payable(owner()).transfer(address(this).balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allows the owner to withdraw DAO tokens
|
||||||
|
function withdraw_dao() external onlyOwner {
|
||||||
|
uint256 amount = daoToken.balanceOf(address(this));
|
||||||
|
daoToken.approve(address(this), amount);
|
||||||
|
daoToken.transferFrom(address(this), owner(), amount);
|
||||||
|
}
|
||||||
|
|
||||||
// Manual minting for itchy fingers
|
// Manual minting for itchy fingers
|
||||||
function raid() external onlyPlayer {
|
function raid() external onlyPlayer {
|
||||||
require(block.timestamp >= players[msg.sender].last_raided_at + RAID_WAIT, "Tried minting too soon");
|
require(block.timestamp >= players[msg.sender].last_raided_at + RAID_WAIT, "Tried minting too soon");
|
||||||
|
|||||||
@ -2,14 +2,13 @@
|
|||||||
pragma solidity ^0.8.13;
|
pragma solidity ^0.8.13;
|
||||||
|
|
||||||
import {Test, console} from "forge-std/Test.sol";
|
import {Test, console} from "forge-std/Test.sol";
|
||||||
import {stdStorage, StdStorage} from "forge-std/Test.sol";
|
import {stdStorage, StdStorage} from "forge-std/Test.sol";
|
||||||
|
|
||||||
import {RaidGeld, Army, Player} from "../src/RaidGeld.sol";
|
import {RaidGeld, Army, Player} from "../src/RaidGeld.sol";
|
||||||
import "../src/RaidGeldUtils.sol";
|
import "../src/RaidGeldUtils.sol";
|
||||||
import {Constants} from "../src/Constants.sol";
|
import {Constants} from "../src/Constants.sol";
|
||||||
|
|
||||||
contract raid_geldTest is Test, Constants {
|
contract raid_geldTest is Test, Constants {
|
||||||
|
|
||||||
using stdStorage for StdStorage;
|
using stdStorage for StdStorage;
|
||||||
|
|
||||||
RaidGeld public raid_geld;
|
RaidGeld public raid_geld;
|
||||||
@ -25,25 +24,21 @@ contract raid_geldTest is Test, Constants {
|
|||||||
vm.prank(owner);
|
vm.prank(owner);
|
||||||
raid_geld = new RaidGeld(DAO_TOKEN, POOL);
|
raid_geld = new RaidGeld(DAO_TOKEN, POOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fundAccount(address _acc) private {
|
function fundAccount(address _acc) private {
|
||||||
vm.deal(_acc, 10 ether);
|
vm.deal(_acc, 10 ether);
|
||||||
stdstore
|
stdstore.target(DAO_TOKEN).sig("balanceOf(address)").with_key(_acc).checked_write(100 ether);
|
||||||
.target(DAO_TOKEN)
|
|
||||||
.sig("balanceOf(address)")
|
|
||||||
.with_key(_acc)
|
|
||||||
.checked_write(100 ether);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerPlayer() private {
|
function registerPlayer() private {
|
||||||
raid_geld.register{value: raid_geld.BUY_IN_AMOUNT()}();
|
raid_geld.register{value: raid_geld.BUY_IN_AMOUNT()}();
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerPlayerWithDaoToken() private {
|
function registerPlayerWithDaoToken() private {
|
||||||
raid_geld.daoToken().approve(address(raid_geld), raid_geld.BUY_IN_DAO_TOKEN_AMOUNT());
|
raid_geld.daoToken().approve(address(raid_geld), raid_geld.BUY_IN_DAO_TOKEN_AMOUNT());
|
||||||
raid_geld.register();
|
raid_geld.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function test_00_no_fallback() public {
|
function test_00_no_fallback() public {
|
||||||
vm.expectRevert();
|
vm.expectRevert();
|
||||||
// Send Ether with some data to trigger fallback
|
// Send Ether with some data to trigger fallback
|
||||||
@ -92,11 +87,13 @@ contract raid_geldTest is Test, Constants {
|
|||||||
// Send registration fee ETH to the contract
|
// Send registration fee ETH to the contract
|
||||||
registerPlayerWithDaoToken();
|
registerPlayerWithDaoToken();
|
||||||
|
|
||||||
// Check that initialraid_geld.is received by the player
|
// Check that initial raid_geld is received by the player
|
||||||
assertEq(raid_geld.balanceOf(player1), raid_geld.INITIAL_GELD());
|
assertEq(raid_geld.balanceOf(player1), raid_geld.INITIAL_GELD());
|
||||||
|
|
||||||
// Verify the contract dao token balance is updated
|
// Verify the contract dao token balance is updated
|
||||||
assertEq(raid_geld.daoToken().balanceOf(address(raid_geld)), initialBalance + raid_geld.BUY_IN_DAO_TOKEN_AMOUNT());
|
assertEq(
|
||||||
|
raid_geld.daoToken().balanceOf(address(raid_geld)), initialBalance + raid_geld.BUY_IN_DAO_TOKEN_AMOUNT()
|
||||||
|
);
|
||||||
|
|
||||||
// Verify player is set initially
|
// Verify player is set initially
|
||||||
Player memory player = raid_geld.getPlayer(player1);
|
Player memory player = raid_geld.getPlayer(player1);
|
||||||
@ -112,8 +109,7 @@ contract raid_geldTest is Test, Constants {
|
|||||||
assertEq(army.champion.level, 0);
|
assertEq(army.champion.level, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_03_01_ETH_funds_can_be_withdrawn() public {
|
||||||
function test_03_funds_can_be_withdrawn() public {
|
|
||||||
uint256 initialBalance = owner.balance;
|
uint256 initialBalance = owner.balance;
|
||||||
|
|
||||||
// Switch to Player 1 and register it
|
// Switch to Player 1 and register it
|
||||||
@ -132,6 +128,25 @@ contract raid_geldTest is Test, Constants {
|
|||||||
assertEq(newBalance, initialBalance + raid_geld.BUY_IN_AMOUNT());
|
assertEq(newBalance, initialBalance + raid_geld.BUY_IN_AMOUNT());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_03_02_RGCVII_funds_can_be_withdrawn() public {
|
||||||
|
uint256 initialBalance = raid_geld.daoToken().balanceOf(address(raid_geld));
|
||||||
|
|
||||||
|
// Switch to Player 1 and register it
|
||||||
|
vm.startPrank(player1);
|
||||||
|
registerPlayerWithDaoToken();
|
||||||
|
|
||||||
|
// Switch back to owner and withdraw funds
|
||||||
|
vm.startPrank(owner);
|
||||||
|
raid_geld.withdraw_dao();
|
||||||
|
uint256 newBalance = raid_geld.daoToken().balanceOf(address(owner));
|
||||||
|
uint256 newContractBalance = raid_geld.daoToken().balanceOf(address(raid_geld));
|
||||||
|
|
||||||
|
// contract balance should be empty
|
||||||
|
assertEq(newContractBalance, 0);
|
||||||
|
// owner should have the extra funds
|
||||||
|
assertGt(newBalance, initialBalance);
|
||||||
|
}
|
||||||
|
|
||||||
function test_04_only_owner_can_withdraw() public {
|
function test_04_only_owner_can_withdraw() public {
|
||||||
// Register player 1
|
// Register player 1
|
||||||
vm.startPrank(player1);
|
vm.startPrank(player1);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user