-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlayerAuction.sol
More file actions
142 lines (114 loc) · 5.09 KB
/
PlayerAuction.sol
File metadata and controls
142 lines (114 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
interface IPlayerNFT {
function ownerOf(uint256 tokenId) external view returns (address);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
}
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
contract PlayerAuction{
struct AuctionData {
uint startPrice;
uint maxPrice;
uint endAt;
bool finished;
bool started;
address winner;
uint256 nftID;
}
AuctionData public auctionData;
address public manager;
mapping(address=>uint) public balances;
IERC20 public gameToken;
IPlayerNFT public nft;
event NewEnter(address indexed user, uint amount);
event AuctionFinished(address indexed winner, uint256 indexed nftID, uint256 amount);
event Withdraw(address indexed user, uint256 indexed nftID, uint256 amount);
// Additional events for The Graph indexing
event AuctionStarted(uint256 indexed nftID, address indexed manager, uint256 startPrice, uint256 endAt);
event BidPlaced(address indexed bidder, uint256 indexed nftID, uint256 amount, uint256 totalBid);
constructor (address NTFaddres,address _gameToken,uint _nftID , uint _startPrice,uint _endAt,address msgSender){
nft=IPlayerNFT(NTFaddres);
gameToken=IERC20(_gameToken);
manager = msgSender;
auctionData.nftID=_nftID;
auctionData.startPrice = _startPrice;
auctionData.endAt = _endAt;
auctionData.maxPrice=_startPrice;
require(nft.ownerOf(_nftID) == msgSender, "You must own the NFT");
}
modifier onlyOwner() {
require(msg.sender == manager, "You aren't the Owner");
_;
}
// start after approve contract in Frontend
function start() external onlyOwner{
require(!auctionData.started, "Auction already started");
nft.safeTransferFrom(manager, address(this),auctionData.nftID);
auctionData.started=true;
emit AuctionStarted(auctionData.nftID, manager, auctionData.startPrice, auctionData.endAt);
}
function bid(uint amount ) external {
require(auctionData.started , "Auction not started yet");
require(block.timestamp < auctionData.endAt, "Auction has ended");
// handling If the owner ends the auction before [auctionData.endAt]
require(!auctionData.finished, "Auction already finished");
uint256 newTotal = balances[msg.sender] + amount;
require(newTotal > auctionData.maxPrice);
// approve contract first in Frontend
gameToken.transferFrom(msg.sender, address(this), amount);
balances[msg.sender]=newTotal;
auctionData.maxPrice=newTotal;
auctionData.winner=msg.sender;
emit NewEnter(msg.sender, amount);
emit BidPlaced(msg.sender, auctionData.nftID, amount, newTotal);
}
function end() external {
require(auctionData.started , "Auction not started yet");
require(
(block.timestamp >= auctionData.endAt) || (msg.sender == manager),
"Auction is not finished yet"
);
require(!auctionData.finished, "Auction is already finished");
// If auction ended naturally (time expired), anyone can call end()
// If manager wants to end early, only manager can call
if (block.timestamp < auctionData.endAt) {
require(msg.sender == manager, "Only manager can end auction early");
}
auctionData.finished = true;
if(auctionData.winner!=address(0)){
nft.safeTransferFrom(address(this), auctionData.winner, auctionData.nftID);
gameToken.transfer(manager, auctionData.maxPrice);
emit AuctionFinished(auctionData.winner, auctionData.nftID, auctionData.maxPrice);
}
else {
nft.safeTransferFrom(address(this), manager, auctionData.nftID);
}
}
function withdraw()external {
// user can withdraw his money if he is not the winner
// even if the auction is in progress
require(auctionData.started , "Auction not started yet");
require(balances[msg.sender]>0);
require(msg.sender != auctionData.winner);
uint amount = balances[msg.sender];
balances[msg.sender]=0;
require(gameToken.transfer(msg.sender, amount), "Transfer failed");
emit Withdraw(msg.sender, auctionData.nftID, amount);
}
function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
return this.onERC721Received.selector;
}
// +==================+
// | getter functions |
// +==================+
function getAuctionInfo() external view returns (AuctionData memory) {
return auctionData;
}
function getUserBalance(address user) external view returns (uint) {
return balances[user];
}
}