Skip to content

Commit

Permalink
Merge pull request #24 from firstbatchxyz/erhant/more-rfks
Browse files Browse the repository at this point in the history
Erhant/more rfks
  • Loading branch information
erhant authored Dec 23, 2024
2 parents 4808f41 + 9576190 commit b804b82
Show file tree
Hide file tree
Showing 18 changed files with 170 additions and 199 deletions.
14 changes: 12 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
{
// solidity
"solidity.packageDefaultDependenciesContractsDirectory": "src",
"solidity.packageDefaultDependenciesDirectory": "lib",
"editor.formatOnSave": true,
"[solidity]": {
"editor.defaultFormatter": "JuanBlanco.solidity"
},
"solidity.formatter": "forge",
"solidity.compileUsingRemoteVersion": "v0.8.26",
"solidity.defaultCompiler": "localFile"
"solidity.defaultCompiler": "localFile",
// remappings.txt here fixes random errors
"solidity.remappingsUnix": [
"forge-std/=lib/forge-std/src/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/"
],
"material-icon-theme.files.associations": {
".gas-snapshot": "bench-ts"
}
}
72 changes: 36 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ To interact with the blockchain, we require an RPC endpoint. You can get one fro

You will use this endpoint for the commands that interact with the blockchain, such as deploying and upgrading; or while doing fork tests.

### Deploy & Verify Contract
### Deploy Contract

Deploy the contract with:

Expand All @@ -116,9 +116,23 @@ forge script ./script/Deploy.s.sol:Deploy<CONTRACT_NAME> \
--broadcast
```

You can see deployed contract addresses under the `deployment/<chainid>.json`
You can see deployed contract addresses under the [`deployments/<chainid>.json`](./deployments/) folder.

You can verify the contract during deployment by adding the verification arguments as well:
You will need the contract ABIs to interact with them as well, thankfully there is a nice short-hand command to export that:

```sh
forge inspect <CONTRACT_NAME> abi > ./deployments/abis/<CONTRACT_NAME>.json
```

### Verify Contract

Verification requires the following values, based on which provider you are using:

- **Provider**: can accept any of `etherscan`, `blockscout`, `sourcify`, `oklink` or `custom` for more fine-grained stuff.
- **URL**: based on the chosen provider, we require its URL as well, e.g. `https://base-sepolia.blockscout.com/api/` for `blockscout` on Base Sepolia
- **API Key**: an API key from the chosen provider, must be stored as `ETHERSCAN_API_KEY` in environment no matter whicih provider it is!.

You can actually verify the contract during deployment by adding the verification arguments as well:

```sh
forge script ./script/Deploy.s.sol:Deploy<CONTRACT_NAME> \
Expand All @@ -129,39 +143,35 @@ forge script ./script/Deploy.s.sol:Deploy<CONTRACT_NAME> \
--verifier-url <VERIFIER_URL>
```

You can verify an existing contract with:
Alternatively, you can verify an existing contract (perhaps deployed from a factory) with:

```sh
forge verify-contract <CONTRACT_ADDRESS> ./src/<CONTRACT_NAME>.sol:<CONTRACT_NAME> \
--verifier blockscout \
--verifier-url <VERIFIER_URL>
--verifier blockscout --verifier-url <VERIFIER_URL>
```

Note that the `--verifier-url` value should be the target explorer's homepage URL. Some example URLs are:

- `https://base.blockscout.com/api/` for Base (Mainnet)
- `https://base-sepolia.blockscout.com/api/` for Base Sepolia (Testnet)

> [!NOTE]
>
> URL should not contain the API key! Foundry will read your `ETHERSCAN_API_KEY` from environment.
> [!NOTE]
>
> The `--verifier` can accept any of the following: `etherscan`, `blockscout`, `sourcify`, `oklink`. We are using Blockscout most of the time.
### Upgrade Contract

### Generate ABIs
Upgrading an existing contract is done as per the instructions in [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) repository.

To interact with the contracts, you need the contract ABIs. We store the ABIs under the [`abis`](./abis/) folder, and these can be generated using the following script:
First, we create a new contract with its name as `ContractNameV2`, and then we execute the following command:

```sh
./export-abis.sh
forge script ./script/Deploy.s.sol:Upgrade<CONTRACT_NAME> \
--rpc-url <RPC_URL> \
--account <WALLET_NAME> --broadcast \
--sender <WALLET_ADDRESS> \
--verify --verifier blockscout \
--verifier-url <VERIFIER_URL>
```

### Upgrade Contract

Upgrading an existing contract is done as per the instructions in [openzeppelin-foundry-upgrades](https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades) repository.
The `--sender <ADDRESS>` field is required when deploying a contract,
> [!NOTE]
>
> The `--sender <ADDRESS>` field is mandatory when deploying a contract, it can be obtained with the command below, which will prompt for keystore password:
>
> ```sh
> cast wallet address --account <WALLET_NAME>
> ```
## Testing & Diagnostics
Expand Down Expand Up @@ -194,16 +204,6 @@ Alternatively, you can see a summarized text-only output as well:
forge coverage --no-match-coverage "(test|mock|script)"
```

### Storage Layout

You can print storage layouts for each contract using:

```sh
./storage.sh
```

The resulting Markdown files will be created under the [`storage`](./storage/) directory.

### Gas Snapshot

You can examine the gas usage metrics using the command:
Expand All @@ -225,7 +225,7 @@ forge fmt ./src/**/*.sol ./script/**/*.sol
If you have solhint installed, you can lint all contracts with:

```sh
solhint 'contracts/**/*.sol'
solhint 'src/**/*.sol'
```

## Documentation
Expand Down
24 changes: 0 additions & 24 deletions abis/parseAbi.cjs

This file was deleted.

136 changes: 68 additions & 68 deletions broadcast/Deploy.s.sol/84532/run-latest.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion deployment/.gitignore

This file was deleted.

1 change: 1 addition & 0 deletions deployments/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
31337/
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -1192,4 +1192,4 @@
}
]
}
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -585,4 +585,4 @@
}
]
}
]
]
8 changes: 0 additions & 8 deletions export-abis.sh

This file was deleted.

2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ force = true
# fs permissions for deployment (false by default)
fs_permissions = [
{ access = "read", path = "out" },
{ access = "read-write", path = "deployment" },
{ access = "read-write", path = "deployments" },
]
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
61 changes: 37 additions & 24 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Upgrades, UnsafeUpgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol";
import {Upgrades, UnsafeUpgrades, Options} from "@openzeppelin/foundry-upgrades/Upgrades.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {Script} from "forge-std/Script.sol";
import {Vm} from "forge-std/Vm.sol";
Expand Down Expand Up @@ -32,13 +32,13 @@ contract DeployLLMOracleRegistry is Script {

function run() external returns (address proxy, address impl) {
vm.startBroadcast();
(proxy, impl) = this.deploy();
(proxy, impl) = deploy();
vm.stopBroadcast();

helper.writeProxyAddresses("LLMOracleRegistry", proxy, impl);
}

function deploy() external returns (address proxy, address impl) {
function deploy() public returns (address proxy, address impl) {
proxy = Upgrades.deployUUPSProxy(
"LLMOracleRegistry.sol",
abi.encodeCall(
Expand Down Expand Up @@ -82,7 +82,7 @@ contract DeployLLMOracleCoordinator is Script {
token = address(0x4200000000000000000000000000000000000006);
}

function run() external returns (address proxy, address impl) {
function run() public {
// read registry address
string memory deployments = helper.getDeploymentsJson();
require(vm.keyExistsJson(deployments, "$.LLMOracleRegistry"), "Please deploy LLMOracleRegistry first");
Expand All @@ -92,13 +92,13 @@ contract DeployLLMOracleCoordinator is Script {
require(registryImlp != address(0), "LLMOracleRegistry implementation address is invalid");

vm.startBroadcast();
(proxy, impl) = this.deploy(registryProxy);
(address proxy, address impl) = deploy(registryProxy);
vm.stopBroadcast();

helper.writeProxyAddresses("LLMOracleCoordinator", proxy, impl);
}

function deploy(address registryAddr) external returns (address proxy, address impl) {
function deploy(address registryAddr) public returns (address proxy, address impl) {
proxy = Upgrades.deployUUPSProxy(
"LLMOracleCoordinator.sol",
abi.encodeCall(
Expand All @@ -111,37 +111,50 @@ contract DeployLLMOracleCoordinator is Script {
}
}

contract UpgradeLLMOracleRegistry is Script {
contract UpgradeLLMOracleCoordinator is Script {
Helper public helper;
Stakes public stakes;
uint256 public minRegistrationTimeSec;
address public token;

constructor() {
helper = new Helper();
}

// parameters
minRegistrationTimeSec = 1 days;
stakes = Stakes({generator: 0.0001 ether, validator: 0.000001 ether});
token = address(0x4200000000000000000000000000000000000006); // WETH
function run() public returns (address impl) {
// todo: get proxy address
address proxy = 0xe3Ab5D57Feb189d7CD1685336FD638856391b9EB;

vm.startBroadcast();
impl = upgrade(proxy);
vm.stopBroadcast();

helper.writeProxyAddresses("LLMOracleCoordinator", proxy, impl);
}

function run() external returns (address proxy, address impl) {
function upgrade(address proxy) public returns (address impl) {
Upgrades.upgradeProxy(proxy, "LLMOracleCoordinatorV2.sol", "");
impl = Upgrades.getImplementationAddress(proxy);
}
}

contract UpgradeLLMOracleRegistry is Script {
Helper public helper;

constructor() {
helper = new Helper();
}

function run() public returns (address impl) {
// todo: get proxy address
address proxy = 0x568Cfb5363E70Cde784f8603E2748e614c3420a7;

vm.startBroadcast();
(proxy, impl) = this.deploy();
impl = upgrade(proxy);
vm.stopBroadcast();

helper.writeProxyAddresses("LLMOracleRegistry", proxy, impl);
}

function deploy() external returns (address proxy, address impl) {
proxy = Upgrades.deployUUPSProxy(
"LLMOracleRegistry.sol",
abi.encodeCall(
LLMOracleRegistry.initialize, (stakes.generator, stakes.validator, token, minRegistrationTimeSec)
)
);

function upgrade(address proxy) public returns (address impl) {
Upgrades.upgradeProxy(proxy, "LLMOracleRegistryV2.sol", "");
impl = Upgrades.getImplementationAddress(proxy);
}
}
11 changes: 5 additions & 6 deletions script/Helper.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,17 @@ contract Helper is Script {
/// @dev You are expect to use JSON-related commands with the returned string,
/// see https://book.getfoundry.sh/cheatcodes/external for more.
function getDeploymentsJson() external view returns (string memory) {
string memory dir = "deployment/";
string memory fileName = Strings.toString(block.chainid);
string memory path = string.concat(dir, fileName, ".json");
string memory chainId = Strings.toString(block.chainid);
string memory path = string.concat("deployments/", chainId, "addresses.json");

return vm.readFile(path);
}

function writeProxyAddresses(string memory name, address _proxy, address _impl) external {
// create a deployment file if not exist
string memory dir = "deployment/";
string memory fileName = Strings.toString(block.chainid);
string memory path = string.concat(dir, fileName, ".json");
string memory dir = "deployments/";
string memory chainId = Strings.toString(block.chainid);
string memory path = string.concat(dir, chainId, ".json");

string memory proxy = Strings.toHexString(uint256(uint160(_proxy)), 20);
string memory impl = Strings.toHexString(uint256(uint160(_impl)), 20);
Expand Down
22 changes: 0 additions & 22 deletions storage.sh

This file was deleted.

2 changes: 1 addition & 1 deletion test/LLMOracleCoordinator.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol";

import {LLMOracleTask, LLMOracleTaskParameters} from "../src/LLMOracleTask.sol";
import {LLMOracleRegistry, LLMOracleKind} from "../src/LLMOracleRegistry.sol";
Expand Down
2 changes: 1 addition & 1 deletion test/LLMOracleRegistry.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol";

import {LLMOracleRegistry, LLMOracleKind} from "../src/LLMOracleRegistry.sol";

Expand Down
3 changes: 2 additions & 1 deletion test/Statistics.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pragma solidity ^0.8.20;

import {Vm} from "forge-std/Vm.sol";
import {Test, console} from "forge-std/Test.sol";
import {Statistics} from "../src/Statistics.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";

import {Statistics} from "../src/Statistics.sol";

contract StatisticsTest is Test {
uint8 constant MAX_SCORE = 255; // max value of uint8
uint8 constant MIN_SCORE = 1;
Expand Down
Loading

0 comments on commit b804b82

Please sign in to comment.