A Decentralized Application for Bounty Creator and Hunters
The application lets any user create a bounty with a reward or submit a solution for an open bounty. It has the following features:
To run the application locally, follow the steps,
Clone the repo
git clone https://github.com/dev-bootcamp-2019/final-project-shashik239
Install the packages required
npm install
Start ganache-cli on port 8545
ganache-cli
Make sure you have Metamask installed and import the accounts provided by ganache-cli by importing with the seed phrase
Compile and deploy the smart contracts
truffle compile
truffle migrate --reset
Run the script to serve the application on port 3000
npm run start
The DApp is also deployed on the Rinkeyby Test Network, and static assets hosted on IPFS and can be accessed via ENS. All details regarding this can be found here Rinkeby Test Network, IPFS and ENS.
The page should be re-loaded everytime the account is changed in Metamask to ensure that the previous account is not picked for the transaction
Every page shows the address of the currently selected Metamask Account.
The state change will reflect once the transaction is complete on the network selected and notification is sent by Metamask. Please wait for transaction completion to notice the state change.
There are two possible states for a bounty -> BountyStage.Open
and BountyStage.Closed
A bounty is created by calling by the createBounty()
function (which creates the bounty in the Open state)
Once a bounty is created in the Open state, it's parameters (the problem statement or reward amount) can not be changed/mutated
A solution can be proposed for a bounty by calling the createSolution()
function (which creates a solution for the bounty in the accepted
is false
state)
This is only possible if the bounty is still in the Open
stage
The user can browse the created bounties and corresponding solutions by calling the getBounty()
and getSolution()
function
The Bounty creator can then accept a proposed solution calling the untrustedAcceptSolution()
[ONLY BOUNTY CREATOR] function which marks the Bounty Closed and sets the solution accepted and calls the untrustedCreditTransfer()
[ONLY BOUNTY CREATOR] function to transfer the credit to the payee, held in the escrow account
Once a Bounty Hunter's solution is accepted he can
call the untrustedCheckBountyWinnings()
function to check his bounty winnings credited to the escrow account
call the untrustedWithdrawBountyReward()
function to withdraw/pull his bounty winnings into his account
The Administrator or the Owner of the contract can pause or un-pause the contract features depending on any vulnerability using the toggleContractActive()
[ONLY OWNER] function inherited from the CircuitBreakerContract.sol contract
When the contract is paused stopped
bool is true
, the user will only be able to withdraw any bounty winnings and browse
To run the tests, run the following command
truffle test
The Test cases and their explanations can be found here tests
For all the design pattern desicions, please see design pattern desicions
For the steps taken to avoid known common attacks, please see avoiding common attacks
Any application can take advantage of the Bounty Contract, which is currently deployed on the Rinkeby network at 0x708a32c5852af615ba24e2ce035681d85563c0f6
All deployed addresses are available in the file deployed addresses
An INFURA hosted Ethereum node is used to connect and deploy to the Rinkeby Testnet. The configuration can be seen in the truffle.config file
The Admin/Owner address used to deploy the contract to the Rinkeby TestNet is 0x4dE2481FD30c938C5E9cFBCFe6D243f4946bf6BD
The private key for importing this account for testing the features of the App can be provided on request
The static assets are deployed to the IPFS name hash https://ipfs.infura.io/ipfs/QmVy3dnRpcXf1YQEqtfmDQCVTWkZpwqhDWyhuXTAYM2oJJ/#/
and can be accessed at https://ipfs.infura.io/ipfs/QmVy3dnRpcXf1YQEqtfmDQCVTWkZpwqhDWyhuXTAYM2oJJ/#/
The ENS name bountyDApp.test
resolves to the BountyContract.sol address 0x708a32c5852af615ba24e2ce035681d85563c0f6
via the ensutils-rinkeby.js
script pointing to the Rinkeby network contracts:
ens contract address: 0xe7410170f87102df0055eb195163a03b7f2bff4a (line 220)
publicResolver address: 0x5d20cf83cb385e06d2f2a892f9322cd4933eacdc (line 1314)
This can be verified by interacting with the public resolver contract at 0x5d20cf83cb385e06d2f2a892f9322cd4933eacdc
on https://rinkeby.etherscan.io
In the Geth console:
> namehash("bountyDApp.test")
"0x6392e5a64fd88c1daad350ddb726990eabf8ba54f74259a46bd2005e8d5b3c55"
Calling the addr()
function with node(bytes32)
input value as the namehash of "bountyDApp.test" which is 0x6392e5a64fd88c1daad350ddb726990eabf8ba54f74259a46bd2005e8d5b3c55
. The address returned is 0x8bae212130236b433915bb982db9e5240d32b404
which is the BountyContract.sol address