Skip to content
This repository was archived by the owner on Oct 19, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/RateProvider/IComposableStablePool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IComposableStablePool {
function getLastJoinExitData() external view returns (uint256, uint256);

function getRate() external view returns (uint256);
}
6 changes: 6 additions & 0 deletions src/RateProvider/ICurvePool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface ICurvePool {
function lp_price() external view returns (uint256);
}
6 changes: 6 additions & 0 deletions src/RateProvider/ISilo.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface ISilo {
function convertToAssets(uint256 _shares) external view returns (uint256);
}
7 changes: 7 additions & 0 deletions src/RateProvider/ISpectraPrincipalToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface ISpectraPrincipalToken {
function convertToUnderlying(uint256 principalAmount) external view returns (uint256);
function underlying() external view returns (address);
}
19 changes: 19 additions & 0 deletions src/RateProvider/angles-liquid/AnglesLiquidVaultRateProvider.sol
Original file line number Diff line number Diff line change
@@ -1,24 +1,43 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.8.0;

import {FixedPointMathLib} from "../../../lib/solady/src/utils/FixedPointMathLib.sol";
import {IRateProvider} from "../IRateProvider.sol";
import {IERC4626RateProvider} from "./IERC4626RateProvider.sol";
import {ICurvePool} from "../ICurvePool.sol";
import {ISpectraPrincipalToken} from "../ISpectraPrincipalToken.sol";
import {IComposableStablePool} from "../IComposableStablePool.sol";
import {ISilo} from "../ISilo.sol";

contract AnglesLiquidVaultRateProvider is IRateProvider {
error RateProvider__InvalidParam();
using FixedPointMathLib for uint256;

uint256 immutable PRECISION = 1e18;

address immutable WRAPPED_ANGLES_S = 0xfA85Fe5A8F5560e9039C04f2b0a90dE1415aBD70;
address immutable WRAPPED_S = 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38;
address immutable WRAPPED_ANGLES_S_RATE_PROVIDER = 0x2d087C0999223997b77cc33BE5E7E8eC79396cea;
address immutable SPECTRA_LP_WRAPPED_ANGLES_S = 0xEc81ee88906ED712deA0a17A3Cd8A869eBFA89A0;
address immutable SPECTRA_LP_WRAPPED_ANGLES_S_POOL = 0x2386ebDE944e723Ffd9066bE23709444342d2685;
address immutable SPECTRA_PT_WRAPPED_ANGLES_S = 0x032d91C8D301F31025DCeC41008C643e626e80AB;
address immutable BEETS_POOL = 0x374641076B68371e69D03C417DAc3E5F236c32FA; // stS/wS pool
address immutable SILO_BORROWABLE_WS_DEPOSIT_TOKEN = 0x47d8490Be37ADC7Af053322d6d779153689E13C1;

/// @dev hardcode price of WRAPPED_S to PRECISION
function rate(address token) external view returns (uint256) {
if (token == WRAPPED_S) {
return PRECISION;
} else if (token == WRAPPED_ANGLES_S) {
return IERC4626RateProvider(WRAPPED_ANGLES_S_RATE_PROVIDER).getRate();
} else if (token == SPECTRA_LP_WRAPPED_ANGLES_S) {
uint256 lpPrice = ICurvePool(SPECTRA_LP_WRAPPED_ANGLES_S_POOL).lp_price();
uint256 ptPrice = ISpectraPrincipalToken(SPECTRA_PT_WRAPPED_ANGLES_S).convertToUnderlying(1e18);
return lpPrice.mulWad(ptPrice);
} else if (token == BEETS_POOL) {
return IComposableStablePool(BEETS_POOL).getRate();
} else if (token == SILO_BORROWABLE_WS_DEPOSIT_TOKEN) {
return ISilo(SILO_BORROWABLE_WS_DEPOSIT_TOKEN).convertToAssets(1e21);
} else {
revert RateProvider__InvalidParam();
}
Expand Down
134 changes: 73 additions & 61 deletions tests/RateProviders.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,48 @@ address constant GAUNTLET_USDC_PRIME = 0xdd0f28e19C1780eb6396170735D45153D261490
// IRateProvider usdeRateProvider;
// IRateProvider pufEthRateProvider;
// uint256 private constant PRECISION = 1e18;
//

// function setUp() public {
// vm.createSelectFork(vm.rpcUrl("http://127.0.0.1:8545"));
// usdeRateProvider = new EthenaVaultV2RateProvider();
// pufEthRateProvider = new PufEthVaultV2RateProvider();
// }
//

// function test__FetchPufEthPrice() public view {
// uint256 rate = pufEthRateProvider.rate(PUFETH);
// console.log("PUFETH/ETH rate:", rate);
// }
//

// function test__FetchPufEthWstEthLpPrice() public view {
// uint256 rate = pufEthRateProvider.rate(PUFETH_WSTETH_CURVE);
// console.log("WSTETHLP/ETH rate:", rate);
// }
//

// function test__FetchWethPufEthLpPrice() public view {
// uint256 rate = pufEthRateProvider.rate(WETH_PUFETH_CURVE);
// console.log("WETHLP/ETH rate:", rate);
// }
//

// function test__GauntletWethCorePrice() public view {
// uint256 rate = pufEthRateProvider.rate(GAUNTLET_WETH_CORE);
// console.log("GWC share/ETH:", rate);
// }
//

// function test__FetchSusdePrice() public view {
// uint256 rate = usdeRateProvider.rate(SUSDE);
// console.log("SUSDE/USD rate:", rate);
// }
//

// function test__FetchMtEthenaPrice() public view {
// uint256 rate = usdeRateProvider.rate(SDAISUSDE_CURVE);
// console.log("MtEthena/USD rate:", rate);
// }
//

// function test__FetchYptsusdePrice() public view {
// uint256 rate = usdeRateProvider.rate(YPTSUSDE);
// console.log("YPTSUSDE/USD rate:", rate);
// }
//

// function test__FetchGauntletPrimePrice() public view {
// uint256 rate = usdeRateProvider.rate(GAUNTLET_USDC_PRIME);
// console.log("Gauntlet USDC prime share rate:", rate);
Expand All @@ -88,69 +88,81 @@ address constant GAUNTLET_USDC_PRIME = 0xdd0f28e19C1780eb6396170735D45153D261490
// address private constant SWBTCWBTC_CURVE = 0x73e4BeC1A111869F395cBB24F6676826BF86d905;
// address private constant SWBTC = 0x8DB2350D78aBc13f5673A411D4700BCF87864dDE;
// address private constant GAUNTLET_WBTC_CORE = 0x443df5eEE3196e9b2Dd77CaBd3eA76C3dee8f9b2;
//

// address immutable WRAPPED_ANGLES_S = 0xfA85Fe5A8F5560e9039C04f2b0a90dE1415aBD70;
// address immutable WRAPPED_S = 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38;
// address immutable WRAPPED_ANGLES_S_RATE_PROVIDER = 0x2d087C0999223997b77cc33BE5E7E8eC79396cea;
//
// address immutable SPECTRA_LP_WRAPPED_ANGLES_S = 0xEc81ee88906ED712deA0a17A3Cd8A869eBFA89A0;
// address immutable SILO_BORROWABLE_WS_DEPOSIT_TOKEN = 0x47d8490Be37ADC7Af053322d6d779153689E13C1;

// IRateProvider rateProvider;
// IRateProvider sxethRateProvider;
// IRateProvider swbtcRateProvider;
// IRateProvider anglesRateProvider;
//

// function setUp() public {
// vm.createSelectFork(vm.rpcUrl("http://127.0.0.1:8545"));
// vm.createSelectFork(vm.rpcUrl("https://rpc.ankr.com/sonic_mainnet"));
// rateProvider = new AnglesLiquidVaultRateProvider();
// sxethRateProvider = new StakeeaseVaultRateProvider();
// }
//
// function testToken0Price() public view {
// uint256 rate = rateProvider.rate(SUSDE);
// console.log("token0", rate);
// }
//
// function testToken1Price() public view {
// uint256 rate = rateProvider.rate(SDAISUSDE_CURVE);
// console.log("token1", rate);
// }
//
// function testToken2Price() public view {
// uint256 rate = rateProvider.rate(FRAXUSDE_CURVE);
// console.log("token2", rate);
// }
//
// function testToken3Price() public view {
// uint256 rate = rateProvider.rate(USDEDAI_CURVE);
// console.log("token3", rate);
// }
//
// function testToken4Price() public view {
// uint256 rate = rateProvider.rate(USDE_LPT_PENDLE_MARCH2025);
// console.log("token4", rate);
// }
//
// function testInvalidParam() public {
// vm.expectRevert(bytes4(keccak256(bytes("RateProvider__InvalidParam()"))));
// rateProvider.rate(address(0x1));
// }
//
// function testSxeth0() public view {
// uint256 rate = sxethRateProvider.rate(WSXETH);
// console.log(rate);
// }
//
// function testSxeth1() public view {
// uint256 rate = sxethRateProvider.rate(SXETHWETH_CURVE);
// console.log(rate);
// }
//
// function testSPrice() public view {
// uint256 rate = rateProvider.rate(WRAPPED_S);
// console.log(rate);
// }
//
// function testWrappedSPrice() public view {
// uint256 rate = rateProvider.rate(WRAPPED_ANGLES_S);

// function testToken0Price() public view {
// uint256 rate = rateProvider.rate(SUSDE);
// console.log("token0", rate);
// }

// function testToken1Price() public view {
// uint256 rate = rateProvider.rate(SDAISUSDE_CURVE);
// console.log("token1", rate);
// }

// function testToken2Price() public view {
// uint256 rate = rateProvider.rate(FRAXUSDE_CURVE);
// console.log("token2", rate);
// }

// function testToken3Price() public view {
// uint256 rate = rateProvider.rate(USDEDAI_CURVE);
// console.log("token3", rate);
// }

// function testToken4Price() public view {
// uint256 rate = rateProvider.rate(USDE_LPT_PENDLE_MARCH2025);
// console.log("token4", rate);
// }

// function testInvalidParam() public {
// vm.expectRevert(bytes4(keccak256(bytes("RateProvider__InvalidParam()"))));
// rateProvider.rate(address(0x1));
// }

// function testSxeth0() public view {
// uint256 rate = sxethRateProvider.rate(WSXETH);
// console.log(rate);
// }

// function testSxeth1() public view {
// uint256 rate = sxethRateProvider.rate(SXETHWETH_CURVE);
// console.log(rate);
// }

// function testSPrice() public view {
// uint256 rate = rateProvider.rate(WRAPPED_S);
// console.log(rate);
// }

// function testWrappedSPrice() public view {
// uint256 rate = rateProvider.rate(WRAPPED_ANGLES_S);
// console.log(rate);
// }

// function testLPWrappedSPrice() public view {
// uint256 rate = rateProvider.rate(SPECTRA_LP_WRAPPED_ANGLES_S);
// console.log(rate);
// }

// function testSiloPrice() public view {
// uint256 rate = rateProvider.rate(SILO_BORROWABLE_WS_DEPOSIT_TOKEN);
// console.log(rate);
// }
// }
Loading