Skip to content

Changes from internal reviews #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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
10 changes: 8 additions & 2 deletions script/deploy/DeployManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {DeployCoreHoleskyScript} from "./holesky/001_DeployCoreScript.sol";
import {UpgradeHoleskyScript} from "./holesky/002_UpgradeScript.sol";
import {DeployOriginARMProxyScript} from "./sonic/001_DeployOriginARMProxy.sol";
import {DeployOriginARMScript} from "./sonic/002_DeployOriginARM.sol";
import {UpgradeSonicHarvesterScript} from "./sonic/003_UpgradeSonicHarvester.sol";
import {UpgradeOriginARMScript} from "./sonic/003_UpgradeOriginARM.sol";

contract DeployManager is Script {
using stdJson for string;
Expand Down Expand Up @@ -79,7 +79,13 @@ contract DeployManager is Script {
console.log("Deploying Origin ARM");
_runDeployFile(new DeployOriginARMProxyScript());
_runDeployFile(new DeployOriginARMScript(getDeployedAddressInBuild("ORIGIN_ARM")));
_runDeployFile(new UpgradeSonicHarvesterScript(getDeployedAddressInBuild("HARVESTER")));
_runDeployFile(
new UpgradeOriginARMScript(
getDeployedAddressInBuild("HARVESTER"),
getDeployedAddressInBuild("ORIGIN_ARM"),
getDeployedAddressInBuild("SILO_VARLAMORE_S_MARKET")
)
);
} else {
console.log("Skipping deployment (not mainnet)");
}
Expand Down
78 changes: 78 additions & 0 deletions script/deploy/sonic/003_UpgradeOriginARM.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

import "forge-std/console.sol";

import {SonicHarvester} from "contracts/SonicHarvester.sol";
import {OriginARM} from "contracts/OriginARM.sol";
import {SiloMarket} from "contracts/markets/SiloMarket.sol";
import {Proxy} from "contracts/Proxy.sol";
import {Sonic} from "contracts/utils/Addresses.sol";
import {AbstractDeployScript} from "../AbstractDeployScript.sol";

contract UpgradeOriginARMScript is AbstractDeployScript {
string public constant override DEPLOY_NAME = "003_UpgradeOriginARMScriptScript";
bool public constant override proposalExecuted = false;

Proxy public harvesterProxy;
SonicHarvester public harvesterImpl;
Proxy public originARMProxy;
OriginARM public originARMImpl;
Proxy public silo_Varlamore_S_MarketProxy;
SiloMarket public silo_Varlamore_S_MarketImpl;

constructor(address _harvesterProxy, address _originARMProxy, address _silo_Varlamore_S_MarketProxy) {
require(_harvesterProxy != address(0), "Invalid proxy address");
harvesterProxy = Proxy(payable(_harvesterProxy));

require(_originARMProxy != address(0), "Invalid OriginARM proxy address");
originARMProxy = Proxy(payable(_originARMProxy));

require(_silo_Varlamore_S_MarketProxy != address(0), "Invalid Silo Varlamore S proxy address");
silo_Varlamore_S_MarketProxy = Proxy(payable(_silo_Varlamore_S_MarketProxy));
}

function _execute() internal override {
console.log("Deploy:", DEPLOY_NAME);
console.log("------------");

// 1. Deploy the SonicHarvester implementation
harvesterImpl = new SonicHarvester(Sonic.WS);
_recordDeploy("HARVESTER_IMPL", address(harvesterImpl));

// 2. Deploy new Origin ARM implementation
uint256 claimDelay = tenderlyTestnet ? 1 minutes : 10 minutes;
uint256 minSharesToRedeem = 1e7;
int256 allocateThreshold = 1e18;
originARMImpl =
new OriginARM(Sonic.OS, Sonic.WS, Sonic.OS_VAULT, claimDelay, minSharesToRedeem, allocateThreshold);
_recordDeploy("ORIGIN_ARM_IMPL", address(originARMImpl));

// 3. Deploy the Silo market implementation for the Varlamore S Vault
silo_Varlamore_S_MarketImpl =
new SiloMarket(address(originARMProxy), Sonic.SILO_VARLAMORE_S_VAULT, Sonic.SILO_VARLAMORE_S_GAUGE);
_recordDeploy("SILO_VARLAMORE_S_MARKET_IMPL", address(silo_Varlamore_S_MarketImpl));

console.log("Finished deploying", DEPLOY_NAME);
}

function _buildGovernanceProposal() internal override {}

function _fork() internal override {
if (this.isForked()) {
vm.startPrank(Sonic.ADMIN);

// 1. Upgrade SonicHarvester Proxy to the new implementation
harvesterProxy.upgradeTo(address(harvesterImpl));

// 2. Upgrade OriginARM Proxy to the new implementation
originARMProxy.upgradeTo(address(originARMImpl));

// 3. Upgrade SiloMarket Proxy to the new implementation
silo_Varlamore_S_MarketProxy.upgradeTo(address(silo_Varlamore_S_MarketImpl));

vm.stopPrank();
}
}
}
47 changes: 0 additions & 47 deletions script/deploy/sonic/003_UpgradeSonicHarvester.sol

This file was deleted.

22 changes: 13 additions & 9 deletions src/contracts/AbstractARM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,17 @@ abstract contract AbstractARM is OwnableOperable, ERC20Upgradeable {
// Store the updated claimed amount
withdrawsClaimed += SafeCast.toUint128(assets);

// If there is not enough liquidity assets in the ARM, get from the active market
uint256 liquidityInARM = IERC20(liquidityAsset).balanceOf(address(this));
if (assets > liquidityInARM) {
uint256 liquidityFromMarket = assets - liquidityInARM;
// This should work as we have checked earlier the claimable() amount which includes the active market
IERC4626(activeMarket).withdraw(liquidityFromMarket, address(this), address(this));
// If there is not enough liquidity assets in the ARM, get from the active market if one is configured.
// Read the active market address from storage once to save gas.
address activeMarketMem = activeMarket;
if (activeMarketMem != address(0)) {
uint256 liquidityInARM = IERC20(liquidityAsset).balanceOf(address(this));

if (assets > liquidityInARM) {
uint256 liquidityFromMarket = assets - liquidityInARM;
// This should work as we have checked earlier the claimable() amount which includes the active market
IERC4626(activeMarketMem).withdraw(liquidityFromMarket, address(this), address(this));
}
}

// transfer the liquidity asset to the withdrawer
Expand Down Expand Up @@ -644,9 +649,8 @@ abstract contract AbstractARM is OwnableOperable, ERC20Upgradeable {
(uint256 fees, uint256 newAvailableAssets) = _feesAccrued();

// total assets should only go up from the initial deposit amount that is burnt
// but in case of something unforeseen, return MIN_TOTAL_SUPPLY if fees is
// greater than or equal the available assets
if (fees >= newAvailableAssets) return MIN_TOTAL_SUPPLY;
// but in case of something unforeseen, return at least MIN_TOTAL_SUPPLY.
if (fees + MIN_TOTAL_SUPPLY >= newAvailableAssets) return MIN_TOTAL_SUPPLY;

// Remove the performance fee from the available assets
return newAvailableAssets - fees;
Expand Down
9 changes: 7 additions & 2 deletions src/contracts/LidoARM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,13 @@ contract LidoARM is Initializable, AbstractARM {
totalAmountRequested += requestAmount;
}

// Store the reduced amount outstanding from the Lido Withdrawal Queue
lidoWithdrawalQueueAmount -= totalAmountRequested;
// Store the reduced outstanding withdrawals from the Lido Withdrawal Queue
if (lidoWithdrawalQueueAmount < totalAmountRequested) {
// This can happen if a Lido withdrawal request was transferred to the ARM contract
lidoWithdrawalQueueAmount = 0;
} else {
lidoWithdrawalQueueAmount -= totalAmountRequested;
}

// Wrap all the received ETH to WETH.
weth.deposit{value: address(this).balance}();
Expand Down
3 changes: 2 additions & 1 deletion src/contracts/OriginARM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ contract OriginARM is Initializable, AbstractARM {
// Claim the previously requested withdrawals from the Origin Vault.
(, amountClaimed) = IOriginVault(vault).claimWithdrawals(requestIds);

// Store the reduced amount outstanding withdrawals from the Origin Vault
// Store the reduced outstanding withdrawals from the Origin Vault.
// Origin Vault withdrawals are not transferrable so its safe to reduce the amount.
vaultWithdrawalAmount -= amountClaimed;

emit ClaimOriginWithdrawals(requestIds, amountClaimed);
Expand Down
38 changes: 28 additions & 10 deletions src/contracts/markets/SiloMarket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,6 @@ contract SiloMarket is Initializable, Ownable {
_setHarvester(_harvester);
}

/// @notice Get the amount of Silo Market shares owned by this contract.
/// @param owner The owner has to be the address of the ARM contract.
/// @return shares The amount of Silo lending market shares owned by this contract.
function balanceOf(address owner) external view returns (uint256) {
if (owner != arm) return 0;

// Get the balance of shares in the lending market
return IERC4626(market).balanceOf(address(this));
}

/// @notice Deposit an exact amount of asset tokens to the Silo lending market
/// and mint a variable amount of Silo lending market shares to this contract.
/// @param assets The exact amount of asset tokens to deposit.
Expand Down Expand Up @@ -164,6 +154,34 @@ contract SiloMarket is Initializable, Ownable {
return (tokens, amounts);
}

////////////////////////////////////////////////////
/// View Functions
////////////////////////////////////////////////////

/// @notice Get the amount of Silo Market shares owned by this contract.
/// @param owner The owner has to be the address of the ARM contract.
/// @return shares The amount of Silo lending market shares owned by this contract.
function balanceOf(address owner) external view returns (uint256) {
if (owner != arm) return 0;

// Get the balance of shares in the lending market
return IERC4626(market).balanceOf(address(this));
}

/// @notice The amount of shares that would exchanged for the amount of assets provided.
/// @param assets The amount of asset tokens to convert to shares.
/// @return shares The amount of Silo lending market shares that would be received.
function convertToShares(uint256 assets) external view returns (uint256 shares) {
shares = IERC4626(market).convertToShares(assets);
}

/// @notice The amount of assets that would be exchanged for the amount of shares provided.
/// @param shares The amount of Silo lending market shares to convert to assets.
/// @return assets The amount of asset tokens that would be received.
function convertToAssets(uint256 shares) external view returns (uint256 assets) {
assets = IERC4626(market).convertToAssets(shares);
}

////////////////////////////////////////////////////
/// Admin Functions
////////////////////////////////////////////////////
Expand Down
Loading