Skip to content

Commit

Permalink
Added a few contracts here, tasks and stuff so we can easily play aro…
Browse files Browse the repository at this point in the history
…und with them
  • Loading branch information
Cashmaney committed Feb 11, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent fde66c3 commit 6bce7b2
Showing 29 changed files with 1,684 additions and 95 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: "CI"

env:
DOTENV_CONFIG_PATH: "./.env.example"

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

jobs:
ci:
services:
# Label used to access the service container
localfhenix:
options: --name localfhenix
image: ghcr.io/fhenixprotocol/fhenix-devnet:0.1.6
ports:
# Opens tcp port
- 5000:5000
- 6000:6000
- 8545:8545
runs-on: "ubuntu-latest"
steps:
- name: "Check out the repo"
uses: "actions/checkout@v3"

- name: "Install Pnpm"
uses: "pnpm/action-setup@v2"
with:
version: "8"

- name: "Install Node.js"
uses: "actions/setup-node@v3"
with:
cache: "pnpm"
node-version: "lts/*"

- name: "Install the dependencies"
run: "pnpm install"

- name: "Lint the code"
run: "pnpm lint"

- name: "Add lint summary"
run: |
echo "## Lint results" >> $GITHUB_STEP_SUMMARY
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
- name: "Compile the contracts and generate the TypeChain bindings"
run: "pnpm typechain"

# - name: "Test the contracts"
# run: "pnpm test"

- name: "Add test summary"
run: |
echo "## Test results" >> $GITHUB_STEP_SUMMARY
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
162 changes: 162 additions & 0 deletions contracts/Auction.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear

pragma solidity >=0.8.13 <0.9.0;

import { inEuint32, euint32, FHE } from "@fhenixprotocol/contracts/FHE.sol";
import { FHERC20 } from "./fherc20.sol";
import "./ConfAddress.sol";

struct HistoryEntry {
euint32 amount;
bool refunded;
}

contract Auction {
address payable public auctioneer;
mapping(address => HistoryEntry) internal auctionHistory;
euint32 internal CONST_0_ENCRYPTED;
euint32 internal highestBid;
Eaddress internal defaultAddress;
Eaddress internal highestBidder;
euint32 internal eMaxEuint32;
uint256 public auctionEndTime;
FHERC20 internal _wfhenix;

// When auction is ended this will contain the PLAINTEXT winner address
address public winnerAddress;

event AuctionEnded(address winner, uint32 bid);

constructor(address wfhenix, uint256 biddingTime) payable {
_wfhenix = FHERC20(wfhenix);
auctioneer = payable(msg.sender);
auctionEndTime = block.timestamp + biddingTime;
CONST_0_ENCRYPTED = FHE.asEuint32(0);
highestBid = CONST_0_ENCRYPTED;
for (uint i = 0; i < 5; i++) {
defaultAddress.values[i] = CONST_0_ENCRYPTED;
highestBidder.values[i] = CONST_0_ENCRYPTED;
}

eMaxEuint32 = FHE.asEuint32(0xFFFFFFFF);
}

// Modifiers
modifier onlyAuctioneer() {
require(msg.sender == auctioneer, "Only auctioneer can perform this action");
_;
}

modifier afterAuctionEnds() {
require(block.timestamp >= auctionEndTime, "Auction ongoing");
_;
}

modifier auctionNotEnded() {
require(winnerAddress == address(0), "Auction already ended");
_;
}

modifier auctionEnded() {
require(winnerAddress != address(0), "Auction already ended");
_;
}

modifier notWinner() {
require(msg.sender != winnerAddress, "Winner cannot perform this action");
_;
}

function updateHistory(address addr, euint32 currentBid) internal returns (euint32) {
// Check for overflow, if such, just don't change the actualBid
// NOTE: overflow is most likely an abnormal action so the funds WON'T be refunded!
if (!FHE.isInitialized(auctionHistory[addr].amount)) {
HistoryEntry memory entry;
entry.amount = currentBid;
entry.refunded = false;
auctionHistory[addr] = entry;
return auctionHistory[addr].amount;
}

// Checking overflow here is optional as in real-life precision would be accounted for.
ebool hadOverflow = (eMaxEuint32 - currentBid).lt(auctionHistory[addr].amount);
euint32 actualBid = FHE.select(hadOverflow, CONST_0_ENCRYPTED, currentBid);

// Add the actual bid to the previous bid
// If there was no bid it will work because the default value of uint32 is encrypted 02
auctionHistory[addr].amount = auctionHistory[addr].amount + actualBid;
return auctionHistory[addr].amount;
}

function bid(inEuint32 calldata amount)
external
auctionNotEnded
{

euint32 spent = _wfhenix.transferFromEncrypted(msg.sender, address(this), amount);

euint32 newBid = updateHistory(msg.sender, spent);
// Can't update here highestBid directly because we need and indication whether the highestBid was changed
// if we will change here the highestBid
// we will have an edge case when the current bid will be equal to the highestBid
euint32 newHeighestBid = FHE.max(newBid, highestBid);

Eaddress memory eaddr = ConfAddress.toEaddress(payable(msg.sender));
ebool wasBidChanged = newHeighestBid.gt(highestBid);

highestBidder = ConfAddress.conditionalUpdate(wasBidChanged, highestBidder, eaddr);
highestBid = newHeighestBid;
}

function getWinner()
external
view
auctionEnded
returns (address) {
return winnerAddress;
}

function getWinningBid()
external
view
auctionEnded
returns (uint256) {
return FHE.decrypt(highestBid);
}

function endAuction()
external
onlyAuctioneer
afterAuctionEnds
auctionNotEnded
{
winnerAddress = ConfAddress.unsafeToAddress(highestBidder);
// The cards can be revealed now, we can safely reveal the bidder
emit AuctionEnded(winnerAddress, FHE.decrypt(highestBid));
}

// just for debugging purposes
function debugEndAuction()
public
onlyAuctioneer
auctionNotEnded
{
winnerAddress = ConfAddress.unsafeToAddress(highestBidder);
// The cards can be revealed now, we can safely reveal the bidder
emit AuctionEnded(winnerAddress, FHE.decrypt(highestBid));
}

function redeemFunds()
external
notWinner
auctionEnded
{
require(!auctionHistory[msg.sender].refunded, "Already refunded");

euint32 toBeRedeemed = auctionHistory[msg.sender].amount;

auctionHistory[msg.sender].refunded = true;

_wfhenix.transferEncrypted(msg.sender, toBeRedeemed);
}
}
Loading

0 comments on commit 6bce7b2

Please sign in to comment.