Skip to content

Commit

Permalink
Dutch auction
Browse files Browse the repository at this point in the history
  • Loading branch information
antico5 committed Jan 6, 2022
1 parent b768ac9 commit fcd4de4
Show file tree
Hide file tree
Showing 11 changed files with 45,113 additions and 0 deletions.
2 changes: 2 additions & 0 deletions dutch_auction/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALCHEMY_API_KEY=
ROPSTEN_PRIVATE_KEY=
8 changes: 8 additions & 0 deletions dutch_auction/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
.env

#Hardhat files
cache
artifacts
dist
typechain
22 changes: 22 additions & 0 deletions dutch_auction/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"explicitTypes": "always",
"semi": true
}
},
{
"files": "*.ts",
"options": {
"printWidth": 120
}
}
]
}
101 changes: 101 additions & 0 deletions dutch_auction/contracts/DutchAuction.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract DutchAuction is Ownable {
IERC721 public immutable nft;
uint256 public immutable tokenId;

uint256 public immutable startPrice;
uint256 public immutable endPrice;

uint256 public immutable startTime;
uint256 public immutable endTime;

address public buyer; // address of buyer
uint256 public saleMoney; // price at which the nft sold
uint256 public buyersChange; // in case buyer sends more money than actual price

modifier onlyBuyer() {
require(msg.sender == buyer, "sender is not buyer");
_;
}

modifier ongoingSale() {
require(block.timestamp >= startTime, "sale didnt start yet");
require(block.timestamp <= endTime, "sale already ended");
_;
}

constructor(
address _nft,
uint256 _tokenId,
uint256 _startPrice,
uint256 _endPrice,
uint256 _startTime,
uint256 _endTime
) {
require(_nft != address(0), "nft zero address");
require(_startPrice > 0, "start price must be positive");
require(_endPrice > 0, "end price must be positive");
require(_startPrice > _endPrice, "start price must be > end price");
require(_startTime >= block.timestamp, "must start in the future");
require(_endTime > _startTime, "end time must be > start time");

nft = IERC721(_nft);
tokenId = _tokenId;
startPrice = _startPrice;
endPrice = _endPrice;
startTime = _startTime;
endTime = _endTime;
}

function buy() external payable ongoingSale {
require(buyer == address(0), "already sold");

require(msg.value >= currentPrice(), "not enough ether");

saleMoney = currentPrice();
buyersChange = msg.value - saleMoney;
buyer = msg.sender;

nft.transferFrom(address(this), msg.sender, tokenId);
}

function withdrawPayment() external onlyOwner {
require(buyer != address(0), "token not sold yet");
require(saleMoney > 0, "already withdrew");

uint256 _saleMoney = saleMoney;
saleMoney = 0;
payable(owner()).transfer(_saleMoney);
}

function retrieveUnsoldToken() external onlyOwner {
require(buyer == address(0), "token was sold");
require(block.timestamp > endTime, "sale still in progress");
require(nft.ownerOf(tokenId) == address(this), "contract doesnt have the token anymore");

nft.transferFrom(address(this), owner(), tokenId);
}

function withdrawChange() external onlyBuyer {
require(buyersChange > 0, "nothing to withdraw");

uint256 _buyersChange = buyersChange;
buyersChange = 0;

payable(msg.sender).transfer(_buyersChange);
}

function currentPrice() public view ongoingSale returns (uint256) {
uint256 elapsed = block.timestamp - startTime;
uint256 duration = endTime - startTime;

uint256 priceDelta = startPrice - endPrice;

uint256 discount = (priceDelta * elapsed) / duration;
return startPrice - discount;
}
}
9 changes: 9 additions & 0 deletions dutch_auction/contracts/TestNFT.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract TestNFT is ERC721("", "") {
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}
56 changes: 56 additions & 0 deletions dutch_auction/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { config as dotenvConfig } from "dotenv";
import "@typechain/hardhat";
import "@nomiclabs/hardhat-ethers";
import "@nomiclabs/hardhat-waffle";
import "@nomiclabs/hardhat-etherscan";
import "solidity-coverage";
import "hardhat-gas-reporter";
import { HardhatUserConfig } from "hardhat/types/config";

dotenvConfig();

const gasPrice = parseInt(process.env.GAS_PRICE || "1000000000");

const config: HardhatUserConfig = {
solidity: {
compilers: [
{
version: "0.8.10",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
networks: {
hardhat: {
initialBaseFeePerGas: 0,
},
rinkeby: {
url: process.env.RINKEBY_URL || "",
accounts:
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
gasPrice,
},
mainnet: {
url: process.env.MAINNET_URL || "",
accounts:
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
gasPrice,
},
},
gasReporter: {
enabled: process.env.REPORT_GAS !== undefined,
currency: "USD",
gasPrice: 120,
coinmarketcap: process.env.COINMARKETCAP_API_KEY,
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
},
};

export default config;
Loading

0 comments on commit fcd4de4

Please sign in to comment.