-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
name: smartContractTest | ||
|
||
on: [push, workflow_dispatch] | ||
|
||
env: | ||
FOUNDRY_PROFILE: ci | ||
|
||
jobs: | ||
check: | ||
strategy: | ||
fail-fast: true | ||
|
||
name: Foundry project | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
with: | ||
submodules: recursive | ||
|
||
- name: Set up env variables | ||
run: | | ||
cp -n example.env .env | ||
- name: Install Foundry | ||
uses: foundry-rs/[email protected] | ||
with: | ||
version: nightly | ||
|
||
- name: Run Forge tests | ||
env: | ||
FOUNDRY_ETH_RPC_URL: ${{ secrets.RPC_URL_MAINNET }} | ||
run: | | ||
cp example.env .env | ||
forge test | ||
id: test | ||
|
||
- name: Run Forge coverage | ||
env: | ||
FOUNDRY_ETH_RPC_URL: ${{ secrets.RPC_URL_MAINNET }} | ||
run: | | ||
forge coverage |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Compiler files | ||
cache/ | ||
out/ | ||
|
||
# Ignores development broadcast logs | ||
!/broadcast | ||
/broadcast/*/31337/ | ||
/broadcast/**/dry-run/ | ||
|
||
# Docs | ||
docs/ | ||
|
||
# Dotenv file | ||
**/.env | ||
|
||
# Mac files | ||
**/.DS_Store | ||
|
||
# VS Code files | ||
.vscode | ||
|
||
# Tests reports | ||
report | ||
tests | ||
crytic-export |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[submodule "lib/forge-std"] | ||
path = lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std | ||
tag = v1.7.1 | ||
[submodule "lib/solmate"] | ||
path = lib/solmate | ||
url = https://github.com/transmissions11/solmate | ||
[submodule "lib/erc4626-tests"] | ||
path = lib/erc4626-tests | ||
url = https://github.com/a16z/erc4626-tests | ||
[submodule "lib/openzeppelin-contracts-v5.0.0"] | ||
path = lib/openzeppelin-contracts-v5.0.0 | ||
url = https://github.com/OpenZeppelin/openzeppelin-contracts | ||
tag = v5.0.0 | ||
[submodule "lib/openzeppelin-contracts-v4.9.3"] | ||
path = lib/openzeppelin-contracts-v4.9.3 | ||
url = https://github.com/OpenZeppelin/openzeppelin-contracts | ||
tag = v4.9.3 | ||
[submodule "lib/openzeppelin-contracts"] | ||
path = lib/openzeppelin-contracts | ||
url = https://github.com/OpenZeppelin/openzeppelin-contracts | ||
[submodule "lib/crytic"] | ||
path = lib/crytic | ||
url = https://github.com/crytic/properties |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
## Context | ||
`Amphor` protocol is a `L1 DeFi` protocol proposing `ERC-4626` based strategies. | ||
The first startegy to come out is a timelocked strategy that require the funds | ||
to exit the vault during the product duration (which varies from `2` to | ||
`6` weeks). | ||
|
||
## AmphorSyntheticVault | ||
This vault is the most basic strategy on the code side because the funds are | ||
deposited by the users, then the vault is locked during the product period. Once | ||
it has been locked, the funds go to a market maker wallet that is keeping the | ||
assets in garantee. | ||
At the end of the period (which varies from `2` to `6` weeks), `Amphor` | ||
get back the funds into the vault and users can `deposit` and/or `withdraw` | ||
again. | ||
|
||
## Underlying supported | ||
For the first iteration of the protocol, the only underlying supported will be | ||
`USDC` from `Circle`. | ||
In the future, we might support `WBTC` and `WETH` as underlying assets. | ||
Since `USDC` token supports `Permit` operations but not `WBTC` and `WETH`, we | ||
have separated this feature into another contract (`AmphorSyntheticVaultWithPermit`). | ||
|
||
## Process flow on the vault manager side | ||
`NOTE:` Management of the vault is handled by a multisig wallet. | ||
1. The vault contract is deployed (`constructor`) and some funds are directly | ||
deposited into it in order to bootstrap it and prevent as much as possible from | ||
inflation attacks (event if there are others protections from it). | ||
A performance fee of `20.00%` for `Amphor` protocol is set. | ||
2. The vault is open for `deposit` and `withdraw` during a little period (approx | ||
2 days). | ||
3. The vault is locked (`deposit`/`withdraw` shouldn't be possible) with the | ||
`start` function (callable only by `owner`/manager of the vault). During this | ||
transaction the funds are withdrawn from the contract. | ||
4. After the product period end, the vault is unlocked (`deposit`/`withdraw` | ||
are now be possible) using | ||
the `end` function (callable only by the `owner` of the vault). | ||
In case of a positive performance, some fees are taken fees by the protocol | ||
(that cannot exceed `30.00%` and can only be changed by `owner` of the vault). | ||
|
||
## Main contracts | ||
### Protocol contracts files | ||
- `AmphorSyntheticVault.sol`: Vanilla `AmphorSyntheticVault`. | ||
- `AmphorSyntheticVaultWithPermit.sol`: `AmphorSyntheticVault` with `Permit` feature. | ||
___ | ||
### Deployment contracts files | ||
- `L1_USDC_DeployAmphorSyntheticVault.sol`: Deployment script for `AmphorSyntheticVaultWithPermit` | ||
with `USDC` as underlying. Should bootstrap the vault with `100 USDC` (based on | ||
the `env` file). Should set the perf fees to `20.00%`. | ||
- `L1_WBTC_DeployAmphorSyntheticVault.sol`: Deployment script for `AmphorSyntheticVault` | ||
with `WBTC` as underlying. Should bootstrap the vault with `0.01 WBTC` (based on | ||
the `env` file). Should set the perf fees to `20.00%`. | ||
- `L1_WETH_DeployAmphorSyntheticVault.sol`: Deployment script for `AmphorSyntheticVault` | ||
with `WETH` as underlying. Should bootstrap the vault with `0.1 WETH` (based on | ||
the `env` file). Should set the perf fees to `20.00%`. | ||
___ | ||
### Test contracts files | ||
- `a16zCompliance.t.sol`: Implements the tests of `a16z`. Unfortunaly we didn't | ||
manage to make them work. | ||
- `cryticCompliance.t.sol`: Implements the tests of `crytic` (from | ||
[Trail of a bits](https://www.trailofbits.com/)). These one pass, you can launch | ||
them with the following command: | ||
``` | ||
$ echidna . --contract CryticERC4626PropertyTestsSynth --config test/echidna.config.yaml | ||
``` | ||
- `SyntheticBase.t.sol`: Should define a part of the main state variables. Should | ||
define some functions that will be directly used into the actual tests. | ||
- `SyntheticBasic.t.sol`: Should implement some basics tests that test the vault | ||
state variables and some basic properties of the vault. | ||
- `SyntheticDepositAndWithdraw.t.sol`: Should implement some tests on the deposit | ||
and the withdraw function. | ||
- `SyntheticEndAndStart.t.sol`: Should implement some tests on the start and the | ||
end function. | ||
- `SyntheticInflation.t.sol`: Should implement some tests demonstrating vault | ||
resilience in the face of inflationary attacks. | ||
- `SyntheticPausable.t.sol`: Should implement some tests demonstrating the good | ||
working of the `Pausable` feature. | ||
- `SyntheticPermit.t.sol`: Should implement some tests demonstrating the good | ||
working of the `Permit` feature. | ||
- `SigUtils.sol`: Should implement utils functions used by `SyntheticPermit` | ||
contract test (`SyntheticPermit.t.sol`). | ||
## Useful commands | ||
### Foundry | ||
The protocol is a [Foundry](https://book.getfoundry.sh) project. | ||
[Foundry](https://book.getfoundry.sh) a blazing fast, portable and modular | ||
toolkit for Ethereum application development written in Rust. | ||
#### Foundry commands | ||
##### Build | ||
```shell | ||
$ forge build | ||
``` | ||
##### Test | ||
```shell | ||
$ forge test | ||
``` | ||
##### Format | ||
```shell | ||
$ forge fmt | ||
``` | ||
##### Coverage | ||
```shell | ||
$ forge coverage | ||
``` | ||
##### Gas Snapshots | ||
```shell | ||
$ forge snapshot | ||
``` | ||
##### Anvil | ||
```shell | ||
$ anvil | ||
``` | ||
##### Deploy | ||
```shell | ||
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key> | ||
``` | ||
##### Cast | ||
```shell | ||
$ cast <subcommand> | ||
``` | ||
##### Help | ||
```shell | ||
$ forge --help | ||
$ anvil --help | ||
$ cast --help | ||
``` | ||
___ |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
SEED= | ||
# OR | ||
PRIVATE_KEY=0x | ||
AMPHORLABS_ADDRESS_GOERLI=0x5A0Fb32360aead818D5486fe311A88bc681A1de1 # TEST USED ONLY | ||
AMPHORLABS_ADDRESS=0x32B0aCfBb18C270491CDD124EB104A8d25A182ca # MAINNET | ||
FOUNDRY_FUZZ_MAX_TEST_REJECTS=4294967295 | ||
FOUNDRY_ETH_RPC_URL="https://eth-mainnet.g.alchemy.com/v2/API_KEY" | ||
############################################## | ||
############## SYNTHETIC VAULT ############# | ||
############################################## | ||
BOOTSTRAP_AMOUNT_SYNTHETIC_USDC=100000000 | ||
BOOTSTRAP_AMOUNT_SYNTHETIC_WETH=10000000000000000000 | ||
BOOTSTRAP_AMOUNT_SYNTHETIC_WBTC=1000000 | ||
DECIMALS_OFFSET_USDC=12 | ||
DECIMALS_OFFSET_WETH=12 | ||
DECIMALS_OFFSET_WBTC=12 | ||
SYNTHETIC_USDC_V0_NAME="Amphor Synthetic LP-IL Hedged (USDC)" | ||
SYNTHETIC_USDC_V0_SYMBOL=ampr-LP-USD | ||
SYNTHETIC_WETH_V0_NAME="Amphor Synthetic LP-IL Hedged (WETH)" | ||
SYNTHETIC_WETH_V0_SYMBOL=ampr-LP-ETH | ||
SYNTHETIC_WBTC_V0_NAME="Amphor Synthetic LP-IL Hedged (WBTC)" | ||
SYNTHETIC_WBTC_V0_SYMBOL=ampr-LP-BTC | ||
INITIAL_FEES_AMOUNT=2000 #2000 = 20.00% | ||
############################################## | ||
################# POLYGON ################# | ||
############################################## | ||
POLYGON_ETHERSCAN_API_KEY= | ||
POLYGON_ZK_TESTNET_ETHERSCAN_API_KEY= | ||
############################################## | ||
# MUMBAI | ||
USDC_MUMBAI=0xe9DcE89B076BA6107Bb64EF30678efec11939234 | ||
USDT_MUMBAI=0xAcDe43b9E5f72a4F554D4346e69e8e7AC8F352f0 | ||
DAI_MUMBAI=0xF14f9596430931E177469715c591513308244e8F | ||
WETH_MUMBAI=0xD087ff96281dcf722AEa82aCA57E8545EA9e6C96 | ||
WBTC_MUMBAI=0x97e8dE167322a3bCA28E8A49BC46F6Ce128FEC68 | ||
VERIFIER_URL_MUMBAI=https://api-testnet.polygonscan.com/api/ | ||
RPC_URL_MUMBAI=https://polygon-mumbai-bor.publicnode.com | ||
############################################## | ||
# POLYGON MAINNET | ||
USDC_POLYGON=0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 | ||
USDT_POLYGON=0xc2132D05D31c914a87C6611C10748AEb04B58e8F | ||
DAI_POLYGON=0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063 | ||
WETH_POLYGON=0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619 | ||
WBTC_POLYGON=0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6 | ||
VERIFIER_URL_POLYGON=https://api.polygonscan.com/api/ | ||
RPC_URL_POLYGON=https://polygon.meowrpc.com | ||
############################################## | ||
# POLYGON ZKEVM TESTNET | ||
VERIFIER_URL_POLYGON_ZKTEST=https://api-testnet-zkevm.polygonscan.com/api/ | ||
RPC_URL_POLYGON_ZKTEST=https://rpc.public.zkevm-test.net | ||
############################################## | ||
# POLYGON ZKEVM MAINNET | ||
VERIFIER_URL_POLYGON_ZKTEST=https://api-zkevm.polygonscan.com/api/ | ||
RPC_URL_POLYGON_ZKTEST=https://zkevm-rpc.com | ||
############################################## | ||
################# OPTIMISM ################# | ||
############################################## | ||
OPTIMISM_ETHERSCAN_API_KEY= | ||
############################################## | ||
# OPTIMISM GOERLI | ||
RPC_URL_OPTIMISM_GOERLI=https://optimism-goerli.publicnode.com | ||
VERIFIER_URL_OPTIMISM_GOERLI=https://api-goerli-optimistic.etherscan.io/api/ | ||
############################################## | ||
# OPTIMISM MAINNET | ||
RPC_URL_OPTIMISM=https://optimism.publicnode.com | ||
VERIFIER_URL_OPTIMISM=https://api-optimistic.etherscan.io/api/ | ||
############################################## | ||
################ AVALANCHE ################# | ||
############################################## | ||
AVALANCHE_SNOWTRACE_API_KEY= | ||
############################################## | ||
# AVALANCHE C-CHAIN | ||
RPC_URL_AVALANCHE=https://1rpc.io/avax/c | ||
VERIFIER_URL_AVALANCHE=https://api.snowtrace.io/api/ | ||
############################################## | ||
# AVALANCHE FUJI TESTNET | ||
RPC_URL_AVALANCHE_FUJI=https://avalanche-fuji-c-chain.publicnode.com | ||
VERIFIER_URL_AVALANCHE_FUJI=https://api-testnet.snowtrace.io/api/ | ||
############################################## | ||
################### BNB ################### | ||
############################################## | ||
BSCSCAN_API_KEY= | ||
############################################## | ||
# BNB SMART CHAIN TESTNET | ||
RPC_URL_BNB_TESTNET=https://bsc-testnet.publicnode.com | ||
VERIFIER_URL_BNB_TESTNET=https://api-testnet.bscscan.com/api/ | ||
############################################## | ||
# BNB SMART CHAIN MAINNET | ||
RPC_URL_BNB_TESTNET=https://bsc.publicnode.com | ||
VERIFIER_URL_BNB=https://api.bscscan.com/api/ | ||
############################################## | ||
################### CELO ################### | ||
############################################## | ||
#CELOSCAN_API_KEY= | ||
############################################## | ||
# CELO TESTNET | ||
RPC_URL_CELO_ALFA_TESTNET=https://alfajores-forno.celo-testnet.org | ||
#VERIFIER_URL_CELO_ALFA_TESTNET=https://alfajores.celoscan.io/api | ||
############################################## | ||
# CELO MAINNET | ||
RPC_URL_CELO=https://1rpc.io/celo | ||
#VERIFIER_URL_CELO=https://api.celoscan.io/api | ||
############################################## | ||
################### NEON ################### | ||
############################################## | ||
############################################## | ||
# NEON DEVNET | ||
RPC_URL_NEON_DEVNET=https://proxy.devnet.neonlabs.org/solana | ||
############################################## | ||
# NEON MAINNET | ||
RPC_URL_NEON_MAINNET=https://neon-proxy-mainnet.solana.p2p.org | ||
############################################## | ||
################### GNOSIS ################### | ||
############################################## | ||
GNOSIS_ETHERSCAN_API_KEY= | ||
############################################## | ||
# GNOSIS DEVNET | ||
#RPC_URL_GNOSIS_TESTNET=https://rpc.chiadochain.net | ||
############################################## | ||
# GNOSIS MAINNET | ||
RPC_URL_GNOSIS=https://gnosischain-rpc.gateway.pokt.network | ||
VERIFIER_URL_GNOSIS=https://api.gnosisscan.io/api/ | ||
############################################## | ||
################# ARBITRUM ################# | ||
############################################## | ||
ARBISCAN_API_KEY= | ||
############################################## | ||
# ARBITRUM ONE | ||
RPC_URL_ARBITRUM_ONE=https://1rpc.io/arb | ||
VERIFIER_URL_ARBITRUM_ONE=https://arbiscan.io/api/ | ||
############################################## | ||
# ARBITRUM GOERLI | ||
RPC_URL_ARBITRUM_GOERLI=https://arbitrum-goerli.publicnode.com | ||
VERIFIER_URL_ARBITRUM_GOERLI=https://api-goerli.arbiscan.io/api/ | ||
############################################## | ||
################## MANTLE ################## | ||
############################################## | ||
MANTLESCAN_API_KEY= | ||
MANTKEEXPLORER_API_KEY= | ||
############################################## | ||
# MANTLE TESTNET | ||
RPC_URL_MANTLE_TESTNET=https://rpc.testnet.mantle.xyz | ||
VERIFIER_URL_MANTLE_TESTNET=https://explorer.testnet.mantle.xyz/api/ | ||
VERIFIER_URL_MANTLESCAN_TESTNET=https://testnet.api.mantlescan.org/api/v1/ | ||
############################################## | ||
# MANTLE MAINNET | ||
RPC_URL_MANTLE_MAINNET=https://rpc.mantle.xyz | ||
VERIFIER_URL_MANTLE_TESTNET=https://explorer.mantle.xyz/api/ | ||
VERIFIER_URL_MANTLESCAN_TESTNET=https://api.mantlescan.org/api/v1/ | ||
############################################## | ||
################# ETHEREUM ################# | ||
############################################## | ||
ETHERSCAN_API_KEY= | ||
VERIFIER_URL_GOERLI=https://api-goerli.etherscan.io/api | ||
VERIFIER_URL=https://api.etherscan.io/api | ||
############################################## | ||
# GOERLI | ||
USDC_GOERLI=0x65afadd39029741b3b8f0756952c74678c9cec93 | ||
AAVE_USDC_GOERLI=0x9FD21bE27A2B059a288229361E2fA632D8D2d074 | ||
CUSTOM_USDC_GOERLI=0x782609433dDCb91c64635F65B92aa09Dc6EFd01D | ||
USDT_GOERLI=0x2e8d98fd126a32362f2bd8aa427e59a1ec63f780 | ||
DAI_GOERLI=0xba8dced3512925e52fe67b1b5329187589072a55 | ||
WETH_GOERLI=0xccb14936c2e000ed8393a571d15a2672537838ad | ||
WBTC_GOERLI=0x45AC379F019E48ca5dAC02E54F406F99F5088099 | ||
RPC_URL_GOERLI=https://ethereum-goerli.publicnode.com | ||
############################################## | ||
# SEPOLIA | ||
RPC_URL_SEPOLIA=https://endpoints.omniatech.io/v1/eth/sepolia/public | ||
############################################## | ||
# MAINNET | ||
USDC_MAINNET=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | ||
USDT_MAINNET=0xdAC17F958D2ee523a2206206994597C13D831ec7 | ||
DAI_MAINNET=0x6B175474E89094C44Da98b954EedeAC495271d0F | ||
WETH_MAINNET=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 | ||
WBTC_MAINNET=0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599 | ||
RPC_URL_MAINNET=https://ethereum.publicnode.com | ||
############################################## |