Skip to content

Commit

Permalink
IterableMapping library
Browse files Browse the repository at this point in the history
  • Loading branch information
antico5 committed Jan 1, 2022
1 parent 9bab232 commit 6b334a1
Show file tree
Hide file tree
Showing 10 changed files with 45,025 additions and 0 deletions.
2 changes: 2 additions & 0 deletions iterable_mapping/.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 iterable_mapping/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
.env

#Hardhat files
cache
artifacts
dist
typechain
16 changes: 16 additions & 0 deletions iterable_mapping/.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
}
}
]
}
82 changes: 82 additions & 0 deletions iterable_mapping/contracts/IterableMapping.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/access/Ownable.sol";
import "hardhat/console.sol";

library IterableMapping {
// iterable mapping of address to uint
struct Map {
address[] keys;
mapping(address => uint256) values;
mapping(address => bool) includes;
mapping(address => uint256) indexes;
}

function set(
Map storage map,
address key,
uint256 value
) public {
if (map.includes[key]) {
map.values[key] = value;
} else {
map.values[key] = value;
map.includes[key] = true;
map.indexes[key] = map.keys.length;
map.keys.push(key);
}
}

function get(Map storage map, address key) public view returns (uint256) {
return map.values[key];
}

function getKeyAtIndex(Map storage map, uint256 index) public view returns (address) {
return map.keys[index];
}

function size(Map storage map) public view returns (uint256) {
return map.keys.length;
}

function remove(Map storage map, address keyToRemove) public {
address lastKey = map.keys[map.keys.length - 1];

uint256 indexToReassign = map.indexes[keyToRemove];
map.keys[indexToReassign] = lastKey;
map.indexes[lastKey] = indexToReassign;

map.keys.pop();
delete map.values[keyToRemove];
delete map.includes[keyToRemove];
delete map.indexes[keyToRemove];
}
}

contract TestIterableMappping {
using IterableMapping for IterableMapping.Map;

IterableMapping.Map private map;

function testIterableMap() public {
map.set(address(0), 0);
map.set(address(1), 100);
map.set(address(2), 200); // insert
map.set(address(2), 200); // update
map.set(address(3), 300);

for (uint256 i = 0; i < map.size(); i++) {
address key = map.getKeyAtIndex(i);

assert(map.get(key) == i * 100);
}

map.remove(address(1));

// keys = [address(0), address(3), address(2)]
assert(map.size() == 3);
assert(map.getKeyAtIndex(0) == address(0));
assert(map.getKeyAtIndex(1) == address(3));
assert(map.getKeyAtIndex(2) == address(2));
}
}
56 changes: 56 additions & 0 deletions iterable_mapping/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { config as dotenvConfig } from "dotenv";
import "@typechain/hardhat";
import "@nomiclabs/hardhat-ethers";
import "@nomiclabs/hardhat-waffle";
import "@nomiclabs/hardhat-etherscan";
import "solidity-coverage";
import "hardhat-gas-reporter";
import { HardhatUserConfig } from "hardhat/types/config";

dotenvConfig();

const gasPrice = parseInt(process.env.GAS_PRICE || "1000000000");

const config: HardhatUserConfig = {
solidity: {
compilers: [
{
version: "0.8.10",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
networks: {
hardhat: {
initialBaseFeePerGas: 0,
},
rinkeby: {
url: process.env.RINKEBY_URL || "",
accounts:
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
gasPrice,
},
mainnet: {
url: process.env.MAINNET_URL || "",
accounts:
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
gasPrice,
},
},
gasReporter: {
enabled: process.env.REPORT_GAS !== undefined,
currency: "USD",
gasPrice: 120,
coinmarketcap: process.env.COINMARKETCAP_API_KEY,
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
},
};

export default config;
Loading

0 comments on commit 6b334a1

Please sign in to comment.