mirror of
https://github.com/autistic-symposium/blockchains-security-toolkit.git
synced 2025-05-15 05:02:22 -04:00
add some files from my computer
This commit is contained in:
parent
44874369f1
commit
33411f9bc4
12 changed files with 318 additions and 25 deletions
24
LICENSE
24
LICENSE
|
@ -1,24 +0,0 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
37
README.md
37
README.md
|
@ -1 +1,36 @@
|
|||
# 🧱⛓☠️ [Scratch Space] Smart Contracts and Security
|
||||
# ☠️ Solidity
|
||||
|
||||
<br>
|
||||
|
||||
### Solidity basics
|
||||
|
||||
* [Solidity docs (a must for any engineer)](https://docs.soliditylang.org/en/v0.8.12/)
|
||||
* [OpenZeppelin docs](https://docs.openzeppelin.com/)
|
||||
* [Solidity style guide](https://docs.soliditylang.org/en/latest/style-guide.html)
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
### The EVM
|
||||
|
||||
* [Ethereum's Whitepaper](https://ethereum.org/en/whitepaper/)
|
||||
* [Speeding up the EVM by Flashbots](https://writings.flashbots.net/research/speeding-up-evm-part-1/)
|
||||
* "Even though at the moment the biggest bottleneck of Ethereum is not EVM's performance (the size of the Ethereum state storage is), it will soon be as Ethereum TPS goes up."
|
||||
|
||||
<br>
|
||||
|
||||
### Rollups
|
||||
|
||||
* [Understanding rollup economics from first principles](https://barnabe.substack.com/p/understanding-rollup-economics-from)
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
### Security
|
||||
|
||||
* [Uniswap Oracle Attack Simulator by Euler](https://blog.euler.finance/uniswap-oracle-attack-simulator-42d18adf65af)
|
||||
* "Given current concentrated liquidity profile of the ABC/WETH pool, what would it cost the attacker to move a N-minute TWAP of the ABC price to x?"
|
||||
* [Hacking the Blockchain by Immunifi](https://medium.com/immunefi/hacking-the-blockchain-an-ultimate-guide-4f34b33c6e8b)
|
||||
* [Thinking About Smart Contract Security by Vitalik](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
|
||||
* [Spoof tokens on Ethereum](https://medium.com/etherscan-blog/spoof-tokens-on-ethereum-c2ad882d9cf6)
|
||||
|
|
5
erc721-solidity-101/.env_sample
Normal file
5
erc721-solidity-101/.env_sample
Normal file
|
@ -0,0 +1,5 @@
|
|||
API_URL = "https://eth-rinkeby.alchemyapi.io/v2/<project>"
|
||||
PUBLIC_KEY =
|
||||
PRIVATE_KEY =
|
||||
METADATA_URL = <pinata IPFS cid dor metadata>"
|
||||
CONTRACT_ADDRESS =
|
20
erc721-solidity-101/README.md
Normal file
20
erc721-solidity-101/README.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# One: A special summer
|
||||
|
||||
|
||||
1. Compile contract:
|
||||
|
||||
```
|
||||
npx hardhat compile
|
||||
```
|
||||
|
||||
2. Deploy contract:
|
||||
|
||||
```
|
||||
npx hardhat run scripts/deploy-contract.js --network rinkeby
|
||||
```
|
||||
|
||||
3. Mint NFT:
|
||||
|
||||
```
|
||||
node scripts/mint-nft.js
|
||||
```
|
28
erc721-solidity-101/contracts/MiaNFT.sol
Normal file
28
erc721-solidity-101/contracts/MiaNFT.sol
Normal file
|
@ -0,0 +1,28 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.7.3 <0.9.0;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
||||
import "@openzeppelin/contracts/utils/Counters.sol";
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
|
||||
|
||||
contract MiaNFT is ERC721, Ownable {
|
||||
|
||||
using Counters for Counters.Counter;
|
||||
Counters.Counter private _tokenIds;
|
||||
|
||||
constructor() public ERC721("Mia's NFT, "NFT") {}
|
||||
|
||||
function mintNFT(address recipient, string memory tokenURI)
|
||||
public onlyOwner
|
||||
returns (uint256)
|
||||
{
|
||||
_tokenIds.increment();
|
||||
|
||||
uint256 newItemId = _tokenIds.current();
|
||||
_mint(recipient, newItemId);
|
||||
_setTokenURI(newItemId, tokenURI);
|
||||
|
||||
return newItemId;
|
||||
}
|
||||
}
|
19
erc721-solidity-101/hardhat.config.js
Normal file
19
erc721-solidity-101/hardhat.config.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @type import('hardhat/config').HardhatUserConfig
|
||||
*/
|
||||
require('dotenv').config();
|
||||
require("@nomiclabs/hardhat-ethers");
|
||||
|
||||
const { API_URL, PRIVATE_KEY } = process.env;
|
||||
|
||||
module.exports = {
|
||||
solidity: "0.7.3",
|
||||
defaultNetwork: "rinkeby",
|
||||
networks: {
|
||||
hardhat: {},
|
||||
rinkeby: {
|
||||
url: API_URL,
|
||||
accounts: [`0x${PRIVATE_KEY}`]
|
||||
}
|
||||
},
|
||||
}
|
23
erc721-solidity-101/package.json
Normal file
23
erc721-solidity-101/package.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "MiaNFT",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Mia von Steinkirch",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
"@openzeppelin/contracts": "^3.1.0-solc-0.7",
|
||||
"chai": "^4.3.4",
|
||||
"ethereum-waffle": "^3.4.0",
|
||||
"ethers": "^5.4.6",
|
||||
"hardhat": "^2.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alch/alchemy-web3": "^1.1.4",
|
||||
"dotenv": "^10.0.0"
|
||||
}
|
||||
}
|
14
erc721-solidity-101/scripts/deploy-contract.js
Normal file
14
erc721-solidity-101/scripts/deploy-contract.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
async function main() {
|
||||
const nft = await ethers.getContractFactory("MiaNFT");
|
||||
|
||||
const nft_deploy = await nft.deploy();
|
||||
console.log(" ⛓🧱✨ Contract address:", nft_deploy.address);
|
||||
console.log(" ➡️ (Please add this string to .env)");
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
41
erc721-solidity-101/scripts/mint-nft.js
Normal file
41
erc721-solidity-101/scripts/mint-nft.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
require('dotenv').config();
|
||||
|
||||
const PUBLIC_KEY = process.env.PUBLIC_KEY;
|
||||
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
||||
const API_URL = process.env.API_URL;
|
||||
const METADATA_URL = process.env.METADATA_URL;
|
||||
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
|
||||
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
|
||||
const web3 = createAlchemyWeb3(API_URL);
|
||||
const contract = require("../artifacts/contracts/MiaNFT.sol/MiaNFT.json");
|
||||
const nftContract = new web3.eth.Contract(contract.abi, CONTRACT_ADDRESS);
|
||||
|
||||
async function mintNFT(tokenURI) {
|
||||
|
||||
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest');
|
||||
|
||||
const transaction = {
|
||||
'from': PUBLIC_KEY,
|
||||
'to': CONTRACT_ADDRESS,
|
||||
'nonce': nonce,
|
||||
'gas': 500000,
|
||||
'maxPriorityFeePerGas': 1999999987,
|
||||
'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
|
||||
};
|
||||
|
||||
const sign = web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY);
|
||||
sign.then((signedTransaction) => {
|
||||
|
||||
web3.eth.sendSignedTransaction(signedTransaction.rawTransaction, function(e, hash) {
|
||||
if (!e) {
|
||||
console.log("💾 Transaction hash: ", hash);
|
||||
} else {
|
||||
console.log("ERROR:", e)
|
||||
}
|
||||
});
|
||||
}).catch((e) => {
|
||||
console.log("ERROR:", e);
|
||||
});
|
||||
}
|
||||
|
||||
mintNFT(METADATA_URL);
|
54
remix_IDE.md
Normal file
54
remix_IDE.md
Normal file
|
@ -0,0 +1,54 @@
|
|||
## Remix IDE
|
||||
|
||||
Remix IDE is an open source web3 application and it's used for the entire journey of smart contract development.
|
||||
|
||||
<br>
|
||||
|
||||
<img width="414" alt="Screen Shot 2022-03-10 at 5 57 22 PM" src="https://user-images.githubusercontent.com/1130416/157715032-63dfbe5d-292d-48e3-8594-04902fb008f6.png">
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
* Everything in Remix is a plugin. The plugin mamanger is the place to load functionalities and create your own plugins.
|
||||
* By default, Remix stores files in Workspaces, which are folders in the browser's local storage.
|
||||
* You can publish all files from current workspace to a gist, using the Gist API.
|
||||
|
||||
#### Compiler (Solidity)
|
||||
|
||||
* You can compile (and deploy) contracts with versions of Solidity older than 0.4.12. However, the older compilers used a legacy AST.
|
||||
* The "fork selection" dropdown list allows to compile code against a specific ehtereum hard fork.
|
||||
|
||||
#### Optimization
|
||||
|
||||
* The optimizer tries to simplify complicated expressions, which reduces both code size and execution cost. It can reduce gas needed for contract deployment as well as for external calls made to the contract.
|
||||
|
||||
|
||||
#### Environment
|
||||
|
||||
* `JavaScript VM`: All transactions will be executed in a sandbox blockchain in the browser.
|
||||
* `Injected Provider`: Metamaask is an example of a profiver that inject web3.
|
||||
* `Web3 Provider`: Remix will connect to a remote node (you need to provide the URL to the selected provider: geth, parity or any ethereum client)
|
||||
|
||||
#### Setup
|
||||
|
||||
* Gas Limit: sets the amount of ETH, WEI, GWEI that is sent to ta contract or a payable function.
|
||||
* Deploy: sends a transaction that deplpys the selected contract.
|
||||
* atAdress: used to access a contract whtat has already been deployed (does not cost gas).
|
||||
* To interact with a contract using the ABI, create a new file in Remix, with extension `.abi`.
|
||||
* The Recorder is a tool used to save a bunch of transactions in a JSON file and rerun them later either in the same environment or in another.
|
||||
* The Debugger shows the contract's state while stepping through a transaction.
|
||||
* Using generated sources will make it easier to audit your contracts.
|
||||
* Static code analysis can be done by a plugin, so that you can examine the code for security vulnerabilities, bad development practices, etc.
|
||||
* Hardhat integration can be done with `hardhat.config.js` (Hardhat websocket listener should run at `65522`). Hardhat provider is a plugin for Remix IDE.
|
||||
|
||||
|
||||
|
||||
#### Generate artifacts
|
||||
|
||||
When a compilation for a Solidity file succeeds, Remix creates three Json files for each compiled contract, that can be seen in the `File Explorers plugin`:
|
||||
|
||||
1. `artifacts/<contractName>.json`: contains links to libraries, the bytecode, gas estimation, the ABI.
|
||||
2. `articfacts/<contractName_metadata>.json`: contains the metadata from the output of Solidity compilation.
|
||||
3. `artifcats/build-info/<dynamic_hash>.json`: contains info about `solc` compiler version, compiler input and output.
|
||||
|
||||
|
15
security.md
Normal file
15
security.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
## Basic security
|
||||
|
||||
|
||||
* `tx.origin` is used: you want to replace it by “msg.sender” because otherwise any contract you call can act on your behalf.
|
||||
* Avoid potential reetrancy bugs:
|
||||
```
|
||||
msg.sender.transfer(amount);
|
||||
balances[msg.sender] -= amount;
|
||||
```
|
||||
* Inline assembly should be used only in rare cases.
|
||||
* Unclear semantics: `now` is alias for `block.timestamp` not current time; use of low level `call`, `callcode`, `delegatecall` should be avoided whenever possible; use `transfer` whenever failure of ether transfer should rollnack the whole transaction.
|
||||
* Beware of caller contracts: `selfdestruct` can block calling contracts unexpectedly.
|
||||
* Invocation of local functions via `this`: never use `this` to call functions in the same contract, it only consumes more gas than normal call.
|
||||
* Transferring Ether in a for/while/do-while loop should be avoid due to the block gas limit.
|
||||
* ERC20 `decimals` should have `uint8` as return type.
|
63
unit_testing.md
Normal file
63
unit_testing.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
## Basic Unit testing
|
||||
|
||||
<br>
|
||||
|
||||
Functions in a test file to make testing more structural:
|
||||
|
||||
* `beforeEach()` - Runs before each test
|
||||
* `beforeAll()` - Runs before all tests
|
||||
* `afterEach()` - Runs after each test
|
||||
* `afterAll()` - Runs after all tests
|
||||
|
||||
<br>
|
||||
|
||||
A generic unit testing file looks like:
|
||||
|
||||
|
||||
```
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
import "remix_tests.sol"; // this import is automatically injected by Remix.
|
||||
import "remix_accounts.sol";
|
||||
// Import here the file to test.
|
||||
|
||||
// File name has to end with '_test.sol', this file can contain more than one testSuite contracts
|
||||
contract testSuite {
|
||||
|
||||
/// 'beforeAll' runs before all other tests
|
||||
/// More special functions are: 'beforeEach', 'beforeAll', 'afterEach' & 'afterAll'
|
||||
function beforeAll() public {
|
||||
// Here should instantiate tested contract
|
||||
Assert.equal(uint(1), uint(1), "1 should be equal to 1");
|
||||
}
|
||||
|
||||
function checkSuccess() public {
|
||||
// Use 'Assert' to test the contract,
|
||||
// See documentation: https://remix-ide.readthedocs.io/en/latest/assert_library.html
|
||||
Assert.equal(uint(2), uint(2), "2 should be equal to 2");
|
||||
Assert.notEqual(uint(2), uint(3), "2 should not be equal to 3");
|
||||
}
|
||||
|
||||
function checkSuccess2() public pure returns (bool) {
|
||||
// Use the return value (true or false) to test the contract
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkFailure() public {
|
||||
Assert.equal(uint(1), uint(2), "1 is not equal to 2");
|
||||
}
|
||||
|
||||
/// Custom Transaction Context
|
||||
/// See more: https://remix-ide.readthedocs.io/en/latest/unittesting.html#customization
|
||||
/// #sender: account-1
|
||||
/// #value: 100
|
||||
function checkSenderAndValue() public payable {
|
||||
// account index varies 0-9, value is in wei
|
||||
Assert.equal(msg.sender, TestsAccounts.getAccount(1), "Invalid sender");
|
||||
Assert.equal(msg.value, 100, "Invalid value");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that ine can input custom values for `msg.sender` & `msg.value` of transaction using NatSpec comments.
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue