Skip to content

Commit

Permalink
feat: zksync support in baseTest (#51)
Browse files Browse the repository at this point in the history
* feat: zksync support in baseTest

* docs: zksync test docs

* feat: add zksync support for baseStableTest + lint in docs

* refactor: zksync adapter params in base tests

* chore: add CI support for zksync tests

* feat: etherfi + Ethena zksync capo (#52)

* feat: add sDAI capo

* feat: weETH, sUSDS, USDSe capo

* fix: script and tests naming

* chore: cleanup

* chore: update weETH and sUSDe snapshots + fork block tests

* chore: weETH + sUSDe reports

* fix:  update solc on CLRatePriceCapAdapter

* fix: zksync ci test support

* chore: update ci

* fix: ci

* fix: ci

---------

Co-authored-by: Harsh Pandey <[email protected]>

---------

Co-authored-by: Harsh Pandey <[email protected]>
  • Loading branch information
ianflexa and brotherlymite authored Nov 22, 2024
1 parent 4348fad commit 9e8584b
Show file tree
Hide file tree
Showing 16 changed files with 367 additions and 48 deletions.
26 changes: 0 additions & 26 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,4 @@ LEDGER_SENDER=
# Deployment via private key
PRIVATE_KEY=

# Test rpc_endpoints
RPC_MAINNET=https://eth.llamarpc.com
RPC_AVALANCHE=https://api.avax.network/ext/bc/C/rpc
RPC_OPTIMISM=https://optimism.llamarpc.com
RPC_POLYGON=https://polygon.llamarpc.com
RPC_ARBITRUM=https://arbitrum.llamarpc.com
RPC_FANTOM=https://rpc.ftm.tools
RPC_HARMONY=https://api.harmony.one
RPC_METIS=https://andromeda.metis.io/?owner=1088
RPC_BASE=https://base.llamarpc.com
RPC_ZKEVM=https://zkevm-rpc.com
RPC_GNOSIS=https://rpc.ankr.com/gnosis
RPC_BNB=https://binance.llamarpc.com

# Etherscan api keys for verification & download utils
ETHERSCAN_API_KEY_MAINNET=
ETHERSCAN_API_KEY_POLYGON=
ETHERSCAN_API_KEY_AVALANCHE=
ETHERSCAN_API_KEY_FANTOM=
ETHERSCAN_API_KEY_OPTIMISM=
ETHERSCAN_API_KEY_ARBITRUM=
ETHERSCAN_API_KEY_BASE=
ETHERSCAN_API_KEY_ZKEVM=
ETHERSCAN_API_KEY_GNOSIS=
ETHERSCAN_API_KEY_BNB=


44 changes: 41 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,44 @@ on:
workflow_dispatch:

jobs:
test:
uses: bgd-labs/github-workflows/.github/workflows/foundry-test.yml@main
secrets: inherit
test-sol:
name: Foundry build n test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: bgd-labs/action-rpc-env@main
with:
ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}

# we simply use foundry zk for all jobs in this repo
- name: Run Foundry setup
uses: bgd-labs/github-workflows/.github/actions/foundry-setup@main
with:
ZKSYNC: "true"

- name: Run Forge tests
id: test
uses: bgd-labs/github-workflows/.github/actions/foundry-test@main
with:
MODE: "CHANGED"

- name: Run ZK tests
id: zktest
uses: bgd-labs/github-workflows/.github/actions/foundry-test@main
with:
MODE: "CHANGED"
ZKSYNC: true
ROOT_DIR: "zksync"

- name: Run Forge tests
uses: bgd-labs/github-workflows/.github/actions/comment-artifact@main

# we let failing tests pass so we can log them in the comment, still we want the ci to fail
- name: Post test
if: ${{ steps.test.outputs.testStatus != 0 || steps.zktest.outputs.testStatus != 0 }}
run: |
echo "tests failed"
exit 1
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# build and cache
cache/
out/
zkout/

# general
.env
Expand Down
19 changes: 19 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ ffi = true
fs_permissions = [{ access = "write", path = "./reports" }]
evm_version = 'shanghai'

[profile.zksync]
src = 'zksync/src'
test = 'zksync/tests'
libs = ['lib']
remappings = []
solc = '0.8.20'
fs_permissions = [{ access = "write", path = "./reports" }]
ffi = true
evm_version = 'shanghai'

[profile.zksync.zksync]
bytecode_hash = 'none'
compile = true
fallback_oz = true
mode = '3'
zksolc = '1.5.3'

[rpc_endpoints]
mainnet = "${RPC_MAINNET}"
optimism = "${RPC_OPTIMISM}"
Expand All @@ -24,6 +41,7 @@ zkevm = "${RPC_ZKEVM}"
gnosis = "${RPC_GNOSIS}"
bnb = "${RPC_BNB}"
scroll="${RPC_SCROLL}"
zksync = "${RPC_ZKSYNC}"

[etherscan]
mainnet = { key="${ETHERSCAN_API_KEY_MAINNET}", chainId=1 }
Expand All @@ -38,5 +56,6 @@ zkevm = { key="${ETHERSCAN_API_KEY_ZKEVM}", chainId=1101 }
gnosis = { key="${ETHERSCAN_API_KEY_GNOSIS}", chainId=100 }
bnb= { key="${ETHERSCAN_API_KEY_BNB}",chainId=56,url='https://api.bscscan.com/api'}
scroll={key="${ETHERSCAN_API_KEY_SCROLL}",chainId=534352}
zksync = { key="${ETHERSCAN_API_KEY_ZKSYNC}", chain = 324 }

# See more config options https://github.com/gakonst/foundry/tree/master/config
7 changes: 7 additions & 0 deletions how-to.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Alter the appropriate deployment script:
- `snapshotTimestamp`: timestamp of the snapshot ratio
- `maxYearlyRatioGrowthPercent`: the maximum possible annual LST growth percentage

1.1 If the adapter is deployed on zkSync network, you'll need to create a function that only returns the encoded parameters above instead of returning the deployment code.

2. Add the deployment script and command to the Makefile.

## 3. Testing
Expand All @@ -65,6 +67,11 @@ To test the adapter:

1. Add the test to the destination network folder inside `tests`.
2. Inherit it from [`BaseTest`](tests/BaseTest.sol) and implement the simple `_createAdapter()` method, when the specific adapter is created. Or just inherit the test from [CLAdapterBaseTest.sol](tests/CLAdapterBaseTest.sol) when Chainlink oracle is used.

2.1. If the adapter will be tested against the zksync network:

- add the `salt` parameter using the `new` keyword for deployment: e.g.: `new CLRatePriceCapAdapter{salt: 'test'}(capAdapterParams)`

3. Specify the following test parameters:
- adapter code
- number of days for retrospective testing (default is 90). Check that with the specified parameters the adapter has not been capped for the last X days. A report comparing prices with the base aggregator is also generated.
Expand Down
34 changes: 34 additions & 0 deletions reports/sUSDe_ZkSync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Capo Report

| Capped sUSDe / USDe / USD | USDe / USD | Diff | Date | 14-day growth in yearly % |
| ------------------------- | ---------- | ------ | ----------- | ------------------------- |
| 1.11195118 | 1.00024757 | 10.58% | 28 Oct 2024 | 9.33% |
| 1.1125614 | 1.0005 | 10.61% | 30 Oct 2024 | 9.62% |
| 1.11341766 | 1.00097941 | 10.64% | 31 Oct 2024 | 9.90% |
| 1.11371677 | 1.00096143 | 10.66% | 01 Nov 2024 | 10.17% |
| 1.11327601 | 1.00026341 | 10.69% | 02 Nov 2024 | 10.53% |
| 1.1143006 | 1.0008725 | 10.73% | 03 Nov 2024 | 10.58% |
| 1.11455263 | 1.00078891 | 10.76% | 04 Nov 2024 | 10.65% |
| 1.11468545 | 1.0006 | 10.79% | 05 Nov 2024 | 10.06% |
| 1.11526216 | 1.00081265 | 10.82% | 06 Nov 2024 | 10.14% |
| 1.11603128 | 1.0012 | 10.85% | 07 Nov 2024 | 10.25% |
| 1.11684814 | 1.00133096 | 10.91% | 08 Nov 2024 | 11.29% |
| 1.11737186 | 1.00150053 | 10.94% | 09 Nov 2024 | 11.33% |
| 1.11723336 | 1.00107996 | 10.97% | 10 Nov 2024 | 11.32% |
| 1.11791936 | 1.0014 | 11.00% | 11 Nov 2024 | 11.38% |
| 1.11884016 | 1.001938 | 11.02% | 12 Nov 2024 | 11.38% |
| 1.11835784 | 1.00150607 | 11.02% | 13 Nov 2024 | 10.69% |
| 1.11947894 | 1.00222841 | 11.05% | 14 Nov 2024 | 10.68% |
| 1.1193506 | 1.00183747 | 11.08% | 15 Nov 2024 | 10.68% |
| 1.12052337 | 1.0018 | 11.19% | 16 Nov 2024 | 12.67% |
| 1.12094851 | 1.00158273 | 11.25% | 17 Nov 2024 | 13.51% |
| 1.12129925 | 1.00131213 | 11.31% | 18 Nov 2024 | 14.25% |
| 1.12191947 | 1.0013 | 11.36% | 19 Nov 2024 | 14.93% |

- 14-day growth is calculated as an annualized percentage relative to the value of the rate 14 days prior.

| Max Yearly % | Max Day-to-day yearly % | Max 14-day yearly % |
| ------------ | ----------------------- | ------------------- |
| 50.00% | 38.25% | 14.93% |

- Max day-to-day yearly % indicates the maximum growth between two emissions as an annualized percentage.
41 changes: 41 additions & 0 deletions reports/weETH_ZkSync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Capo Report

| Capped weETH / eETH(ETH) / USD | ETH / USD | Diff | Date | 7-day growth in yearly % |
| ------------------------------ | ------------- | ----- | ----------- | ------------------------ |
| 2796.30214289 | 2661.02 | 4.96% | 21 Oct 2024 | 2.82% |
| 2754.66311811 | 2621.21 | 4.96% | 22 Oct 2024 | 2.81% |
| 2640.15185513 | 2512.04 | 4.97% | 23 Oct 2024 | 2.82% |
| 2649.8634455 | 2521.09862646 | 4.98% | 24 Oct 2024 | 2.86% |
| 2605.81459261 | 2479.02 | 4.99% | 25 Oct 2024 | 2.49% |
| 2619.25098808 | 2491.62 | 4.99% | 26 Oct 2024 | 2.51% |
| 2652.20026346 | 2522.79 | 5.00% | 27 Oct 2024 | 2.43% |
| 2697.10415893 | 2565.33062993 | 5.01% | 28 Oct 2024 | 2.49% |
| 2767.7168616 | 2632.31044615 | 5.02% | 30 Oct 2024 | 2.48% |
| 2793.03766059 | 2656.18 | 5.02% | 31 Oct 2024 | 2.48% |
| 2659.20135356 | 2528.75 | 5.03% | 01 Nov 2024 | 2.42% |
| 2646.76422145 | 2516.9136 | 5.03% | 02 Nov 2024 | 2.12% |
| 2583.38116131 | 2456.258022 | 5.04% | 03 Nov 2024 | 2.50% |
| 2587.57445769 | 2460.06324246 | 5.05% | 04 Nov 2024 | 2.54% |
| 2550.78265691 | 2424.9076 | 5.06% | 05 Nov 2024 | 2.57% |
| 2735.55463878 | 2600.36 | 5.07% | 06 Nov 2024 | 2.61% |
| 2954.92711115 | 2808.6694 | 5.08% | 07 Nov 2024 | 2.60% |
| 3052.44231365 | 2900.8948 | 5.09% | 08 Nov 2024 | 3.10% |
| 3213.70316926 | 3053.91 | 5.10% | 09 Nov 2024 | 3.45% |
| 3375.72482722 | 3207.6299 | 5.11% | 10 Nov 2024 | 3.10% |
| 3359.40506995 | 3191.871483 | 5.11% | 11 Nov 2024 | 3.16% |
| 3583.57362333 | 3404.579563 | 5.12% | 12 Nov 2024 | 3.25% |
| 3328.81126755 | 3162.5422 | 5.12% | 13 Nov 2024 | 2.88% |
| 3400.41654846 | 3230.37692177 | 5.13% | 14 Nov 2024 | 2.80% |
| 3204.02893756 | 3043.4155 | 5.14% | 15 Nov 2024 | 2.65% |
| 3270.47195073 | 3106.2683715 | 5.15% | 16 Nov 2024 | 2.69% |
| 3312.50919564 | 3145.9392 | 5.16% | 17 Nov 2024 | 2.72% |
| 3277.67047438 | 3112.67627839 | 5.16% | 18 Nov 2024 | 2.58% |
| 3271.89848866 | 3106.95 | 5.17% | 19 Nov 2024 | 2.53% |

- 7-day growth is calculated as an annualized percentage relative to the value of the rate 7 days prior.

| Max Yearly % | Max Day-to-day yearly % | Max 7-day yearly % |
| ------------ | ----------------------- | ------------------ |
| 8.75% | 5.76% | 3.45% |

- Max day-to-day yearly % indicates the maximum growth between two emissions as an annualized percentage.
89 changes: 89 additions & 0 deletions scripts/DeployZkSync.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import {ZkSyncScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol';
import {CLRatePriceCapAdapter} from '../src/contracts/CLRatePriceCapAdapter.sol';
import {AaveV3ZkSync, AaveV3ZkSyncAssets} from 'aave-address-book/AaveV3ZkSync.sol';
import {PriceCapAdapterStable} from '../src/contracts/PriceCapAdapterStable.sol';
import {IPriceCapAdapterStable} from '../src/interfaces/IPriceCapAdapterStable.sol';
import {IPriceCapAdapter, IChainlinkAggregator} from '../src/interfaces/IPriceCapAdapter.sol';

library CapAdaptersCodeZkSync {
address public constant weETH_eETH_AGGREGATOR = 0x8D3184a992f93729b249407C33F1e78abE0d650e;
address public constant sUSDe_USDe_AGGREGATOR = 0x97920183c36B022B46D6C14b9dA36c5f31A98C6A;
address public constant USDe_PRICE_FEED = 0x4899faF0b6c36620168D00e3DbD4CB9361244c4d;

function weETHAdapterParams() internal pure returns (bytes memory) {
return
abi.encode(
IPriceCapAdapter.CapAdapterParams({
aclManager: AaveV3ZkSync.ACL_MANAGER,
baseAggregatorAddress: AaveV3ZkSyncAssets.WETH_ORACLE,
ratioProviderAddress: weETH_eETH_AGGREGATOR,
pairDescription: 'Capped weETH / eETH(ETH) / USD',
minimumSnapshotDelay: 7 days,
priceCapParams: IPriceCapAdapter.PriceCapUpdateParams({
snapshotRatio: 1_052574497679413779,
snapshotTimestamp: 1731404006, // 12th of November 2024
maxYearlyRatioGrowthPercent: 8_75
})
})
);
}

function sUSDeAdapterParams() internal pure returns (bytes memory) {
return
abi.encode(
IPriceCapAdapter.CapAdapterParams({
aclManager: AaveV3ZkSync.ACL_MANAGER,
baseAggregatorAddress: USDe_PRICE_FEED,
ratioProviderAddress: sUSDe_USDe_AGGREGATOR,
pairDescription: 'Capped sUSDe / USDe / USD',
minimumSnapshotDelay: 14 days,
priceCapParams: IPriceCapAdapter.PriceCapUpdateParams({
snapshotRatio: 1_114017044432046603,
snapshotTimestamp: 1730790353, // 05th of November 2024
maxYearlyRatioGrowthPercent: 50_00
})
})
);
}

function USDeAdapterParams() internal pure returns (bytes memory) {
return
abi.encode(
IPriceCapAdapterStable.CapAdapterStableParams({
aclManager: AaveV3ZkSync.ACL_MANAGER,
assetToUsdAggregator: IChainlinkAggregator(USDe_PRICE_FEED),
adapterDescription: 'Capped USDe / USD',
priceCap: int256(1.04 * 1e8)
})
);
}
}

contract DeployWeEthZkSync is ZkSyncScript {
function run() external broadcast {
new CLRatePriceCapAdapter{salt: 'capo'}(
abi.decode(CapAdaptersCodeZkSync.weETHAdapterParams(), (IPriceCapAdapter.CapAdapterParams))
);
}
}

contract DeploySUSDeZkSync is ZkSyncScript {
function run() external broadcast {
new CLRatePriceCapAdapter{salt: 'capo'}(
abi.decode(CapAdaptersCodeZkSync.sUSDeAdapterParams(), (IPriceCapAdapter.CapAdapterParams))
);
}
}

contract DeployUSDeZkSync is ZkSyncScript {
function run() external broadcast {
new PriceCapAdapterStable{salt: 'capo'}(
abi.decode(
CapAdaptersCodeZkSync.USDeAdapterParams(),
(IPriceCapAdapterStable.CapAdapterStableParams)
)
);
}
}
2 changes: 1 addition & 1 deletion src/contracts/CLRatePriceCapAdapter.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.19;
pragma solidity 0.8.20;

import {IACLManager} from 'aave-address-book/AaveV3.sol';
import {IChainlinkAggregator} from 'cl-synchronicity-price-adapter/interfaces/IChainlinkAggregator.sol';
Expand Down
28 changes: 20 additions & 8 deletions tests/BaseStableTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {IACLManager, BasicIACLManager} from 'aave-address-book/AaveV3.sol';
import {GovV3Helpers} from 'aave-helpers/GovV3Helpers.sol';
import {IPriceCapAdapterStable, ICLSynchronicityPriceAdapter} from '../src/interfaces/IPriceCapAdapterStable.sol';
import {BlockUtils} from './utils/BlockUtils.sol';
import {PriceCapAdapterStable} from '../src/contracts/PriceCapAdapterStable.sol';

abstract contract BaseStableTest is Test {
uint256 public constant RETROSPECTIVE_STEP = 3;
Expand All @@ -19,25 +20,28 @@ abstract contract BaseStableTest is Test {

ForkParams public forkParams;
bytes public deploymentCode;
bytes public adapterParams;

constructor(
bytes memory _deploymentCode,
bytes memory _deploymentCodeOrParams,
uint8 _retrospectiveDays,
ForkParams memory _forkParams
) {
forkParams = _forkParams;
deploymentCode = _deploymentCode;
RETROSPECTIVE_DAYS = _retrospectiveDays;
if (keccak256(bytes(_forkParams.network)) == keccak256(bytes('zksync'))) {
adapterParams = _deploymentCodeOrParams;
} else {
deploymentCode = _deploymentCodeOrParams;
}
}

function setUp() public {
vm.createSelectFork(vm.rpcUrl(forkParams.network), forkParams.blockNumber);
}

function test_latestAnswer() public virtual {
IPriceCapAdapterStable adapter = IPriceCapAdapterStable(
GovV3Helpers.deployDeterministic(deploymentCode)
);
IPriceCapAdapterStable adapter = _createAdapter();

int256 price = adapter.latestAnswer();
int256 referencePrice = adapter.ASSET_TO_USD_AGGREGATOR().latestAnswer();
Expand All @@ -57,9 +61,7 @@ abstract contract BaseStableTest is Test {
);
vm.createSelectFork(vm.rpcUrl(forkParams.network), currentBlock);

IPriceCapAdapterStable adapter = IPriceCapAdapterStable(
GovV3Helpers.deployDeterministic(deploymentCode)
);
IPriceCapAdapterStable adapter = _createAdapter();

// persist adapter
vm.makePersistent(address(adapter));
Expand All @@ -82,4 +84,14 @@ abstract contract BaseStableTest is Test {
vm.revokePersistent(address(adapter));
vm.createSelectFork(vm.rpcUrl(forkParams.network), finishBlock);
}

function _createAdapter() internal returns (IPriceCapAdapterStable) {
if (keccak256(bytes(forkParams.network)) == keccak256(bytes('zksync'))) {
return
new PriceCapAdapterStable{salt: 'test'}(
abi.decode(adapterParams, (IPriceCapAdapterStable.CapAdapterStableParams))
);
}
return IPriceCapAdapterStable(GovV3Helpers.deployDeterministic(deploymentCode));
}
}
Loading

0 comments on commit 9e8584b

Please sign in to comment.