Skip to content

Commit 874730a

Browse files
authored
Added SimpleTreasury contract (#21)
* Added SimpleTreasury contract * Typo * Added deployed contract address
1 parent d782565 commit 874730a

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Repository holding the contracts made by Gnosis Labs team.
1010
| OmenAgentResultMapping | Maps prediction results to markets on Omen 2.0 | [0xbe1F6944496923683ca849fc0cC93fD10523cB83](https://gnosisscan.io/address/0x260E1077dEA98e738324A6cEfB0EE9A272eD471a#code) | [omen-agentresultmapping](https://thegraph.com/studio/subgraph/omen-agentresultmapping/) |
1111
| Agent NFT | Agent NFTs that control mechs for NFT game | [0x0D7C0Bd4169D090038c6F41CFd066958fe7619D0](https://gnosisscan.io/address/0x0D7C0Bd4169D090038c6F41CFd066958fe7619D0#code) | |
1212
| Agent communication contract | Simple contract storing message queue for each agent | [0xd422e0059ed819e8d792af936da206878188e34f](https://gnosisscan.io/address/0xd422e0059ed819e8d792af936da206878188e34f#code) | |
13+
| Simple Treasury contract | Contract for storing the NFT agent game treasury | [0x624ad0db52e6b18afb4d36b8e79d0c2a74f3fc8a](https://gnosisscan.io/address/0x624ad0db52e6b18afb4d36b8e79d0c2a74f3fc8a#code) | |
1314

1415
## Set up contracts development
1516

src/NFT/SimpleTreasury.sol

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
5+
import "@openzeppelin/contracts/access/Ownable.sol";
6+
7+
contract SimpleTreasury is Ownable {
8+
IERC721 public nftContract;
9+
uint256 public requiredNFTBalance = 3;
10+
11+
function setRequiredNFTBalance(uint256 _newBalance) external onlyOwner {
12+
requiredNFTBalance = _newBalance;
13+
}
14+
15+
event WithdrawnByNFTHolder(address indexed holder, uint256 amount);
16+
17+
constructor(address _nftContract) Ownable(msg.sender) {
18+
require(_nftContract != address(0), "Invalid NFT contract address");
19+
nftContract = IERC721(_nftContract);
20+
}
21+
22+
// Function to receive xDAI
23+
receive() external payable {}
24+
25+
// Withdraw function that checks NFT balance
26+
function withdraw() external {
27+
uint256 nftBalance = nftContract.balanceOf(msg.sender);
28+
require(nftBalance >= requiredNFTBalance, "Insufficient NFT balance");
29+
30+
uint256 balance = address(this).balance;
31+
require(balance > 0, "No funds to withdraw");
32+
33+
(bool success,) = payable(msg.sender).call{value: balance}("");
34+
require(success, "Transfer failed");
35+
36+
emit WithdrawnByNFTHolder(msg.sender, balance);
37+
}
38+
}

test/SimpleTreasury.t.sol

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import "forge-std/Test.sol";
5+
import "../src/NFT/SimpleTreasury.sol";
6+
import "./mocks/MockNFT.sol";
7+
8+
contract SimpleTreasuryTest is Test {
9+
SimpleTreasury public treasury;
10+
MockNFT public nft;
11+
12+
address public owner;
13+
address public user;
14+
uint256 public constant INITIAL_BALANCE = 10 ether;
15+
16+
function setUp() public {
17+
owner = makeAddr("owner");
18+
user = makeAddr("user");
19+
20+
vm.startPrank(owner);
21+
nft = new MockNFT();
22+
treasury = new SimpleTreasury(address(nft));
23+
vm.stopPrank();
24+
25+
// Fund treasury
26+
vm.deal(address(treasury), INITIAL_BALANCE);
27+
}
28+
29+
function test_WithdrawWithSufficientNFTs() public {
30+
// Mint 3 NFTs to user
31+
vm.startPrank(owner);
32+
for (uint256 i = 0; i < treasury.requiredNFTBalance(); ++i) {
33+
nft.mint(user);
34+
}
35+
vm.stopPrank();
36+
37+
// Try to withdraw as user
38+
vm.prank(user);
39+
uint256 userBalanceBefore = user.balance;
40+
treasury.withdraw();
41+
42+
assertEq(user.balance - userBalanceBefore, INITIAL_BALANCE, "User should receive all treasury balance");
43+
assertEq(address(treasury).balance, 0, "Treasury should be empty");
44+
}
45+
46+
function test_WithdrawWithInsufficientNFTs() public {
47+
// Mint only 2 NFTs to user
48+
vm.startPrank(owner);
49+
nft.mint(user);
50+
nft.mint(user);
51+
vm.stopPrank();
52+
53+
// Try to withdraw as user
54+
vm.prank(user);
55+
vm.expectRevert("Insufficient NFT balance");
56+
treasury.withdraw();
57+
}
58+
59+
function test_SetRequiredNFTBalance() public {
60+
uint256 newRequiredBalance = 5;
61+
62+
vm.prank(owner);
63+
treasury.setRequiredNFTBalance(newRequiredBalance);
64+
65+
assertEq(treasury.requiredNFTBalance(), newRequiredBalance, "Required NFT balance should be updated");
66+
}
67+
68+
function test_SetRequiredNFTBalanceNotOwner() public {
69+
vm.prank(user);
70+
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(user)));
71+
treasury.setRequiredNFTBalance(5);
72+
}
73+
74+
function test_ReceiveEther() public {
75+
uint256 amount = 1 ether;
76+
vm.deal(user, amount);
77+
78+
vm.prank(user);
79+
(bool success,) = address(treasury).call{value: amount}("");
80+
81+
assertTrue(success, "Should accept ether");
82+
assertEq(address(treasury).balance, INITIAL_BALANCE + amount, "Treasury balance should increase");
83+
}
84+
}

test/mocks/MockNFT.sol

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5+
6+
contract MockNFT is ERC721 {
7+
uint256 private _tokenIdCounter;
8+
9+
constructor() ERC721("MockNFT", "MNFT") {}
10+
11+
function mint(address to) external returns (uint256) {
12+
uint256 tokenId = _tokenIdCounter++;
13+
_mint(to, tokenId);
14+
return tokenId;
15+
}
16+
}

0 commit comments

Comments
 (0)