Skip to content

Commit

Permalink
Merge pull request #22 from moonshotcollective/week2-stake-unstake
Browse files Browse the repository at this point in the history
Week2 stake unstake
  • Loading branch information
ghostffcode authored Aug 5, 2022
2 parents 0bf1cf5 + c57321e commit c2beb2b
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 279 deletions.
79 changes: 0 additions & 79 deletions packages/hardhat/contracts/IStaking.sol

This file was deleted.

180 changes: 54 additions & 126 deletions packages/hardhat/contracts/Staking.sol
Original file line number Diff line number Diff line change
@@ -1,159 +1,87 @@
pragma solidity >=0.8.0 <0.9.0;

//SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import {IStaking} from "./IStaking.sol";

// import "hardhat/console.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Staking is IStaking, Ownable {
contract Staking is Ownable {
IERC20 public token;
uint256 public fee;

constructor(
IERC20 _token,
uint256 _quorum,
uint256 _fee
) payable {
token = _token;
fee = _fee;
quorum = _quorum;
}
uint256 public start;
uint256 public duration;
mapping(address => uint256) stakes;

function updateJuror(address juror, bool active)
public
virtual
override
onlyOwner
{
jurors[juror] = active;
event tokenStaked(address staker, uint256 amount);
event tokenUnstaked(address staker, uint256 amount);

emit jurorAction(juror, active);
modifier canUnstake() {
require(
(start == 0 && duration == 0) ||
(start > block.timestamp) ||
(start < block.timestamp && block.timestamp > start + duration),
"Can't unstake during an active round"
);
_;
}

// stake
function stake(uint256 amount) public virtual override {
token.transferFrom(msg.sender, address(this), amount);

stakes[msg.sender].balance += amount;

emit tokenStaked(msg.sender, amount);
constructor(IERC20 _token) payable {
token = _token;
}

function unstake(uint256 amount) public virtual override {
function updateMeta(uint256 _start, uint256 _duration) public onlyOwner {
require(
stakes[msg.sender].balance >= amount,
"Not enough balance to withdraw"
_start > 0 && _duration > 0,
"start and duration has to be > 0"
);
require(!stakes[msg.sender].locked, "Your stakes are currently locked");

stakes[msg.sender].balance -= amount;

token.transfer(msg.sender, amount);

emit tokenWithdrawn(msg.sender, amount);
}

function challenge(address[] memory stakers)
public
virtual
override
returns (bytes32 id)
{
// create challenge ID
id = keccak256(abi.encodePacked(msg.sender, block.number));
uint256 totalStakers = stakers.length;

require(
totalStakers > 0 && totalStakers < 255,
"Stakers out of bounds"
start + duration < block.timestamp,
"A round is currently active"
);
require(challenges[id].challenger == address(0), "Non-unique ID");

// pay challenge fee
token.transferFrom(msg.sender, address(this), fee);

// initiate challenge
challenges[id].amount = fee;
challenges[id].challenger = msg.sender;

for (uint256 i = 0; i < totalStakers; i++) {
address currentStaker = stakers[i];
require(
stakes[currentStaker].balance > 0,
"Not enough balance staked"
);
require(
!challenges[id].stakerList[currentStaker],
"Duplicate staker in array"
);

stakes[currentStaker].locked = true;
challenges[id].stakers.push(currentStaker);
challenges[id].stakerList[currentStaker] = true;
}

emit challenged(msg.sender, id);
require(
_start > block.timestamp,
"start point should be in the future"
);
start = _start;
duration = _duration;
}

function voteChallenge(bytes32 id)
function fetchMeta()
public
virtual
override
onlyJuror
challengeExists(id)
view
returns (
uint256 _start,
uint256 _duration,
bool isActiveRound
)
{
challenges[id].voted[msg.sender] = true;
challenges[id].votes += 1;
challenges[id].voters.push(msg.sender);

emit challengeVoted(id, msg.sender);
return (
start,
duration,
start < block.timestamp && block.timestamp < (start + duration)
);
}

function finalizeChallenge(bytes32 id)
public
virtual
override
challengeExists(id)
{
challenges[id].resolved = true;
// stake
function stake(uint256 amount) public {
token.transferFrom(msg.sender, address(this), amount);

uint256 amount = challenges[id].amount;
challenges[id].amount = 0;
address[] memory challengedAddresses = challenges[id].stakers;
stakes[msg.sender] += amount;

// slashes & payout
for (uint256 i = 0; i < challengedAddresses.length; i++) {
amount += stakes[challengedAddresses[i]].balance;
stakes[challengedAddresses[i]].balance = 0;
}
emit tokenStaked(msg.sender, amount);
}

uint256 totalVoters = challenges[id].voters.length;
// unstake
function unstake(uint256 amount) public canUnstake {
require(stakes[msg.sender] >= amount, "Not enough balance to withdraw");

// split token among voters and challenger
uint256 share = ((amount * 80) / 100) / totalVoters;
token.transferFrom(
address(this),
challenges[id].challenger,
(amount * 20) / 100
);
stakes[msg.sender] -= amount;

for (uint256 i = 0; i < totalVoters; i++) {
token.transferFrom(address(this), challenges[id].voters[i], share);
}
token.transfer(msg.sender, amount);

emit challengeFinalized(id);
emit tokenUnstaked(msg.sender, amount);
}

function getStakeFor(address user)
public
view
virtual
override
returns (Stake memory)
{
// view for stake amount
function getStakeFor(address user) public view returns (uint256) {
return stakes[user];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module.exports = async ({ getNamedAccounts, deployments, getChainId }) => {
const { deployer } = await getNamedAccounts();
const chainId = await getChainId();

const admin = "0x77B8A624b2e8f6772C0f20c683b075E2bf778d64";

await deploy("Token", {
from: deployer,
log: true,
Expand All @@ -17,7 +19,7 @@ module.exports = async ({ getNamedAccounts, deployments, getChainId }) => {

const Token = await ethers.getContract("Token", deployer);

const stakingArgs = [Token.address, 3, ethers.utils.parseEther("20")];
const stakingArgs = [Token.address];

await deploy("Staking", {
// Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy
Expand All @@ -29,6 +31,7 @@ module.exports = async ({ getNamedAccounts, deployments, getChainId }) => {

// Getting a previously deployed contract
const Staking = await ethers.getContract("Staking", deployer);
await Staking.transferOwnership(admin);

// Verify from the command line by running `yarn verify`

Expand Down
16 changes: 8 additions & 8 deletions packages/hardhat/hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,56 +231,56 @@ module.exports = {
},
},
moonbeam: {
url: 'https://rpc.api.moonbeam.network',
url: "https://rpc.api.moonbeam.network",
chainId: 1284,
accounts: {
mnemonic: mnemonic(),
},
},
moonriver: {
url: 'https://rpc.api.moonriver.moonbeam.network',
url: "https://rpc.api.moonriver.moonbeam.network",
chainId: 1285,
accounts: {
mnemonic: mnemonic(),
},
},
moonbaseAlpha: {
url: 'https://rpc.api.moonbase.moonbeam.network',
url: "https://rpc.api.moonbase.moonbeam.network",
chainId: 1287,
accounts: {
mnemonic: mnemonic(),
},
},
moonbeamDevNode: {
url: 'http://127.0.0.1:9933',
url: "http://127.0.0.1:9933",
chainId: 1281,
accounts: {
mnemonic: mnemonic(),
},
},
godwoken: {
url: 'https://godwoken-testnet-v1.ckbapp.dev',
url: "https://godwoken-testnet-v1.ckbapp.dev",
chainId: 71401,
accounts: {
mnemonic: mnemonic(),
},
},
arbitrum: {
url: 'https://arb1.arbitrum.io/rpc',
url: "https://arb1.arbitrum.io/rpc",
chainId: 42161,
accounts: {
mnemonic: mnemonic(),
},
},
rinkebyArbitrum: {
url: 'https://rinkeby.arbitrum.io/rpc',
url: "https://rinkeby.arbitrum.io/rpc",
chainId: 421611,
accounts: {
mnemonic: mnemonic(),
},
},
devnetArbitrum: {
url: 'https://nitro-devnet.arbitrum.io/rpc',
url: "https://nitro-devnet.arbitrum.io/rpc",
chainId: 421612,
accounts: {
mnemonic: mnemonic(),
Expand Down
1 change: 1 addition & 0 deletions packages/react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"graphql": "^15.3.0",
"ipfs-http-client": "^55.0.0",
"isomorphic-fetch": "^3.0.0",
"moment": "^2.29.4",
"node-watch": "^0.7.1",
"postcss": "^8.2.6",
"qrcode.react": "^1.0.0",
Expand Down
Loading

0 comments on commit c2beb2b

Please sign in to comment.