Skip to content

Commit

Permalink
feat: rsETH L2 adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
ianflexa committed Feb 17, 2025
1 parent 9a01d9c commit 64549ce
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ deploy-sdai-mainnet :; forge script scripts/DeployEthereum.s.sol:DeploySDaiEther
deploy-sdai-gnosis :; forge script scripts/DeployGnosis.s.sol:DeploySDaiGnosis --rpc-url gnosis $(common-flags)

deploy-rseth-mainnet :; forge script scripts/DeployEthereum.s.sol:DeployRsEthEthereum --rpc-url mainnet $(common-flags)
deploy-rseth-arbitrum :; forge script scripts/DeployArbitrum.s.sol:DeployRsETHArbitrum --rpc-url arbitrum $(common-flags)
deploy-rseth-base :; forge script scripts/DeployBase.s.sol:DeployRsETHBase --rpc-url base $(common-flags)

deploy-ausd-avalanche :; forge script scripts/DeployAvalanche.s.sol:DeployAUSDAvalanche --rpc-url avalanche $(common-flags)

Expand Down
30 changes: 30 additions & 0 deletions scripts/DeployArbitrum.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbi

import {CLRatePriceCapAdapter, IPriceCapAdapter} from '../src/contracts/CLRatePriceCapAdapter.sol';

import {RsETHL2PriceCapAdapter} from '../src/contracts/lst-adapters/RsETHL2PriceCapAdapter.sol';

library CapAdaptersCodeArbitrum {
address public constant weETH_eETH_AGGREGATOR = 0x20bAe7e1De9c596f5F7615aeaa1342Ba99294e12;
address public constant ezETH_ETH_AGGREGATOR = 0x989a480b6054389075CBCdC385C18CfB6FC08186;
address public constant rsETH_LRT_ORACLE = 0x3222d3De5A9a3aB884751828903044CC4ADC627e;

function weETHAdapterCode() internal pure returns (bytes memory) {
return
Expand Down Expand Up @@ -52,6 +55,27 @@ library CapAdaptersCodeArbitrum {
)
);
}

function rsETHAdapterCode() internal pure returns (bytes memory) {
return
abi.encodePacked(
type(RsETHL2PriceCapAdapter).creationCode,
abi.encode(
IPriceCapAdapter.CapAdapterParams({
aclManager: AaveV3Arbitrum.ACL_MANAGER,
baseAggregatorAddress: AaveV3ArbitrumAssets.WETH_ORACLE,
ratioProviderAddress: rsETH_LRT_ORACLE,
pairDescription: 'Capped rsETH / ETH / USD',
minimumSnapshotDelay: 14 days,
priceCapParams: IPriceCapAdapter.PriceCapUpdateParams({
snapshotRatio: 1_035909659684521016,
snapshotTimestamp: 1738578150, // Feb-03-2025
maxYearlyRatioGrowthPercent: 9_83
})
})
)
);
}
}

contract DeployWeEthArbitrum is ArbitrumScript {
Expand All @@ -65,3 +89,9 @@ contract DeployEzEthArbitrum is ArbitrumScript {
GovV3Helpers.deployDeterministic(CapAdaptersCodeArbitrum.ezETHAdapterCode());
}
}

contract DeployRsETHArbitrum is ArbitrumScript {
function run() external broadcast {
GovV3Helpers.deployDeterministic(CapAdaptersCodeArbitrum.rsETHAdapterCode());
}
}
30 changes: 30 additions & 0 deletions scripts/DeployBase.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import {AaveV3Base, AaveV3BaseAssets} from 'aave-address-book/AaveV3Base.sol';

import {CLRatePriceCapAdapter, IPriceCapAdapter} from '../src/contracts/CLRatePriceCapAdapter.sol';

import {RsETHL2PriceCapAdapter} from '../src/contracts/lst-adapters/RsETHL2PriceCapAdapter.sol';

library CapAdaptersCodeBase {
address public constant weETH_eETH_AGGREGATOR = 0x35e9D7001819Ea3B39Da906aE6b06A62cfe2c181;
address public constant ezETH_ETH_AGGREGATOR = 0xC4300B7CF0646F0Fe4C5B2ACFCCC4dCA1346f5d8;
address public constant rsETH_LRT_ORACLE = 0x7781ae9B47FeCaCEAeCc4FcA8d0b6187E3eF9ba7;

function weETHAdapterCode() internal pure returns (bytes memory) {
return
Expand Down Expand Up @@ -52,6 +55,27 @@ library CapAdaptersCodeBase {
)
);
}

function rsETHAdapterCode() internal pure returns (bytes memory) {
return
abi.encodePacked(
type(RsETHL2PriceCapAdapter).creationCode,
abi.encode(
IPriceCapAdapter.CapAdapterParams({
aclManager: AaveV3Base.ACL_MANAGER,
baseAggregatorAddress: AaveV3BaseAssets.WETH_ORACLE,
ratioProviderAddress: rsETH_LRT_ORACLE,
pairDescription: 'Capped rsETH / ETH / USD',
minimumSnapshotDelay: 14 days,
priceCapParams: IPriceCapAdapter.PriceCapUpdateParams({
snapshotRatio: 1035909659684521016,
snapshotTimestamp: 1738564013, // Feb-03-2025
maxYearlyRatioGrowthPercent: 9_83
})
})
)
);
}
}

contract DeployWeEthBase is BaseScript {
Expand All @@ -65,3 +89,9 @@ contract DeployEzEthBase is BaseScript {
GovV3Helpers.deployDeterministic(CapAdaptersCodeBase.ezETHAdapterCode());
}
}

contract DeployRsETHBase is BaseScript {
function run() external broadcast {
GovV3Helpers.deployDeterministic(CapAdaptersCodeBase.rsETHAdapterCode());
}
}
48 changes: 48 additions & 0 deletions src/contracts/lst-adapters/RsETHL2PriceCapAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.19;

import {PriceCapAdapterBase, IPriceCapAdapter} from '../PriceCapAdapterBase.sol';

import {IRsETHL2} from '../../interfaces/IRsETHL2.sol';

/**
* @title RsETHL2PriceCapAdapter
* @author BGD Labs
* @notice Price capped adapter to calculate price of (rsETH / USD) pair by using
* @notice Chainlink data feed for (ETH / USD) and (rsETH / ETH) ratio.
* @dev IMPORTANT: This adapter uses the exchange rate bridged via LayerZero using the multi-chain rate provider adapter at 0x0788906B19bA8f8d0e8a7015f0714DF3179D9aB6
* fetching the exchange rate from the rsETH Oracle.
* In the L1 rsETH Oracle The `rsETHPrice()` function called in the `RATIO_PROVIDER` is a storage variable that updates the exchange rate for rsETH.
* This variable is updated via the `updateRSETHPrice` function, which internally calculates using the formula: `staked assets value in ETH / rsETH.totalSupply()`.
* To calculate the staked assets value in ETH, the `getTotalAssetDeposits()` function is called in the rsETH DepositPool contract(0x036676389e48133B63a802f8635AD39E752D375D).
* It internally calls the `getAssetDistributionData(asset)` to obtain the balances via the `asset.balanceOf()` function, meaning that the exchange rate of rsETH can be
* manipulated by inflating its price via the donation of these assets. But it's understood that, exclusively in this case, the donations cannot cause a 'completed' manipulation because
* the token donated cannot be rescued after the donation and can be considered as an 'injection of rewards', which would benefit all rsETH shareholders. Also,
* it is important to mention that the Aave Protocol does not allow the rsETH to be borrowed in its system (this restriction has been in place since the asset's listing, but it may/could change in the future if the governance decides otherwise.), which limits any benefit to the attacker from the 'possible'
* manipulation of the exchange rate. Other systems using this oracle should consider and evaluate those risks described here.
* More information can be found in the rsETH discussion in the forum: https://governance.aave.com/t/arfc-add-rseth-to-aave-v3-ethereum/17696/16
*/
contract RsETHL2PriceCapAdapter is PriceCapAdapterBase {
/**
* @param capAdapterParams parameters to create cap adapter
*/
constructor(
CapAdapterParams memory capAdapterParams
)
PriceCapAdapterBase(
CapAdapterBaseParams({
aclManager: capAdapterParams.aclManager,
baseAggregatorAddress: capAdapterParams.baseAggregatorAddress,
ratioProviderAddress: capAdapterParams.ratioProviderAddress,
pairDescription: capAdapterParams.pairDescription,
ratioDecimals: 18,
minimumSnapshotDelay: capAdapterParams.minimumSnapshotDelay,
priceCapParams: capAdapterParams.priceCapParams
})
)
{}

function getRatio() public view override returns (int256) {
return int256(IRsETHL2(RATIO_PROVIDER).rate());
}
}
8 changes: 8 additions & 0 deletions src/interfaces/IRsETHL2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @notice A simple version of the rsETH L2 Oracle allowing to get the rsETH exchange ratio with ETH
interface IRsETHL2 {
/// @notice rsETH:ETH exchange rate
function rate() external view returns (uint256);
}

0 comments on commit 64549ce

Please sign in to comment.