-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bd9c70b
Showing
11 changed files
with
12,858 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.