Skip to content

Proposed solution to the challenge #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
.env
coverage
coverage.json
typechain

#Hardhat files
cache
artifacts
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,43 @@ Useful resources:

Make sure that all your code is tested properly

***Solution***

`npx hardhat test ./test/testETHPool.ts`

### 3) Deploy your contract

Deploy the contract to any Ethereum testnet of your preference. Keep record of the deployed address.


It is necessary to have a hidden file (.env) where the Infura project ID,
the EtherScan API Key and the private key of the account that will sign the transactions are stored

***Solution***

to deploy the contract

`npx hardhat run --network rinkeby scripts/deploy.ts`

Address of the contract of this solution

[0x5adcFC1289F883E9210ADF40840E7602F15755e6](https://rinkeby.etherscan.io/address/0x5adcFC1289F883E9210ADF40840E7602F15755e6 "0x5adcFC1289F883E9210ADF40840E7602F15755e6")

Bonus:

- Verify the contract in Etherscan

***Solution***

to verify the contract
`npx hardhat verify --network rinkeby 'contract address'`

### 4) Interact with the contract

Create a script (or a Hardhat task) to query the total amount of ETH held in the contract.

_You can use any library you prefer: Ethers.js, Web3.js, Web3.py, eth-brownie_

`npx hardhat run scripts/interactWithContract.ts`


154 changes: 154 additions & 0 deletions contracts/ETHPool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

///@title ETHPool Challenge
///@author Jeisson Niño
/**
@notice ETHPool provides a service where
people can deposit ETH and they will receive weekly rewards
*/
contract ETHPool {

uint256 public lastRewardDate;

/**@dev
They are used to carry the total of
these values ​​and thus not have to make arrangement tours
*/
uint256 public totalReward;
uint256 public totalUserDeposits;

struct detailUser {
uint256 deposit;
uint256 dateDeposit;
}
mapping(address => detailUser) public users;

mapping(address => bool) public usersTeam;

///@dev Emitted when the team deposits the winnings
///@param from The address of the user who deposits
///@param value ETH value sent by user
///@param date date when the deposit is made
event DepositRewardTeam(
address from,
uint256 value,
uint256 date
);


///@dev Emitted when the team deposits the winnings
///@param from The address of the team who deposits
///@param value ETH value sent by team
///@param date date when the deposit is made
event DepositEthUser(
address from,
uint256 value,
uint256 date);


///@dev Emitted when the user withdraws
///@param from The address of the user making the withdrawal
///@param value ETH withdrawn value
///@param date date of when the withdrawal is made
event Withdraw(
address from,
uint256 value,
uint256 date);


modifier onlyTeam() {
require(
usersTeam[msg.sender] == true,
"Exclusive function of the team"
);
_;
}


constructor() {
lastRewardDate = block.timestamp;
usersTeam[msg.sender] = true;
}


function depositRewardTeam() external payable onlyTeam {
require(
block.timestamp > (lastRewardDate + 1 weeks),
"It hasn't been a week"
);

totalReward += msg.value;
lastRewardDate = block.timestamp;
emit DepositRewardTeam(
msg.sender,
msg.value,
block.timestamp
);
}

function depositEthUser() external payable {

users[msg.sender].deposit += msg.value;
users[msg.sender].dateDeposit = block.timestamp;

totalUserDeposits += msg.value;

emit DepositEthUser(msg.sender, msg.value, block.timestamp);
}



/**@dev
Withdrawal of winnings plus the deposit
is allowed if the user blocked the ETH before
the team deposited the winnings into the contract.
if not and you have blocked ETH, you can withdraw it.

The percentage is handled using the state variables.
The treatment of converting decimals into integers is done
*/
function withdraw() external {

require(
users[msg.sender].deposit > 0,
"The user has not deposited"
);

if (users[msg.sender].dateDeposit < lastRewardDate) {
uint256 porcentagePool = (users[msg.sender].deposit * 1 ether) /
totalUserDeposits;

uint256 earningsAndDeposit = users[msg.sender].deposit +
(totalReward * porcentagePool) /
1 ether;

totalUserDeposits -= users[msg.sender].deposit;

totalReward =
totalReward -
(totalReward * porcentagePool) /
1 ether;

users[msg.sender].deposit = 0;

(bool success, ) = payable(msg.sender).call{
value: earningsAndDeposit
}("");

require(success, "Transfer failed");

emit Withdraw(
msg.sender,
earningsAndDeposit,
block.timestamp
);
} else {
(bool success, ) = payable(msg.sender).call{
value: users[msg.sender].deposit
}("");

require(success, "Transfer failed");
}
}
}
45 changes: 45 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { task } from "hardhat/config";
import "@nomiclabs/hardhat-waffle";
import "@nomiclabs/hardhat-etherscan";

require("dotenv").config();



const projeId=process.env.INFURA_PROJECT_ID
const privateKey = process.env.DEPLOYER_SIGNER_PRIVATE_KEY
const etherscanApi = process.env.ETHERSCAN_API_KEY;

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (args, hre) => {
const accounts = await hre.ethers.getSigners();

for (const account of accounts) {
console.log(await account.address);
}
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
defaultNetwork: "hardhat",
networks:{
hardhat: {
},
rinkeby:{
url: `https://rinkeby.infura.io/v3/${projeId}`,
accounts:[
privateKey
]
}
},
etherscan: {
apiKey: etherscanApi
}
};
Loading