Skip to content

Commit

Permalink
Merge pull request #197 from stabilitydao/sonic
Browse files Browse the repository at this point in the history
💥 Sonic
  • Loading branch information
a17 authored Dec 24, 2024
2 parents 5be853d + 8e4e2eb commit 129faa5
Show file tree
Hide file tree
Showing 66 changed files with 4,456 additions and 52 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ BASE_RPC_URL=
ARBITRUM_RPC_URL=
ETHEREUM_RPC_URL=
REAL_RPC_URL=
SONIC_RPC_URL=
POLYGONSCAN_API_KEY=
BASESCAN_API_KEY=
ARBITRUMSCAN_API_KEY=
ETHERSCAN_API_KEY=
SONICSCAN_API_KEY=
PRIVATE_KEY=
FOUNDRY_PROFILE=lite
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
ARBITRUM_RPC_URL: ${{secrets.ARBITRUM_RPC_URL}}
ETHEREUM_RPC_URL: ${{secrets.ETHEREUM_RPC_URL}}
REAL_RPC_URL: ${{secrets.REAL_RPC_URL}}
SONIC_RPC_URL: ${{secrets.SONIC_RPC_URL}}
id: test

- name: Run Forge coverage
Expand All @@ -53,6 +54,7 @@ jobs:
ARBITRUM_RPC_URL: ${{secrets.ARBITRUM_RPC_URL}}
ETHEREUM_RPC_URL: ${{secrets.ETHEREUM_RPC_URL}}
REAL_RPC_URL: ${{secrets.REAL_RPC_URL}}
SONIC_RPC_URL: ${{secrets.SONIC_RPC_URL}}
id: coverage

- name: Upload coverage lcov report to Codecov
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Platform address.
* **Polygon** [137] `0xb2a0737ef27b5Cc474D24c779af612159b1c3e60` [polygonscan](https://polygonscan.com/address/0xb2a0737ef27b5Cc474D24c779af612159b1c3e60)
* **Base** [8453] `0x7eAeE5CfF17F7765d89F4A46b484256929C62312` [basescan](https://basescan.org/address/0x7eaee5cff17f7765d89f4a46b484256929c62312)
* **Re.al** [111188] `0xB7838d447deece2a9A5794De0f342B47d0c1B9DC` [explorer.re.al](https://explorer.re.al/address/0xB7838d447deece2a9A5794De0f342B47d0c1B9DC)
* **Sonic** [146] `0x4Aca671A420eEB58ecafE83700686a2AD06b20D8` [sonicscan](https://sonicscan.org/address/0x4aca671a420eeb58ecafe83700686a2ad06b20d8)

## Audits

Expand Down
3 changes: 3 additions & 0 deletions chains/ArbitrumLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ library ArbitrumLib {
p.gelatoAutomate = address(0);
p.gelatoMinBalance = 1e16;
p.gelatoDepositAmount = 2e16;
p.fee = 6_000;
p.feeShareVaultManager = 30_000;
p.feeShareStrategyLogic = 30_000;
}

function deployAndSetupInfrastructure(address platform, bool showLog) internal {
Expand Down
3 changes: 3 additions & 0 deletions chains/BaseLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ library BaseLib {
p.gelatoAutomate = address(0);
p.gelatoMinBalance = 1e16;
p.gelatoDepositAmount = 2e16;
p.fee = 6_000;
p.feeShareVaultManager = 30_000;
p.feeShareStrategyLogic = 30_000;
}

function deployAndSetupInfrastructure(address platform, bool showLog) internal {
Expand Down
3 changes: 3 additions & 0 deletions chains/EthereumLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ library EthereumLib {
p.gelatoAutomate = address(0);
p.gelatoMinBalance = 1e18;
p.gelatoDepositAmount = 2e18;
p.fee = 6_000;
p.feeShareVaultManager = 30_000;
p.feeShareStrategyLogic = 30_000;
}

function deployAndSetupInfrastructure(address platform, bool showLog) internal {
Expand Down
3 changes: 3 additions & 0 deletions chains/PolygonLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ library PolygonLib {
p.gelatoAutomate = GELATO_AUTOMATE;
p.gelatoMinBalance = 1e18;
p.gelatoDepositAmount = 2e18;
p.fee = 6_000;
p.feeShareVaultManager = 30_000;
p.feeShareStrategyLogic = 30_000;
}

function deployAndSetupInfrastructure(address platform, bool showLog) internal {
Expand Down
3 changes: 3 additions & 0 deletions chains/RealLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ library RealLib {
p.gelatoAutomate = address(0);
p.gelatoMinBalance = 1e16;
p.gelatoDepositAmount = 2e16;
p.fee = 6_000;
p.feeShareVaultManager = 30_000;
p.feeShareStrategyLogic = 30_000;
}

function deployAndSetupInfrastructure(address platform, bool showLog) internal {
Expand Down
234 changes: 234 additions & 0 deletions chains/SonicLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import "../script/libs/LogDeployLib.sol";
import {IPlatformDeployer} from "../src/interfaces/IPlatformDeployer.sol";
import {IBalancerAdapter} from "../src/interfaces/IBalancerAdapter.sol";
import {CommonLib} from "../src/core/libs/CommonLib.sol";
import {AmmAdapterIdLib} from "../src/adapters/libs/AmmAdapterIdLib.sol";
import {DeployAdapterLib} from "../script/libs/DeployAdapterLib.sol";
import {Api3Adapter} from "../src/adapters/Api3Adapter.sol";
import {IBalancerGauge} from "../src/integrations/balancer/IBalancerGauge.sol";
import {StrategyIdLib} from "../src/strategies/libs/StrategyIdLib.sol";
import {BeetsStableFarm} from "../src/strategies/BeetsStableFarm.sol";
import {StrategyDeveloperLib} from "../src/strategies/libs/StrategyDeveloperLib.sol";

/// @dev Sonic network [chainId: 146] data library
// _____ _
// / ____| (_)
// | (___ ___ _ __ _ ___
// \___ \ / _ \| '_ \| |/ __|
// ____) | (_) | | | | | (__
// |_____/ \___/|_| |_|_|\___|
//
/// @author Alien Deployer (https://github.com/a17)
library SonicLib {
// initial addresses
address public constant MULTISIG = 0xF564EBaC1182578398E94868bea1AbA6ba339652;

// ERC20
// https://docs.soniclabs.com/technology/contract-addresses
address public constant TOKEN_wS = 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38;
address public constant TOKEN_wETH = 0x309C92261178fA0CF748A855e90Ae73FDb79EBc7;
address public constant TOKEN_USDC = 0x29219dd400f2Bf60E5a23d13Be72B486D4038894;
address public constant TOKEN_stS = 0xE5DA20F15420aD15DE0fa650600aFc998bbE3955;
address public constant TOKEN_BEETS = 0x2D0E0814E62D80056181F5cd932274405966e4f0;
address public constant TOKEN_EURC = 0xe715cbA7B5cCb33790ceBFF1436809d36cb17E57;

// AMMs
address public constant POOL_BEETHOVENX_wS_stS = 0x374641076B68371e69D03C417DAc3E5F236c32FA;
address public constant POOL_BEETHOVENX_BEETS_stS = 0x10ac2F9DaE6539E77e372aDB14B1BF8fBD16b3e8;
address public constant POOL_BEETHOVENX_wS_USDC = 0xE93a5fc4Ba77179F6843b30cff33a97d89FF441C;
address public constant POOL_SUSHI_wS_USDC = 0xE72b6DD415cDACeAC76616Df2C9278B33079E0D3;

// Beethoven X
address public constant BEETS_BALANCER_HELPERS = 0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9;
address public constant BEETS_GAUGE_wS_stS = 0x8476F3A8DA52092e7835167AFe27835dC171C133;

// Oracles
address public constant ORACLE_API3_USDC_USD = 0xD3C586Eec1C6C3eC41D276a23944dea080eDCf7f;

//noinspection NoReturn
function platformDeployParams() internal pure returns (IPlatformDeployer.DeployPlatformParams memory p) {
p.multisig = MULTISIG;
p.version = "25.01.0-alpha";
p.buildingPermitToken = address(0);
p.buildingPayPerVaultToken = TOKEN_wS;
p.networkName = "Sonic";
p.networkExtra = CommonLib.bytesToBytes32(abi.encodePacked(bytes3(0xfec160), bytes3(0x000000)));
p.targetExchangeAsset = TOKEN_wS;
p.gelatoAutomate = address(0);
p.gelatoMinBalance = 1e16;
p.gelatoDepositAmount = 2e16;
p.fee = 30_000;
p.feeShareVaultManager = 10_000;
p.feeShareStrategyLogic = 40_000;
}

function deployAndSetupInfrastructure(address platform, bool showLog) internal {
IFactory factory = IFactory(IPlatform(platform).factory());

//region ----- Deployed Platform -----
if (showLog) {
console.log("Deployed Stability platform", IPlatform(platform).platformVersion());
console.log("Platform address: ", platform);
}
//endregion ----- Deployed Platform -----

//region ----- Deploy and setup vault types -----
_addVaultType(factory, VaultTypeLib.COMPOUNDING, address(new CVault()), 10e6);
//endregion ----- Deploy and setup vault types -----

//region ----- Deploy and setup oracle adapters -----
IPriceReader priceReader = PriceReader(IPlatform(platform).priceReader());
// Api3
{
Proxy proxy = new Proxy();
proxy.initProxy(address(new Api3Adapter()));
Api3Adapter adapter = Api3Adapter(address(proxy));
adapter.initialize(platform);
address[] memory assets = new address[](1);
assets[0] = TOKEN_USDC;
address[] memory priceFeeds = new address[](1);
priceFeeds[0] = ORACLE_API3_USDC_USD;
adapter.addPriceFeeds(assets, priceFeeds);
priceReader.addAdapter(address(adapter));
LogDeployLib.logDeployAndSetupOracleAdapter("Api3", address(adapter), showLog);
}
//endregion ----- Deploy and setup oracle adapters -----

//region ----- Deploy AMM adapters -----
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.UNISWAPV3);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.BALANCER_COMPOSABLE_STABLE);
IBalancerAdapter(
IPlatform(platform).ammAdapter(keccak256(bytes(AmmAdapterIdLib.BALANCER_COMPOSABLE_STABLE))).proxy
).setupHelpers(BEETS_BALANCER_HELPERS);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.BALANCER_WEIGHTED);
IBalancerAdapter(IPlatform(platform).ammAdapter(keccak256(bytes(AmmAdapterIdLib.BALANCER_WEIGHTED))).proxy)
.setupHelpers(BEETS_BALANCER_HELPERS);
LogDeployLib.logDeployAmmAdapters(platform, showLog);
//endregion ----- Deploy AMM adapters -----

//region ----- Setup Swapper -----
{
(ISwapper.AddPoolData[] memory bcPools, ISwapper.AddPoolData[] memory pools) = routes();
ISwapper swapper = ISwapper(IPlatform(platform).swapper());
swapper.addBlueChipsPools(bcPools, false);
swapper.addPools(pools, false);
address[] memory tokenIn = new address[](3);
tokenIn[0] = TOKEN_wS;
tokenIn[1] = TOKEN_stS;
tokenIn[2] = TOKEN_BEETS;
uint[] memory thresholdAmount = new uint[](3);
thresholdAmount[0] = 1e10;
thresholdAmount[1] = 1e10;
thresholdAmount[2] = 1e10;
swapper.setThresholds(tokenIn, thresholdAmount);
LogDeployLib.logSetupSwapper(platform, showLog);
}
//endregion ----- Setup Swapper -----

//region ----- Add farms -----
factory.addFarms(farms());
LogDeployLib.logAddedFarms(address(factory), showLog);
//endregion ----- Add farms -----

//region ----- Deploy strategy logics -----
_addStrategyLogic(factory, StrategyIdLib.BEETS_STABLE_FARM, address(new BeetsStableFarm()), true);
LogDeployLib.logDeployStrategies(platform, showLog);
//endregion ----- Deploy strategy logics -----

//region ----- Add DeX aggregators -----
address[] memory dexAggRouter = new address[](1);
dexAggRouter[0] = IPlatform(platform).swapper();
IPlatform(platform).addDexAggregators(dexAggRouter);
//endregion -- Add DeX aggregators -----
}

function routes()
public
pure
returns (ISwapper.AddPoolData[] memory bcPools, ISwapper.AddPoolData[] memory pools)
{
//region ----- BC pools ----
bcPools = new ISwapper.AddPoolData[](2);
bcPools[0] =
_makePoolData(POOL_BEETHOVENX_wS_stS, AmmAdapterIdLib.BALANCER_COMPOSABLE_STABLE, TOKEN_stS, TOKEN_wS);
// bcPools[1] = _makePoolData(POOL_BEETHOVENX_wS_USDC, AmmAdapterIdLib.BALANCER_WEIGHTED, TOKEN_USDC, TOKEN_wS);
bcPools[1] = _makePoolData(POOL_SUSHI_wS_USDC, AmmAdapterIdLib.UNISWAPV3, TOKEN_USDC, TOKEN_wS);
//endregion ----- BC pools ----

//region ----- Pools ----
pools = new ISwapper.AddPoolData[](4);
uint i;
pools[i++] =
_makePoolData(POOL_BEETHOVENX_wS_stS, AmmAdapterIdLib.BALANCER_COMPOSABLE_STABLE, TOKEN_wS, TOKEN_stS);
pools[i++] =
_makePoolData(POOL_BEETHOVENX_wS_stS, AmmAdapterIdLib.BALANCER_COMPOSABLE_STABLE, TOKEN_stS, TOKEN_wS);
pools[i++] = _makePoolData(POOL_BEETHOVENX_BEETS_stS, AmmAdapterIdLib.BALANCER_WEIGHTED, TOKEN_BEETS, TOKEN_stS);
pools[i++] = _makePoolData(POOL_BEETHOVENX_wS_USDC, AmmAdapterIdLib.BALANCER_WEIGHTED, TOKEN_USDC, TOKEN_wS);
//endregion ----- Pools ----
}

function farms() public view returns (IFactory.Farm[] memory _farms) {
_farms = new IFactory.Farm[](1);
uint i;

_farms[i++] = _makeBeetsStableFarm(BEETS_GAUGE_wS_stS);
}

function _makeBeetsStableFarm(address gauge) internal view returns (IFactory.Farm memory) {
IFactory.Farm memory farm;
farm.status = 0;
farm.pool = IBalancerGauge(gauge).lp_token();
farm.strategyLogicId = StrategyIdLib.BEETS_STABLE_FARM;
uint len = IBalancerGauge(gauge).reward_count();
farm.rewardAssets = new address[](len);
for (uint i; i < len; ++i) {
farm.rewardAssets[i] = IBalancerGauge(gauge).reward_tokens(i);
}
farm.addresses = new address[](1);
farm.addresses[0] = gauge;
// farm.addresses[2] = boxManager;
farm.nums = new uint[](0);
farm.ticks = new int24[](0);
return farm;
}

function _makePoolData(
address pool,
string memory ammAdapterId,
address tokenIn,
address tokenOut
) internal pure returns (ISwapper.AddPoolData memory) {
return ISwapper.AddPoolData({pool: pool, ammAdapterId: ammAdapterId, tokenIn: tokenIn, tokenOut: tokenOut});
}

function _addVaultType(IFactory factory, string memory id, address implementation, uint buildingPrice) internal {
factory.setVaultConfig(
IFactory.VaultConfig({
vaultType: id,
implementation: implementation,
deployAllowed: true,
upgradeAllowed: true,
buildingPrice: buildingPrice
})
);
}

function _addStrategyLogic(IFactory factory, string memory id, address implementation, bool farming) internal {
factory.setStrategyLogicConfig(
IFactory.StrategyLogicConfig({
id: id,
implementation: address(implementation),
deployAllowed: true,
upgradeAllowed: true,
farming: farming,
tokenId: type(uint).max
}),
StrategyDeveloperLib.getDeveloper(id)
);
}

function testChainLib() external {}
}
4 changes: 3 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fs_permissions = [{ access = "read-write", path = "./"}]
solc_version = "0.8.23"
gas_limit = "18446744073709551615"
optimizer-runs = 200
evm_version = "Shanghai"
evm_version = "Cancun"

[profile.lite]
optimizer = false
Expand All @@ -27,9 +27,11 @@ base = "${BASE_RPC_URL}"
arbitrum = "${ARBITRUM_RPC_URL}"
ethereum = "${ETHEREUM_RPC_URL}"
real = "${REAL_RPC_URL}"
sonic = "${SONIC_RPC_URL}"

[etherscan]
polygon = { key = "${POLYGONSCAN_API_KEY}", chain = 137 }
base = { key = "${BASESCAN_API_KEY}", chain = 8453 }
arbitrum = { key = "${ARBITRUMSCAN_API_KEY}", chain = 42161 }
ethereum = { key = "${ETHERSCAN_API_KEY}", chain = 1 }
sonic = { key = "${SONICSCAN_API_KEY}", chain = 146, url = "https://api.sonicscan.org/api" }
12 changes: 6 additions & 6 deletions script/base/DeployCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ abstract contract DeployCore {
IPlatform.PlatformSettings({
networkName: p.networkName,
networkExtra: p.networkExtra,
fee: 6_000, // todo pass in args
feeShareVaultManager: 30_000, // todo pass in args
feeShareStrategyLogic: 30_000, // todo pass in args
feeShareEcosystem: 0, // todo pass in args
minInitialBoostPerDay: 30e18, // $30 // todo pass in args
minInitialBoostDuration: 30 * 86400 // 30 days // todo pass in args
fee: p.fee,
feeShareVaultManager: p.feeShareVaultManager,
feeShareStrategyLogic: p.feeShareStrategyLogic,
feeShareEcosystem: 0,
minInitialBoostPerDay: 30e18, // $30
minInitialBoostDuration: 30 * 86400 // 30 days
})
);

Expand Down
18 changes: 18 additions & 0 deletions script/deploy-core/Deploy.Sonic.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import "forge-std/Script.sol";
import "../../chains/SonicLib.sol";
import {DeployCore} from "../base/DeployCore.sol";

contract DeploySonic is Script, DeployCore {
function run() external {
uint deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
address platform = _deployCore(SonicLib.platformDeployParams());
SonicLib.deployAndSetupInfrastructure(platform, false);
vm.stopBroadcast();
}

function testDeploySonic() external {}
}
Loading

0 comments on commit 129faa5

Please sign in to comment.