Skip to content

Commit

Permalink
swan foundry setup
Browse files Browse the repository at this point in the history
  • Loading branch information
caglacelik committed Nov 20, 2024
1 parent a14c029 commit 59401fe
Show file tree
Hide file tree
Showing 39 changed files with 5,624 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Deployer key (REQUIRED)
PUBLIC_KEY=

### Base URLs ###
# Mainnet
BASE_MAIN_RPC_URL=

# Testnet
BASE_TEST_RPC_URL=https://sepolia.base.org

# Blockscout API Key
# Foundry expects the API key to be defined as ETHERSCAN_API_KEY
ETHERSCAN_API_KEY=
47 changes: 47 additions & 0 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
BuyerAgentTest:test_InBuyPhase() (gas: 182615337)
BuyerAgentTest:test_InSellPhase() (gas: 182593663)
BuyerAgentTest:test_RevertWhen_SetAmountPerRoundInBuyPhase() (gas: 182596518)
BuyerAgentTest:test_RevertWhen_SetFeeWithInvalidRoyalty() (gas: 182603480)
BuyerAgentTest:test_RevertWhen_SetRoyaltyInSellPhase() (gas: 182595095)
BuyerAgentTest:test_RevertWhen_WithdrawByAnotherOwner() (gas: 182621624)
BuyerAgentTest:test_RevertWhen_WithdrawInBuyPhase() (gas: 182608980)
BuyerAgentTest:test_SetRoyaltyAndAmountPerRound() (gas: 182604536)
BuyerAgentTest:test_WithdrawInWithdrawPhase() (gas: 182585003)
DeployTest:test_Deploy() (gas: 101371)
LLMOracleCoordinatorTest:test_Deployment() (gas: 86478543)
LLMOracleCoordinatorTest:test_RegisterOracles() (gas: 86763309)
LLMOracleCoordinatorTest:test_ValidatorIsGenerator() (gas: 87180676)
LLMOracleCoordinatorTest:test_WithValidation() (gas: 87839545)
LLMOracleCoordinatorTest:test_WithoutValidation() (gas: 87420651)
LLMOracleRegistryTest:test_Deployment() (gas: 18798876)
LLMOracleRegistryTest:test_RegisterGeneratorOracle() (gas: 19137915)
LLMOracleRegistryTest:test_RegisterValidatorOracle() (gas: 19137984)
LLMOracleRegistryTest:test_RevertWhen_RegisterSameGeneratorTwice() (gas: 19141313)
LLMOracleRegistryTest:test_RevertWhen_RegistryHasNotApprovedByOracle() (gas: 18938187)
LLMOracleRegistryTest:test_RevertWhen_UnregisterSameGeneratorTwice() (gas: 19157453)
LLMOracleRegistryTest:test_UnregisterOracle() (gas: 19154341)
LLMOracleRegistryTest:test_WithdrawStakesAfterUnregistering() (gas: 19179317)
SwanIntervalsTest:test_ChangeCycleTime() (gas: 184999199)
SwanIntervalsTest:test_InBuyPhase() (gas: 182573254)
SwanIntervalsTest:test_InSellPhase() (gas: 182568456)
SwanIntervalsTest:test_InWithdrawPhase() (gas: 182576467)
SwanTest:test_CreateBuyerAgents() (gas: 183760248)
SwanTest:test_Deployment() (gas: 179280562)
SwanTest:test_PurchaseAnAsset() (gas: 188748932)
SwanTest:test_RelistAsset() (gas: 187998184)
SwanTest:test_RevertWhen_CreateBuyerWithInvalidRoyalty() (gas: 179349648)
SwanTest:test_RevertWhen_ListInWithdrawPhase() (gas: 183823955)
SwanTest:test_RevertWhen_ListMoreThanMaxAssetCount() (gas: 187892487)
SwanTest:test_RevertWhen_PurchaseByAnotherBuyer() (gas: 187906998)
SwanTest:test_RevertWhen_PurchaseInSellPhase() (gas: 187890335)
SwanTest:test_RevertWhen_PurchaseMoreThanAmountPerRound() (gas: 188775426)
SwanTest:test_RevertWhen_RelistAlreadyPurchasedAsset() (gas: 188743009)
SwanTest:test_RevertWhen_RelistByAnotherSeller() (gas: 187888798)
SwanTest:test_RevertWhen_RelistInBuyPhase() (gas: 187920803)
SwanTest:test_RevertWhen_RelistInTheSameRound() (gas: 187893814)
SwanTest:test_RevertWhen_RelistInWithdrawPhase() (gas: 187920820)
SwanTest:test_SetAmountPerRound() (gas: 183801616)
SwanTest:test_SetFactories() (gas: 183318192)
SwanTest:test_SetMarketParameters() (gas: 183900237)
SwanTest:test_SetOracleParameters() (gas: 183743049)
SwanTest:test_UpdateState() (gas: 189350579)
45 changes: 45 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Show Forge version
run: |
forge --version
- name: Run Forge fmt
run: |
forge fmt --check
id: fmt

- name: Run Forge build
run: |
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Forge files
cache/
out/

# coverage
coverage/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/*/84532/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env

# Forge files
cache/
out/
lib/

# gas snapshot
.gas-snapshot/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Dotenv file
.env
12 changes: 12 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-foundry-upgrades"]
path = lib/openzeppelin-foundry-upgrades
url = https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-include .env

.PHONY: build test local-key base-sepolia-key deploy anvil install update

# Capture the network name
network := $(word 2, $(MAKECMDGOALS))

# Default to forked base-sepolia network
KEY_NAME := local-key
NETWORK_ARGS := --account local-key --sender 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --broadcast

ifeq ($(network), base-sepolia)
KEY_NAME := base-sepolia-key
NETWORK_ARGS:= --rpc-url $(BASE_TEST_RPC_URL) --account base-sepolia-key --sender $(PUBLIC_KEY) --broadcast --verify --verifier blockscout --verifier-url https://base-sepolia.blockscout.com/api/
endif

# Install Dependencies
install:
forge install foundry-rs/forge-std --no-commit && forge install OpenZeppelin/openzeppelin-contracts --no-commit && forge install OpenZeppelin/openzeppelin-foundry-upgrades --no-commit && forge install OpenZeppelin/openzeppelin-contracts-upgradeable --no-commit

# Build the contracts
build:
forge clean && forge build

# Generate gas snapshot under snapshots directory
snapshot:
forge snapshot

# Generate the documentation under docs directory
docs:
forge doc

# Test the contracts on forked base-sepolia network
test:
forge clean && forge test --fork-url $(BASE_TEST_RPC_URL)

anvil:
anvil --fork-url $(BASE_TEST_RPC_URL)

# Create keystores for encrypted private keys by using bls12-381 curve (https://eips.ethereum.org/EIPS/eip-2335)
key:
cast wallet import $(KEY_NAME) --interactive

# Default to local network if no network is specified
deploy:
forge script ./script/Deploy.s.sol:Deploy $(NETWORK_ARGS)

# TODO: forge-verify

# Prevent make from interpreting the network name as a target
$(eval $(network):;@:)
104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Swan Protocol

This document provides instructions for swan contracts using Foundry.

## Test

Compile the contracts:

```sh
make build
```

Run tests on forked base-sepolia:

```sh
make test
```

## Coverage

Check coverages with:

```sh
bash coverage.sh
```

You can see coverages under the coverage directory.

## Storage Layout

Create storage layout with:

```sh
bash coverage.sh
```

You can see storage layouts under the storage directory.

## Deployment

**Step 1.**
Import your `PUBLIC_KEY` and `ETHERSCAN_API_KEY` to env file.

> [!NOTE]
>
> Foundry expects the API key to be defined as `ETHERSCAN_API_KEY` even though you're using another explorer.
**Step 2.**
Create keystores for deployment. [See more for keystores](https://eips.ethereum.org/EIPS/eip-2335)

```sh
make local-key
```

or for base-sepolia

```sh
make base-sepolia-key
```

> [!NOTE]
>
> Recommended to create keystores on directly on your shell.
> You HAVE to type your password on the terminal to be able to use your keys. (e.g when deploying a contract)
**Step 3.**
Enter your private key (associated with the public key you added to env file) and password on terminal. You'll see your public key on terminal.

> [!NOTE]
>
> If you want to deploy contracts on localhost please provide localhost public key for the command above.
**Step 4.** Required only for local deployment.

Start a local node with:

```sh
make anvil
```

**Step 5.**
Deploy the contracts on localhost (forked Base Sepolia) using Deploy script:

```sh
make deploy
```

or Base Sepolia with the command below:

```sh
make deploy base-sepolia
```

You can see deployed contract addresses under the `deployment/<chainid>.json`

## Gas Snapshot

Take the gas snapshot with:

```sh
make snapshot
```

You can see the snapshot `.gas-snapshot` in the current directory.
48 changes: 48 additions & 0 deletions contracts/libraries/Statistics.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

/// @notice Simple statistic library for uint256 arrays, numbers are treat as fixed-precision floats.
library Statistics {
/// @notice Compute the mean of the data.
/// @param data The data to compute the mean for.
function avg(uint256[] memory data) internal pure returns (uint256 ans) {
uint256 sum = 0;
for (uint256 i = 0; i < data.length; i++) {
sum += data[i];
}
ans = sum / data.length;
}

/// @notice Compute the variance of the data.
/// @param data The data to compute the variance for.
function variance(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
mean = avg(data);
uint256 sum = 0;
for (uint256 i = 0; i < data.length; i++) {
uint256 diff = data[i] - mean;
sum += diff * diff;
}
ans = sum / data.length;
}

/// @notice Compute the standard deviation of the data.
/// @dev Computes variance, and takes the square root.
/// @param data The data to compute the standard deviation for.
function stddev(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
(uint256 _variance, uint256 _mean) = variance(data);
mean = _mean;
ans = sqrt(_variance);
}

/// @notice Compute the square root of a number.
/// @dev Uses Babylonian method.
/// @param x The number to compute the square root for.
function sqrt(uint256 x) internal pure returns (uint256 y) {
uint256 z = (x + 1) / 2;
y = x;
while (z < y) {
y = z;
z = (x / z + z) / 2;
}
}
}
Loading

0 comments on commit 59401fe

Please sign in to comment.