We had a few goals with Proof of Steak:

  1. Keep gas as low as possible
  2. Allow us to reserve them for people on-chain
  3. Enable multiple Proof of Steaks per address
  4. Allow people to keep their Proof of Steak after redeeming it

The first thing I thought about was the reservations. How do you make sure someone has access to take an action within a contract? What I did was write a function called

addReservations()

. It takes in a list of addresses and how many Proof of Steaks they're each allowed and stores them. Only the admin of the contract can add reservations to keep things super safe. When people requested reservations, I called the contract and added their addresses. We spent about $1,000-$2,000 on gas to upload all of the reservations!

With all the reservations in, now we had to think about how people could mint. What I ended up doing was creating a mint function where it generates an ERC-721 for whoever calls it. But the special thing it does is saves the amount of redemptions associated with that token.

The number of redemptions is based on how much money is spent to purchase it. Token #1 may have 5 redemptions, token #2 may have 99, and token #3 may have 1. Each token has its own balance. This was specifically done to:

  1. Reduce gas (minting 1 ERC-721 is much cheaper than minting 99!)
  2. Allow you to keep your Proof of Steak after redeeming it (a fully redeemed token simply has a balance of 0)

When you mint one, we reduce your reservations by how ever many redemptions are in that new token

. If you mint one for x10 redemptions and you had reserved 15, your new reservation balance is 5. This created the nice side effect of users being able to have more than one PoS if they wanted!

And finally I wrote a redeem function. The Dogs contract will call this to check what balance a token has and if it can still be redeemed for a Dog.

And that's it! Proof of Steak.