diff --git a/script/DeployAprOracle.s.sol b/script/DeployAprOracle.s.sol index dd112e3..509a8d2 100644 --- a/script/DeployAprOracle.s.sol +++ b/script/DeployAprOracle.s.sol @@ -6,19 +6,22 @@ import "forge-std/Script.sol"; // Deploy a contract to a deterministic address with create2 contract DeployAprOracle is Script { - Deployer public deployer = Deployer(0x8D85e7c9A4e369E53Acc8d5426aE1568198b0112); + Deployer public deployer = Deployer(0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed); function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); vm.startBroadcast(deployerPrivateKey); + // Encode constructor arguments + bytes memory construct = abi.encode(0x33333333D5eFb92f19a5F94a43456b3cec2797AE); + // Get the bytecode - bytes memory bytecode = abi.encodePacked(vm.getCode("AprOracle.sol:AprOracle")); + bytes memory bytecode = abi.encodePacked(vm.getCode("AprOracle.sol:AprOracle"), construct); // Pick an unique salt - uint256 salt = uint256(keccak256("APR Oracle")); + bytes32 salt = keccak256("APR Oracle"); - address contractAddress = deployer.deploy(bytecode, salt); + address contractAddress = deployer.deployCreate2(salt, bytecode); console.log("Address is ", contractAddress); @@ -27,17 +30,10 @@ contract DeployAprOracle is Script { } contract Deployer { - event Deployed(address addr, uint256 salt); - - function deploy(bytes memory code, uint256 salt) external returns (address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt); - return addr; - } + event ContractCreation(address indexed newContract, bytes32 indexed salt); + + function deployCreate2( + bytes32 salt, + bytes memory initCode + ) public payable returns (address newContract) {} } \ No newline at end of file diff --git a/src/AprOracle/AprOracle.sol b/src/AprOracle/AprOracle.sol index 49d6983..8e4134f 100644 --- a/src/AprOracle/AprOracle.sol +++ b/src/AprOracle/AprOracle.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0 pragma solidity 0.8.18; +import {Governance} from "../utils/Governance.sol"; import {IVault} from "@yearn-vaults/interfaces/IVault.sol"; import {IStrategy} from "@tokenized-strategy/interfaces/IStrategy.sol"; @@ -28,7 +29,7 @@ interface IOracle { * NOTE: All values are just at the specific time called and subject * to change. */ -contract AprOracle { +contract AprOracle is Governance { // Mapping of a strategy to its specific apr oracle. mapping(address => address) public oracles; @@ -36,6 +37,8 @@ contract AprOracle { uint256 internal constant MAX_BPS_EXTENDED = 1_000_000_000_000; uint256 internal constant SECONDS_PER_YEAR = 31_556_952; + constructor(address _governance) Governance(_governance) {} + /** * @notice Get the current APR a strategy is earning. * @dev Will revert if an oracle has not been set for that strategy. @@ -49,17 +52,19 @@ contract AprOracle { * * @param _strategy Address of the strategy to check. * @param _debtChange Positive or negative change in debt. - * @return . The expected APR it will be earning represented as 1e18. + * @return apr The expected APR it will be earning represented as 1e18. */ function getStrategyApr( address _strategy, int256 _debtChange - ) public view virtual returns (uint256) { + ) public view virtual returns (uint256 apr) { // Get the oracle set for this specific strategy. address oracle = oracles[_strategy]; - // Will revert if a oracle is not set. - return IOracle(oracle).aprAfterDebtChange(_strategy, _debtChange); + // Don't revert if a oracle is not set. + if (oracle != address(0)) { + return IOracle(oracle).aprAfterDebtChange(_strategy, _debtChange); + } } /** @@ -79,7 +84,8 @@ contract AprOracle { /** * @notice Set a custom APR `_oracle` for a `_strategy`. - * @dev Can only be called by the management of the `_strategy`. + * @dev Can only be called by the oracle's `governance` or + * management of the `_strategy`. * * The `_oracle` will need to implement the IOracle interface. * @@ -87,7 +93,12 @@ contract AprOracle { * @param _oracle Address of the APR Oracle. */ function setOracle(address _strategy, address _oracle) external virtual { - require(msg.sender == IStrategy(_strategy).management(), "!authorized"); + if (governance != msg.sender) { + require( + msg.sender == IStrategy(_strategy).management(), + "!authorized" + ); + } oracles[_strategy] = _oracle; }