Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Salmandabbakuti committed Sep 23, 2024
0 parents commit bd9c70b
Show file tree
Hide file tree
Showing 11 changed files with 12,858 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
node_modules
.env

# Hardhat files
/cache
/artifacts

# TypeChain files
/typechain
/typechain-types

# solidity-coverage files
/coverage
/coverage.json

# Hardhat Ignition default folder for deployments against a local node
ignition/deployments/chain-31337
.DS_Store
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 blockninja007

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Sample Hardhat Project

This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.

Try running some of the following tasks:

```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat ignition deploy ./ignition/modules/Lock.ts
```
212 changes: 212 additions & 0 deletions contracts/FluidGrants.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.24;

import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import {ISuperfluidPool} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/gdav1/ISuperfluidPool.sol";
import {SuperTokenV1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";

contract FluidGrants {
using SuperTokenV1Library for ISuperToken;

uint256 public grantCount;
uint256 public projectCount;

struct Grant {
uint256 id;
string name;
string description;
string externalUrl;
uint256 amount;
uint256 submissionStartsAt;
uint256 submissionEndsAt;
uint256 judgingStartsAt;
uint256 judgingEndsAt;
ISuperToken distributionToken;
ISuperfluidPool pool;
bool isActive;
}

struct Project {
uint256 id;
string name;
string description;
string repositoryUrl;
string demoUrl;
address walletAddress;
uint256 votes;
}

event GrantCreated(
uint256 id,
string name,
string description,
string externalUrl,
uint256 amount,
uint256 submissionStartsAt,
uint256 submissionEndsAt,
uint256 judgingStartsAt,
uint256 judgingEndsAt,
address distributionToken,
address pool
);

event ProjectSubmitted(
uint256 id,
uint256 grantId,
string name,
string description,
string repositoryUrl,
string demoUrl,
address walletAddress
);

event ProjectVoted(
uint256 projectId,
uint256 grantId,
uint256 votes,
address voter
);

event GrantDistributed(uint256 grantId, uint256 amount);

mapping(uint256 grantId => Grant) public grants;
mapping(uint256 projectId => Project) public projects;
mapping(uint256 grantId => uint256 count) public grantProjectCount;
mapping(uint256 grantId => mapping(address user => bool hasSubmitted))
public hasSubmittedToGrant;
mapping(uint256 grantId => mapping(uint256 projectId => bool))
public isProjectInGrant;

function createGrant(
string memory _name,
string memory _description,
string memory _externalUrl,
uint256 _amount,
uint256 _submissionStartsAt,
uint256 _submissionEndsAt,
uint256 _judgingStartsAt,
uint256 _judgingEndsAt,
ISuperToken _distributionToken
) external {
PoolConfig memory config = PoolConfig({
transferabilityForUnitsOwner: false,
distributionFromAnyAddress: true
});

ISuperfluidPool pool = _distributionToken.createPool(
address(this),
config
);

uint256 grantId = grantCount++;

grants[grantId] = Grant({
id: grantId,
name: _name,
description: _description,
amount: _amount,
submissionStartsAt: _submissionStartsAt,
submissionEndsAt: _submissionEndsAt,
judgingStartsAt: _judgingStartsAt,
judgingEndsAt: _judgingEndsAt,
externalUrl: _externalUrl,
distributionToken: _distributionToken,
pool: pool,
isActive: true
});
emit GrantCreated(
grantId,
_name,
_description,
_externalUrl,
_amount,
_submissionStartsAt,
_submissionEndsAt,
_judgingStartsAt,
_judgingEndsAt,
address(_distributionToken),
address(pool)
);
}

function distributeGrant(uint256 _grantId) external {
Grant storage grant = grants[_grantId];
require(grant.isActive, "Grant is not active");
ISuperToken token = grant.distributionToken;
uint256 amount = grant.amount;
token.distributeToPool(address(this), grant.pool, amount);
grant.isActive = false;
emit GrantDistributed(_grantId, amount);
}

function submitProject(
uint256 _grantId,
string memory _name,
string memory _description,
string memory repositoryUrl,
string memory _demoUrl,
address _walletAddress
) external {
Grant memory grant = grants[_grantId];
require(grant.isActive, "Grant is not active");
require(
block.timestamp >= grant.submissionStartsAt ||
block.timestamp <= grant.submissionEndsAt,
"Grant is not in submission period"
);
require(
!hasSubmittedToGrant[_grantId][msg.sender],
"You have already submitted a project to this grant"
);
ISuperToken token = grant.distributionToken;
ISuperfluidPool pool = grant.pool;
uint256 projectId = grantProjectCount[_grantId]++;
projects[projectId] = Project({
id: projectId,
name: _name,
description: _description,
repositoryUrl: repositoryUrl,
demoUrl: _demoUrl,
walletAddress: _walletAddress,
votes: 0
});
hasSubmittedToGrant[_grantId][msg.sender] = true;
isProjectInGrant[_grantId][projectId] = true;
token.connectPool(pool);
emit ProjectSubmitted(
projectId,
_grantId,
_name,
_description,
repositoryUrl,
_demoUrl,
_walletAddress
);
}

function voteOnProject(
uint256 _grantId,
uint256 _projectId,
uint128 _votes
) external {
Grant memory grant = grants[_grantId];
Project storage project = projects[_projectId];
require(project.walletAddress != address(0), "Project does not exist");
require(grant.isActive, "Grant is not active");
require(
block.timestamp >= grant.judgingStartsAt ||
block.timestamp <= grant.judgingEndsAt,
"Grant is not in judging period"
);
require(
isProjectInGrant[_grantId][_projectId],
"Project is not in grant"
);
project.votes = _votes;
ISuperToken token = grant.distributionToken;
ISuperfluidPool pool = grant.pool;
token.updateMemberUnits(pool, project.walletAddress, _votes);
emit ProjectVoted(_projectId, _grantId, _votes, msg.sender);
}
}
34 changes: 34 additions & 0 deletions contracts/Lock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
uint public unlockTime;
address payable public owner;

event Withdrawal(uint amount, uint when);

constructor(uint _unlockTime) payable {
require(
block.timestamp < _unlockTime,
"Unlock time should be in the future"
);

unlockTime = _unlockTime;
owner = payable(msg.sender);
}

function withdraw() public {
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);

require(block.timestamp >= unlockTime, "You can't withdraw yet");
require(msg.sender == owner, "You aren't the owner");

emit Withdrawal(address(this).balance, block.timestamp);

owner.transfer(address(this).balance);
}
}
8 changes: 8 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
solidity: "0.8.24",
};

export default config;
17 changes: 17 additions & 0 deletions ignition/modules/Lock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const JAN_1ST_2030 = 1893456000;
const ONE_GWEI: bigint = 1_000_000_000n;

const LockModule = buildModule("LockModule", (m) => {
const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);

const lock = m.contract("Lock", [unlockTime], {
value: lockedAmount,
});

return { lock };
});

export default LockModule;
Loading

0 comments on commit bd9c70b

Please sign in to comment.