Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M-02 [Oval] Attempts to Push Price to the CoinbaseOracle Will Always Fail #18

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions scripts/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
TENDERLY_USER=
TENDERLY_PROJECT=
TENDERLY_ACCESS_KEY=
COINBASE_API_KEY=
COINBASE_API_SECRET=
COINBASE_API_PASSPHRASE=
40 changes: 40 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,43 @@ The script will create Tenderly forks that have Note starting with `Generated: 0
identify the forks that it had created and delete them when creating the same type of simulation. If you are sharing
Tenderly forks with other people, it is better to remove the `Generated: 0x...` Note from the fork through Tenderly
UI.


# Coinbase API Price Scripts

The following describes the Coinbase API Price Scripts to fetch cryptocurrency prices from the Coinbase API and logs related messages and signatures.

## Prerequisites

Before running the scripts you need to create an .env file in the scripts directory of the project and add the following environment variables:

```
COINBASE_API_KEY=your_api_key
COINBASE_API_SECRET=your_api_secret
COINBASE_API_PASSPHRASE=your_api_passphrase
```

## Installation

To set up the project, you need to install the necessary dependencies. You can do this by running the following command in your terminal:

```
yarn install
```

## Running the Scripts

Once the installation is complete, you can start the scripts with the following command:

Fetch data from the Coinbase API and save it to a file:
```
node ./src/fetchData.js
```
Read data from the file and send it to stdout:
```
node ./src/readData.js
```

## Integrating Signatures and Messages

test/unit/CoinbaseOracle.sol uses the out `fetchData.js` and `readData.js` scripts to fetch data from the Coinbase API and push it the CoinbaseOracle smart contract. Make sure the .env file is set up correctly before running the forge test.
12 changes: 7 additions & 5 deletions scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
"clean": "rm -rf contract-types && rm -rf dist && rm -rf node_modules"
},
"devDependencies": {
"@redstone-finance/protocol": "^0.5.1",
"@redstone-finance/sdk": "^0.5.1",
"@typechain/ethers-v5": "^11.1.2",
"@types/node": "^20.8.6",
"typechain": "^8.3.2",
"typescript": "^5.2.2",
"axios": "^1.5.1",
"dotenv": "^16.3.1",
"dotenv": "^16.4.5",
"ethers": "^5.7.2",
"@redstone-finance/protocol": "^0.5.1",
"@redstone-finance/sdk": "^0.5.1"
"typechain": "^8.3.2",
"typescript": "^5.2.2",
"node-fetch": "^3.3.2",
"web3": "^4.9.0"
}
}
54 changes: 54 additions & 0 deletions scripts/src/coinbase/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"BTC": {
"message": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000667021bc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000f527b32780000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
"signature": "0xfe72fff2d36008b1ad1c2f4bedd2457922ead78ba27b2cbdce6759a2bd833420966064a6df58df6a2d38c5283c7247abd68bff21cf3d237006e5bd0216bc76bc000000000000000000000000000000000000000000000000000000000000001c"
},
"ETH": {
"message": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000667021bc00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000d22e27000000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
"signature": "0xec8905696b28efa8e0b1715d0066d90ec6488915a8db5dc134d94bb11af5ec9ea95755f82e3b38f7a133b8629156ab4f71f1816c475db72554d6001ec1ec4b96000000000000000000000000000000000000000000000000000000000000001b"
},
"XTZ": {
"message": "0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006670218000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000bc7a000000000000000000000000000000000000000000000000000000000000000067072696365730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000358545a0000000000000000000000000000000000000000000000000000000000",
"signature": "0x8d86bf14f9e635caab4300780a7e830a372fee09ea61223793910b9533a0e7eb695ac2e43c36aa32ac26d501a272849ea800e1b13294fe26a10746f0be46542c000000000000000000000000000000000000000000000000000000000000001c"
},
"DAI": {
"message": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000062cedf1c00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000f41780000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034441490000000000000000000000000000000000000000000000000000000000",
"signature": "0xad99f6564beb896c16f31145b5b3f176c7ac9ac1bba315d42ef252c460b7a0a9cd75d5e25e7d05d0616d4341a1f93c46168c487addf04414d7ab1d7b44ea4887000000000000000000000000000000000000000000000000000000000000001c"
},
"REP": {
"message": "0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006424597800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000788b600000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035245500000000000000000000000000000000000000000000000000000000000",
"signature": "0x3df12304d9ac17111ac80a7237ec2fa994e1fc7b56547f12e4a66f30b4e60ff6f3adc3cc845993832855c4796b44e09b82770c7d888684eb5ae0695548e41dd8000000000000000000000000000000000000000000000000000000000000001b"
},
"ZRX": {
"message": "0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006670218000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000005d7330000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035a52580000000000000000000000000000000000000000000000000000000000",
"signature": "0x2268a2c9c7939008468c5456906f8d2abba88e91b498782b17e53607c8512c2ff85c6f89ee9d7b2d559cb6e4b36d82d7858f866c73edb82f3b6a6e2695cd29cb000000000000000000000000000000000000000000000000000000000000001c"
},
"BAT": {
"message": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000062cf049c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000005a7b20000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034241540000000000000000000000000000000000000000000000000000000000",
"signature": "0x882bc7b0c91e58ca72e5689789463fad2772de1cd4b58c3e3cde43c4a3519fb3dd4e15256dffa71504048afa784bd288570aa98a7a660c54ef147256b302281e000000000000000000000000000000000000000000000000000000000000001c"
},
"KNC": {
"message": "0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006670210800000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000009d2100000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034b4e430000000000000000000000000000000000000000000000000000000000",
"signature": "0x51bdd17d0094d50a53b7d4e87bc85e7135c958945203016aebefccf40dc5f7b3c16f2b163bf3f8c40b4ace3336146614d7a7433a121be14934fb0f11407886bc000000000000000000000000000000000000000000000000000000000000001b"
},
"LINK": {
"message": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000667021bc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000da7f8c0000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044c494e4b00000000000000000000000000000000000000000000000000000000",
"signature": "0xb26581f2666663e06e715e4ce71f7deb4c96ff767bba5b5d998c572ece609685e8f8e9fb4f7dd7017d5ca4c8eba5335e45da4ad4e00b6fb3fad7b0912e54457a000000000000000000000000000000000000000000000000000000000000001b"
},
"COMP": {
"message": "0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006670218000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000031640b0000000000000000000000000000000000000000000000000000000000000000670726963657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004434f4d5000000000000000000000000000000000000000000000000000000000",
"signature": "0x0d26681fb760c2b8cfa540d94b2d829e3711c4ee86cfbc9c9c044e75bffa39339293af1b40b5dbe878bf2bd98d4a3c3e83afd79a16ca591fc51847fe8cebac19000000000000000000000000000000000000000000000000000000000000001b"
},
"UNI": {
"message": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000667021bc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000a63e98000000000000000000000000000000000000000000000000000000000000000670726963657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003554e490000000000000000000000000000000000000000000000000000000000",
"signature": "0x5b6d356b3d4c6b9dadfd4807e45e434cbecd6cab3e741191a1c6ef830b4aa0a52cceba6adfece1e0dbdeed1d4c9322d6b4a82e4bdc7e9e7f3ab25d6a5289f019000000000000000000000000000000000000000000000000000000000000001c"
},
"GRT": {
"message": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000667021bc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000034db40000000000000000000000000000000000000000000000000000000000000006707269636573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034752540000000000000000000000000000000000000000000000000000000000",
"signature": "0x94bc918d38446f273ca07d91d9f1fff8bb0f2fcb31eb726ef26a32464e74ab07824edd51d32d9c343fef801c60d8731f4be8c6b287b956975d9b8998d56be7a6000000000000000000000000000000000000000000000000000000000000001b"
},
"SNX": {
"message": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000066701fdc00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000001f5964000000000000000000000000000000000000000000000000000000000000000670726963657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003534e580000000000000000000000000000000000000000000000000000000000",
"signature": "0xe4e42dccf098cff55a1ef70bd97e0c2f3808e3a47b12b1187d9a3da65f2f3410e50edb6937210671f3a85168a95a44b031e113132cd281d40f4506862d31c72f000000000000000000000000000000000000000000000000000000000000001b"
}
}
67 changes: 67 additions & 0 deletions scripts/src/coinbase/fetchData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require("dotenv").config(); // Add dotenv package to load environment variables
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const web3 = require("web3");

const { COINBASE_API_KEY, COINBASE_API_SECRET, COINBASE_API_PASSPHRASE } =
process.env;
if (!COINBASE_API_KEY || !COINBASE_API_SECRET || !COINBASE_API_PASSPHRASE) {
console.log(
"error: missing one or more of COINBASE_API_KEY, COINBASE_API_SECRET, COINBASE_API_PASSPHRASE environment variables"
);
process.exit(1);
}

const API_URL = "https://api.exchange.coinbase.com";

async function main() {
const timestamp = (new Date().getTime() / 1000).toString();
const message = timestamp + "GET" + "/oracle";
const hmac = crypto
.createHmac("sha256", Buffer.from(COINBASE_API_SECRET, "base64"))
.update(message);
const signature = hmac.digest("base64");

const headers = {
"CB-ACCESS-SIGN": signature,
"CB-ACCESS-TIMESTAMP": timestamp,
"CB-ACCESS-KEY": COINBASE_API_KEY,
"CB-ACCESS-PASSPHRASE": COINBASE_API_PASSPHRASE,
};

const res = await fetch(API_URL + "/oracle", { method: "GET", headers });

const { messages, signatures } = await res.json();

const output = {};
for (let i = 0; i < messages.length; ++i) {
const record = Object.values(
web3.eth.abi.decodeParameters(
["string", "uint", "string", "uint"],
messages[i]
)
).slice(0, -1);

const adr = web3.eth.accounts.recover(
web3.utils.keccak256(messages[i]),
signatures[i]
);

if (adr !== "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC")
throw new Error("Invalid signature");

output[record[2]] = {
message: messages[i],
signature: signatures[i],
};
}

const filePath = path.join(__dirname, "data.json");

fs.mkdirSync(path.dirname(filePath), { recursive: true });

fs.writeFileSync(filePath, JSON.stringify(output, null, 2));
}

main();
37 changes: 37 additions & 0 deletions scripts/src/coinbase/readData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require("dotenv").config(); // Load environment variables from .env file
const web3 = require("web3");
const fs = require("fs");
const path = require("path");

async function main(symbol) {
try {
if (!symbol) {
console.error("Error: No symbol argument provided");
process.exit(1);
}

const filePath = path.join(__dirname, "data.json");

const file = fs.readFileSync(filePath);
const data = JSON.parse(file);
const tickerData = data[symbol];

if (!tickerData) {
console.error("Error: Symbol not found");
process.exit(1);
}

const encodedData = web3.eth.abi.encodeParameters(
["bytes", "bytes"],
[tickerData.message, tickerData.signature]
);

process.stdout.write(encodedData);
} catch (error) {
console.error("An error occurred:", error.message);
process.exit(1);
}
}

const symbolArg = process.argv[2];
main(symbolArg);
Loading
Loading