Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rafael-ab committed Mar 1, 2024
0 parents commit 0108a0f
Show file tree
Hide file tree
Showing 19 changed files with 4,888 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MNEMONIC_FUJI=
ETH_NODE_URI_FUJI=
ETHERSCAN_API_KEY_FUJI=

MNEMONIC_AVALANCHE=
ETH_NODE_URI_AVALANCHE=
24 changes: 24 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Build contracts
on: [pull_request]

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ["18"]
steps:
- uses: actions/checkout@v3
with:
node-version: ${{ matrix.node-version }}

- name: Yarn install
run: yarn install --check-cache

- name: Yarn build
run: yarn build

- name: Lint
run: yarn lint
27 changes: 27 additions & 0 deletions .github/workflows/lint-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Lint check contracts
on: [pull_request]

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
linter:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ["18"]
steps:
- uses: actions/checkout@v3
with:
node-version: ${{ matrix.node-version }}

- name: Yarn install
run: yarn install --check-cache

### Run lint
- name: Check contracts solidity linter
if: always()
run: yarn run pr:lint:check:contracts

- name: Check contracts tests linter
if: always()
run: yarn run pr:lint:check:tests
32 changes: 32 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Build and Test
on: [pull_request]

jobs:
build-test:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Setup NodeJS 18
uses: actions/setup-node@v3
with:
node-version: 18

- name: Install yarn
run: npm install -g yarn

- name: Clean cache
run: yarn cache clean

- name: Install dependencies
run: yarn install

- name: Build
run: yarn build

- name: Test
run: yarn test
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules
.env
coverage
coverage.json
typechain
typechain-types
.vscode

# Hardhat files
cache
artifacts
hardhat-dependency-compiler

5 changes: 5 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": "hardhat/register",
"timeout": 40000,
"_": ["tests/**/*.spec.ts"]
}
18 changes: 18 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# General
.prettierignore
.solhintignore
.gitignore
.env.example
.env

# Hardhat
coverage
coverage.json
artifacts
cache
typechain-types

# JS
node_modules
package-lock.json
yarn.lock
34 changes: 34 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"overrides": [
{
"files": "**.sol",
"options": {
"printWidth": 120,
"compiler": "0.8.18",
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"trailingComma": "none"
}
},
{
"files": ["**.ts", "**.js"],
"options": {
"printWidth": 100,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"useTabs": false,
"endOfLine": "auto"
}
},
{
"files": "**.json",
"options": {
"tabWidth": 2,
"printWidth": 200
}
}
]
}
13 changes: 13 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "solhint:recommended",
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"compiler-version": ["off"],
"constructor-syntax": "warn",
"quotes": ["error", "double"],
"func-visibility": ["warn", { "ignoreConstructors": true }],
"not-rely-on-time": "off",
"private-vars-leading-underscore": ["warn", { "strict": false }]
}
}
1 change: 1 addition & 0 deletions .solhintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
56 changes: 56 additions & 0 deletions contracts/CoinPriceOneTimeFetch.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: MIT
pragma solidity =0.8.18;

import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Context} from "@openzeppelin/contracts/utils/Context.sol";

contract CoinPriceOneTimeFetch is Context, Ownable {
error NOT_FORWARDER(address forwarder, address sender);
error COIN_PRICE_ALREADY_FETCHED(string coinPair, int256 lastestCoinPrice);

event LatestCoinPrice(string indexed coinPair, int256 indexed price);

AggregatorV3Interface public coinPriceDataFeed;
address public forwarderAddress;
int256 public coinPrice;
bool public fetched;

modifier onlyForwarder() {
if (_msgSender() != forwarderAddress) revert NOT_FORWARDER(forwarderAddress, _msgSender());
_;
}

constructor(address coinPriceDataFeed_) {
coinPriceDataFeed = AggregatorV3Interface(coinPriceDataFeed_);
}

function decimals() external view returns (uint8) {
return coinPriceDataFeed.decimals();
}

function coinPair() external view returns (string memory) {
return _getCoinPair();
}

function fetchBtcPrice() external onlyForwarder {
if (fetched) revert COIN_PRICE_ALREADY_FETCHED(_getCoinPair(), coinPrice);

fetched = true;
coinPrice = _getChainlinkDataFeedLatestAnswer();

emit LatestCoinPrice(_getCoinPair(), coinPrice);
}

function setForwarderAddress(address forwarderAddress_) external onlyOwner {
forwarderAddress = forwarderAddress_;
}

function _getCoinPair() internal view returns (string memory) {
return coinPriceDataFeed.description();
}

function _getChainlinkDataFeedLatestAnswer() internal view returns (int256 answer) {
(, answer, , , ) = coinPriceDataFeed.latestRoundData();
}
}
29 changes: 29 additions & 0 deletions deploy/001_deploy_BTCUSD_CoinPriceOneTimeFetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { DeployFunction } from 'hardhat-deploy/types';
import { BTC_USD_DATA_FEED_CONTRACT } from '../utils/constants';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts, getChainId } = hre;
const { deploy } = deployments;

const { admin } = await getNamedAccounts();

const chainId = await getChainId();

const btcPriceDataFeed = BTC_USD_DATA_FEED_CONTRACT[chainId];

const deployedPriceFetch = await deploy('CoinPriceOneTimeFetch', {
from: admin,
args: [btcPriceDataFeed],
});

console.log(
'BTC/USD CoinPriceOneTimeFetch implementation deployed successfully at',
deployedPriceFetch.address
);

if (process.env.TEST !== 'true') await hre.run('etherscan-verify');
};

export default func;
func.tags = ['BTCUSD_CoinPriceOneTimeFetch'];
59 changes: 59 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'dotenv/config';
import { HardhatUserConfig } from 'hardhat/config';
import '@nomicfoundation/hardhat-ethers';
import '@nomicfoundation/hardhat-chai-matchers';
import '@nomicfoundation/hardhat-toolbox';
import '@typechain/hardhat';
import 'solidity-coverage';
import 'hardhat-deploy';
import 'hardhat-deploy-ethers';
import 'hardhat-contract-sizer';
import { network } from './utils';

const config: HardhatUserConfig = {
solidity: {
version: '0.8.18',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
networks: {
fuji: {
url: network.getNodeUrl('fuji'),
accounts: network.getAccounts('fuji'),
verify: {
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY_FUJI,
},
},
},
snowtrace: {
url: network.getNodeUrl('avalanche'),
accounts: network.getAccounts('avalanche'),
},
},
etherscan: {
apiKey: {
snowtrace: 'snowtrace', // apiKey is not required, just set a placeholder
},
customChains: [
{
network: 'snowtrace',
chainId: 43114,
urls: {
apiURL: 'https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan',
browserURL: 'https://avalanche.routescan.io',
},
},
],
},
namedAccounts: {
admin: 0,
user: 1,
},
};

export default config;
54 changes: 54 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"name": "nuklai-contracts-bitcoin-form",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"build": "hardhat compile",
"clean": "npx hardhat clean",
"contract-size": "hardhat size-contracts",
"coverage": "cross-env HARDHAT_DEPLOY_FIXTURE=true TEST=true npx hardhat coverage --testfiles \"tests/*.spec.ts\"",
"lint": "sort-package-json && cross-env prettier --write . && cross-env solhint --fix 'contracts/**/*.sol'",
"lint:check": "cross-env solhint 'contracts/**/*.sol' && cross-env prettier --check .",
"pr:lint:check:contracts": "prettier --check **.sol",
"pr:lint:check:tests": "prettier --check **/tests/**.ts",
"test": "yarn build && yarn typechain && cross-env TEST=true mocha 'tests/**/*.spec.ts'",
"typechain": "yarn hardhat typechain"
},
"dependencies": {
"@chainlink/contracts": "^0.8.0",
"@openzeppelin/contracts": "^4.9.3",
"hardhat-deploy": "^0.11.34",
"hardhat-deploy-ethers": "^0.4.1"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.0",
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
"@nomicfoundation/hardhat-verify": "^1.0.0",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@typechain/ethers-v6": "^0.4.0",
"@typechain/hardhat": "^8.0.0",
"@types/chai": "^4.2.0",
"@types/mocha": ">=9.1.0",
"@types/node": "^16.4.13",
"chai": "^4.2.0",
"cross-env": "^7.0.2",
"dotenv": "^16.3.1",
"ethers": "^6.6.4",
"hardhat": "^2.17.0",
"hardhat-contract-sizer": "^2.10.0",
"hardhat-dependency-compiler": "^1.1.3",
"hardhat-gas-reporter": "^1.0.8",
"mocha": "^10.2.0",
"prettier": "2.8.3",
"prettier-plugin-solidity": "^1.1.3",
"solhint": "^3.6.2",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.8.1",
"sort-package-json": "^2.5.1",
"ts-node": "^10.9.1",
"typechain": "^8.2.0",
"typescript": "^5.1.6"
}
}
Loading

0 comments on commit 0108a0f

Please sign in to comment.