-
High - 100xp
-
Medium - 20xp
-
Low - 2xp
-
Starts: March 07, 2024 Noon UTC
-
Ends: March 14, 2024 Noon UTC
- nSLOC: 136
- Complexity Score: ๐
The Puppy Raffle NFT team is back! And this time, they've learnt from their mistakes... It couldn't have been their fault their last contract had so many bugs, so puppies and solidity must have just been bad luck! They decided to try this again, with sneks and Vyper! Surely that was the issue last time? ๐
The Puppy Raffle team loves being on the cutting edge, so this codebase is built with a new beta release of the vyper compiler!
Introducing... Imports!! The vyper compiler now features imports, and you can see we use imports from the ๐ snekmate repo. We pip
installed the library by invoking:
pip3 install git+https://github.com/pcaversaccio/snekmate.git@modules -t contracts/libraries
And then we removed all the files except the ones we needed.
We will use ๐ snekmate's latest ERC721.vy
contract, which is compatible with the latest Vyper compiler version, but the contract itself is considered out of scope for this audit.
You can see how we import the ERC721.vy
contract in the snek_raffle.vy
contract:
from libraries.snekmate.tokens import ERC721 # Imports the contract
initializes: ERC721 # This means that our contract initializes with the __init__ func of the ERC721 contract
exports: ( # In vyper, you have specify what external functions you want your contract to use/inherit
ERC721.balanceOf,
ERC721.ownerOf,
.
.
)
.
.
.
ERC721.__init__("Snek Raffle", "SNEK", "", "snek raffle", "v0.0.1") # This is how we initialize the ERC721 contract in our constructor
You cannot inherit/override internal functions. This is a specific design choice by the Vyper team - so that knowing exactly what a function is supposed to do is easier.
The snek_raffle.vy
is the main contract that the team is looking for a security review on, and the only contract considered in-scope. The contract functionality is as such:
enter_raffle
: Users pay theENTRANCE_FEE
to enter the snek rafflerequest_raffle_winner
: This is the function to kick off a chainlink VRF call to get a random winner. This function can be called only when the following conditions are met:- The
raffle_state
is set toOPEN
- Enough
RAFFLE_DURATION
has passed since the raffle was opened - There are at least 1
players
- There is more than 0
balance
in the contract
- The
rawFulfillRandomWords
: The function that the Chainlink VRF calls back to give the contest a random winner. The following happens when this function is called:- The winner receives:
- A random snek NFT
- The balance of the contract (should be all the entrace fees added together)
- The contract is "reset" to it's initial state:
- The raffle is considered
OPEN
players
array is resetlast_timestamp
is reset
- The raffle is considered
- The winner receives:
When someone wins a snek, it should have all the functionality of a normal NFT. It should be able to be viewed, transferred, approved, etc.
Note: If you find an issue with ERC721.vy
, ignore it. If the snek_raffle.vy
forgets to import/export a function, or uses it wrong, consider that a bug. But if the function itself is wrong in ERC721.vy
, that's fine. We are pretending that contract is perfect for this review.
The contracts rely on the Chainlink VRF to get a random number. Assume the contract/subscription will always be properly funded with LINK tokens.
There are 3 NFTs that can be won in the snek raffle, each with varying rarity.
- Brown Snek - 70% Chance to get
- Jungle Snek - 25% Chance to get
- Cosmic Snek - 5% Chance to get
The Chainlink VRF is used to get a random number, and the random number is used to determine the winner.
- Chainlink VRF: The Chainlink VRF is responsible for providing a random number to the contract.
- Users: People who can enter the raffle for the sneks.
- git
- You'll know you did it right if you can run
git --version
and you see a response likegit version x.x.x
- You'll know you did it right if you can run
- python3
- You'll know you've done it right if you can run
python3 --version
and you see a response likePython x.x.x
- You'll know you've done it right if you can run
- pip3
- You'll know you've done it right if you can run
pip3 --version
and you see a response likepip x.x.x from /path/to/site-packages/pip (python x.x)
- You'll know you've done it right if you can run
If this is your first time using a python virtual environment, you can learn more about it here, and we highly advise that you work with an AI to help you get set up. AIs like ChatGPT tend to be very good at python debugging.
- Clone the repository
git clone https://github.com/Cyfrin/2024-03-snek-raffle
cd 2024-03-snek-raffle
- Setup the virtual environment, and install packages
make venv
source ./venv/bin/activate
make install
Be sure to run source ./venv/bin/activate
before you install!
or, if make
doesn't work:
python3 -m venv ./venv
source ./venv/bin/activate
pip3 install vyper==0.4.0b1
pip3 install git+https://github.com/vyperlang/[email protected]
Q: Why not a
requirements.txt
file? A: Because this is an experimental package and the dependencies are all messed up right now.
You'll be in something called a "virtual environment" which will have all the packages you need for this project to run tests. To "leave" the python virtual environment, just run deactivate
.
The above will install the new experimental vyper compiler and titanoboa testing framework, so it might take a little longer to install than normal.
You can manually compile the vyper contract with this command:
vyper contracts/snek_raffle.vy
or
python3 -m vyper contracts/snek_raffle.vy
pytest
or
python3 -m pytest
- In Scope:
โโโ contracts
โโโ snek_raffle.vy
- Vyper Version:
0.4.0b1
(Experimental new Vyper compiler version) - Chain(s) to deploy contract to:
- Ethereum
- Arbitrum
- ZKSync
- This is a beta release of the vyper compiler which hasn't undergone a security review itself, and we expect there to be some issues with the compiler itself, ignore those.