Skip to content

Commit

Permalink
NFT Marketplace Auction
Browse files Browse the repository at this point in the history
  • Loading branch information
ABFX15 committed Nov 25, 2024
1 parent fa9cce1 commit 738b36d
Show file tree
Hide file tree
Showing 14 changed files with 801 additions and 108 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/openzepplin-contracts"]
path = lib/openzepplin-contracts
url = https://github.com/openzepplin/openzepplin-contracts
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
89 changes: 38 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,53 @@
## Foundry
# NFT Auction Smart Contract

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
A decentralized NFT auction platform built on Ethereum that allows users to create auctions for their NFTs and accept bids from other users.

Foundry consists of:
## Features

- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
- **Chisel**: Fast, utilitarian, and verbose solidity REPL.
- NFT owners can create auctions with custom reserve prices and durations
- Bidders can place bids on active auctions
- Automatic refund of outbid amounts
- Sellers can end auctions early if reserve price is met
- Built-in security with reentrancy protection
- Fully tested with Foundry

## Documentation
## Contract Details

https://book.getfoundry.sh/
The main contract `AuctionContract.sol` implements the following key functionality:

## Usage
- `depositNft()`: Create a new auction by depositing an NFT
- `bid()`: Place a bid on an active auction
- `finishAuction()`: Complete an auction after time expires
- `sellerEndAuction()`: Allow seller to end auction early if reserve met
- `withdraw()`: Withdraw refunded bid amounts
- `getActiveAuctions()`: View all currently active auctions

### Build
## Technical Specifications

```shell
$ forge build
```
- Solidity version: 0.8.20
- Built with OpenZeppelin contracts
- Implements ERC721 receiver interface
- Uses ReentrancyGuard for security
- Comprehensive test suite in Foundry

### Test
## Security Features

```shell
$ forge test
```
- Reentrancy protection on critical functions
- Checks-Effects-Interactions pattern
- Access control via Ownable
- Minimum auction duration enforcement
- Safe transfer handling

### Format
## Testing

```shell
$ forge fmt
```
The contract includes extensive tests covering:

### Gas Snapshots
- NFT deposits
- Bidding functionality
- Auction completion
- Withdrawal mechanics
- Edge cases and security scenarios

```shell
$ forge snapshot
```
Run tests with:
`forge test`

### Anvil

```shell
$ anvil
```

### Deploy

```shell
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
```

### Cast

```shell
$ cast <subcommand>
```

### Help

```shell
$ forge --help
$ anvil --help
$ cast --help
```
1 change: 1 addition & 0 deletions lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at dac63c
7 changes: 7 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=lib/forge-std/src/
halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/
openzepplin-contracts/=lib/openzepplin-contracts/
236 changes: 236 additions & 0 deletions report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# Aderyn Analysis Report

This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a static analysis tool built by [Cyfrin](https://cyfrin.io), a blockchain security company. This report is not a substitute for manual audit or security review. It should not be relied upon for any purpose other than to assist in the identification of potential security vulnerabilities.
# Table of Contents

- [Summary](#summary)
- [Files Summary](#files-summary)
- [Files Details](#files-details)
- [Issue Summary](#issue-summary)
- [High Issues](#high-issues)
- [H-1: Uninitialized State Variables](#h-1-uninitialized-state-variables)
- [H-2: Sending native Eth is not protected from these functions.](#h-2-sending-native-eth-is-not-protected-from-these-functions)
- [Low Issues](#low-issues)
- [L-1: Centralization Risk for trusted owners](#l-1-centralization-risk-for-trusted-owners)
- [L-2: Unsafe ERC20 Operations should not be used](#l-2-unsafe-erc20-operations-should-not-be-used)
- [L-3: `public` functions not used internally could be marked `external`](#l-3-public-functions-not-used-internally-could-be-marked-external)
- [L-4: Event is missing `indexed` fields](#l-4-event-is-missing-indexed-fields)
- [L-5: PUSH0 is not supported by all chains](#l-5-push0-is-not-supported-by-all-chains)


# Summary

## Files Summary

| Key | Value |
| --- | --- |
| .sol Files | 2 |
| Total nSLOC | 186 |


## Files Details

| Filepath | nSLOC |
| --- | --- |
| src/AuctionContract.sol | 168 |
| src/SellerNft.sol | 18 |
| **Total** | **186** |


## Issue Summary

| Category | No. of Issues |
| --- | --- |
| High | 2 |
| Low | 5 |


# High Issues

## H-1: Uninitialized State Variables

Solidity does initialize variables by default when you declare them, however it's good practice to explicitly declare an initial value. For example, if you transfer money to an address we must make sure that the address has been initialized.

<details><summary>1 Found Instances</summary>


- Found in src/SellerNft.sol [Line: 11](src/SellerNft.sol#L11)

```solidity
uint256 private tokenCounter;
```

</details>



## H-2: Sending native Eth is not protected from these functions.

Introduce checks for `msg.sender` in the function

<details><summary>1 Found Instances</summary>


- Found in src/AuctionContract.sol [Line: 198](src/AuctionContract.sol#L198)

```solidity
function withdraw() public {
```

</details>



# Low Issues

## L-1: Centralization Risk for trusted owners

Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.

<details><summary>3 Found Instances</summary>


- Found in src/AuctionContract.sol [Line: 12](src/AuctionContract.sol#L12)

```solidity
contract AuctionContract is Ownable, ReentrancyGuard, IERC721Receiver {
```

- Found in src/SellerNft.sol [Line: 10](src/SellerNft.sol#L10)

```solidity
contract SellerNFT is ERC721, Ownable {
```

- Found in src/SellerNft.sol [Line: 22](src/SellerNft.sol#L22)

```solidity
function approveToAuction(address auctionContract, uint256 tokenId) external onlyOwner{
```

</details>



## L-2: Unsafe ERC20 Operations should not be used

ERC20 functions may not behave as expected. For example: return values are not always meaningful. It is recommended to use OpenZeppelin's SafeERC20 library.

<details><summary>2 Found Instances</summary>


- Found in src/AuctionContract.sol [Line: 112](src/AuctionContract.sol#L112)

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

- Found in src/AuctionContract.sol [Line: 175](src/AuctionContract.sol#L175)

```solidity
payable(auction.seller).transfer(sellerEth);
```

</details>



## L-3: `public` functions not used internally could be marked `external`

Instead of marking a function as `public`, consider marking it as `external` if it is not used internally.

<details><summary>5 Found Instances</summary>


- Found in src/AuctionContract.sol [Line: 133](src/AuctionContract.sol#L133)

```solidity
function bid(
```

- Found in src/AuctionContract.sol [Line: 162](src/AuctionContract.sol#L162)

```solidity
function sellerEndAuction(uint256 auctionId) public nonReentrant {
```

- Found in src/AuctionContract.sol [Line: 186](src/AuctionContract.sol#L186)

```solidity
function getActiveAuctions() public view returns (uint256[] memory) {
```

- Found in src/AuctionContract.sol [Line: 198](src/AuctionContract.sol#L198)

```solidity
function withdraw() public {
```

- Found in src/AuctionContract.sol [Line: 210](src/AuctionContract.sol#L210)

```solidity
function onERC721Received(
```

</details>



## L-4: Event is missing `indexed` fields

Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.

<details><summary>4 Found Instances</summary>


- Found in src/AuctionContract.sol [Line: 27](src/AuctionContract.sol#L27)

```solidity
event NFTDeposited(
```

- Found in src/AuctionContract.sol [Line: 32](src/AuctionContract.sol#L32)

```solidity
event BidPlaced(
```

- Found in src/AuctionContract.sol [Line: 37](src/AuctionContract.sol#L37)

```solidity
event AuctionEnded(
```

- Found in src/AuctionContract.sol [Line: 42](src/AuctionContract.sol#L42)

```solidity
event bidRefunded(
```

</details>



## L-5: PUSH0 is not supported by all chains

Solc compiler version 0.8.20 switches the default target EVM version to Shanghai, which means that the generated bytecode will include PUSH0 opcodes. Be sure to select the appropriate EVM version in case you intend to deploy on a chain other than mainnet like L2 chains that may not support PUSH0, otherwise deployment of your contracts will fail.

<details><summary>2 Found Instances</summary>


- Found in src/AuctionContract.sol [Line: 3](src/AuctionContract.sol#L3)

```solidity
pragma solidity 0.8.20;
```

- Found in src/SellerNft.sol [Line: 3](src/SellerNft.sol#L3)

```solidity
pragma solidity 0.8.20;
```

</details>



19 changes: 0 additions & 19 deletions script/Counter.s.sol

This file was deleted.

17 changes: 17 additions & 0 deletions script/DeployAuctionContract.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import {Script} from "forge-std/Script.sol";
import {AuctionContract} from "../src/AuctionContract.sol";

contract DeployAuctionContract is Script {
AuctionContract private auctionContract;

function run() public returns (AuctionContract) {
vm.startBroadcast();
auctionContract = new AuctionContract();
vm.stopBroadcast();
return auctionContract;
}
}
Loading

0 comments on commit 738b36d

Please sign in to comment.