Skip to content

Commit

Permalink
Merge branch 'master' into pablo/uma-2653-n-06-oval-state-variable-vi…
Browse files Browse the repository at this point in the history
…sibility-not-explicitly-declared
  • Loading branch information
md0x committed Jun 18, 2024
2 parents 9977256 + ff31b1b commit 11a13ac
Show file tree
Hide file tree
Showing 24 changed files with 992 additions and 120 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<img alt="UMA Logo" src="https://i.imgur.com/fSkkK5M.png" width="440">
</p>

Oval is an MEV capture mechanism that lets protocols reclaim Oracle Extractable Value(OEV) by auctioning oracle updates. It leveraged Flashbot's [MEV-share](https://docs.flashbots.net/flashbots-protect/mev-share) OFA system by running auctions for the right to backrun an oracle update.
Oval is an MEV capture mechanism that lets protocols reclaim Oracle Extractable Value(OEV) by auctioning oracle updates. It leverages Flashbot's [MEV-share](https://docs.flashbots.net/flashbots-protect/mev-share) OFA system by running auctions for the right to backrun an oracle update.

For more information on how Oval works and how to integrate with it see the [docs](https://docs.oval.xyz/).

## Repo contents

This repository contains the main smart contracts for Oval. It uses [Foundry](https://github.com/foundry-rs/foundry). For spesific information on contracts, see the [Contract Architecture](https://docs.oval.xyz/contract-architecture) section of the docs.
This repository contains the main smart contracts for Oval. It uses [Foundry](https://github.com/foundry-rs/foundry). For specific information on contracts, see the [Contract Architecture](https://docs.oval.xyz/contract-architecture) section of the docs.

This repo also consists of a set of scripts used to profile the Oval gas usage. See [README](./scripts/README.md) that shows how to run these and [this](https://docs.oval.xyz/contract-architecture/gas-profiling) docs page that outlines the gas profiling finding.

Expand All @@ -32,10 +32,10 @@ forge build
This repository uses foundry fork tests. You will need to run the fork tests as follows:

```
export RPC_MAINNET=[your ethereum mainnet archive node url]
export RPC_MAINNET=[your Ethereum mainnet archive node url]
forge test
```

## License

All code in this repository is licensed under BUSL-1.1 unless specified differently in the file. Individual exceptions to this license can be made by Risk Labs, which holds the rights to this software and design. If you are interested in using the code or designs in a derivative work, feel free to reach out to licensing@risklabs.foundation.
All code in this repository is licensed under BUSL-1.1 unless specified differently in the file. Individual exceptions to this license can be made by Risk Labs, which holds the rights to this software and design. If you are interested in using the code or designs in a derivative work, feel free to reach out to licensing@risklabs.foundation.
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

0 comments on commit 11a13ac

Please sign in to comment.