Skip to content

Commit 7ae194a

Browse files
committed
feat(blackjack): random function exploitable
1 parent 1a6a8fb commit 7ae194a

File tree

6 files changed

+89
-250
lines changed

6 files changed

+89
-250
lines changed

contracts/Blackjack.sol

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
pragma solidity 0.8.9;
2+
3+
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
4+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
5+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
6+
7+
contract Blackjack is Initializable, PausableUpgradeable, OwnableUpgradeable {
8+
9+
/// @custom:oz-upgrades-unsafe-allow constructor
10+
constructor() {
11+
_disableInitializers();
12+
}
13+
14+
function initialize() initializer public {
15+
__Pausable_init();
16+
__Ownable_init();
17+
nonce = 0;
18+
}
19+
20+
function pause() public onlyOwner {
21+
_pause();
22+
}
23+
24+
function unpause() public onlyOwner {
25+
_unpause();
26+
}
27+
28+
uint256 nonce;
29+
// this function is exploitable. we need to change this ASAP
30+
function random() public returns (uint256) {
31+
uint256 randomNumber = uint256(
32+
keccak256(
33+
abi.encodePacked(
34+
nonce,
35+
msg.sender,
36+
gasleft(),
37+
block.difficulty,
38+
block.timestamp,
39+
block.number,
40+
blockhash(block.number - 1),
41+
block.coinbase,
42+
block.gaslimit,
43+
block.basefee,
44+
block.chainid,
45+
address(this)
46+
)
47+
)
48+
);
49+
nonce++;
50+
return randomNumber;
51+
}
52+
}

hardhat.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import "solidity-coverage";
99
import { Wallet } from "ethers";
1010
import { resolve } from "path";
1111
import { HardhatNetworkUserConfig } from "hardhat/types/config";
12+
import "@openzeppelin/hardhat-upgrades";
1213

1314
dotenv.config({ path: resolve(__dirname, "./.env") });
1415

package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
"@nomiclabs/hardhat-waffle": "^2.0.5",
77
"@openzeppelin/contracts": "^4.8.2",
88
"@openzeppelin/contracts-upgradeable": "^4.8.2",
9-
"@typechain/ethers-v5": "^7.2.0",
10-
"@typechain/hardhat": "^2.3.1",
9+
"@openzeppelin/hardhat-upgrades": "^1.22.1",
10+
"@typechain/ethers-v5": "^10.2.0",
11+
"@typechain/hardhat": "^6.1.5",
1112
"@types/chai": "^4.3.4",
1213
"@types/mocha": "^9.1.1",
1314
"@types/node": "^12.20.55",
@@ -26,17 +27,17 @@
2627
"eslint-plugin-node": "^11.1.0",
2728
"eslint-plugin-prettier": "^3.4.1",
2829
"eslint-plugin-promise": "^5.2.0",
29-
"ethereum-waffle": "^3.4.4",
30+
"ethereum-waffle": "^4.0.10",
3031
"ethers": "^5.7.2",
3132
"hardhat": "^2.13.0",
3233
"hardhat-gas-reporter": "^1.0.9",
3334
"prettier": "^2.8.4",
3435
"prettier-plugin-solidity": "^1.1.3",
3536
"rimraf": "^3.0.2",
3637
"solhint": "^3.4.1",
37-
"solidity-coverage": "^0.7.22",
38+
"solidity-coverage": "^0.8.2",
3839
"ts-node": "^10.9.1",
39-
"typechain": "^5.2.0",
40+
"typechain": "^8.1.1",
4041
"typescript": "^4.9.5"
4142
},
4243
"scripts": {

test/Blackjack.test.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect } from "chai";
2+
import { ethers, network, upgrades } from "hardhat";
3+
import { Blackjack, Blackjack__factory } from "../typechain";
4+
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
5+
import { Contract, utils } from "ethers";
6+
import {
7+
bigNumberToFloat,
8+
expandTo9Decimals,
9+
expandTo18Decimals,
10+
} from "./shared/utilities";
11+
import { abi } from "@uniswap/v2-periphery/build/UniswapV2Router02.json";
12+
import { abi as factoryAbi } from "@uniswap/v2-periphery/build/IUniswapV2Factory.json";
13+
import { abi as pairAbi } from "@uniswap/v2-periphery/build/IUniswapV2Pair.json";
14+
15+
describe("BlackJack", function () {
16+
let contract: Blackjack;
17+
beforeEach(async function () {
18+
const BlackJackFactory = <Blackjack__factory>(
19+
await ethers.getContractFactory("Blackjack")
20+
);
21+
contract = await upgrades.deployProxy(BlackJackFactory);
22+
await contract.deployed();
23+
});
24+
25+
it("Two calls of random should generate different values", async function () {
26+
const result1 = await contract.random();
27+
const result2 = await contract.random();
28+
expect(result1.value !== result2.value);
29+
});
30+
});

test/JuniorCoin.test.ts

-65
This file was deleted.

test/MafaCoin.ts

-180
This file was deleted.

0 commit comments

Comments
 (0)