-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #213 from etherfi-protocol/syko/feature/etherfi_op…
…eration_parameters
- Loading branch information
Showing
3 changed files
with
225 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.13; | ||
|
||
import "forge-std/Script.sol"; | ||
|
||
import "@openzeppelin/contracts/utils/Strings.sol"; | ||
|
||
import "../../src/Liquifier.sol"; | ||
import "../../src/EtherFiRestaker.sol"; | ||
import "../../src/helpers/AddressProvider.sol"; | ||
import "../../src/UUPSProxy.sol"; | ||
import "../../src/helpers/EtherFiOperationParameters.sol"; | ||
|
||
|
||
contract Deploy is Script { | ||
using Strings for string; | ||
AddressProvider public addressProvider; | ||
|
||
function run() external { | ||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
address addressProviderAddress = vm.envAddress("CONTRACT_REGISTRY"); | ||
addressProvider = AddressProvider(addressProviderAddress); | ||
|
||
vm.startBroadcast(deployerPrivateKey); | ||
|
||
bool to_upgrade = true; | ||
|
||
if (to_upgrade) { | ||
EtherFiOperationParameters instance = EtherFiOperationParameters(0xD0Ff8996DB4bDB46870b7E833b7532f484fEad1A); | ||
EtherFiOperationParameters impl = new EtherFiOperationParameters(); | ||
instance.upgradeTo(address(impl)); | ||
} else { | ||
EtherFiOperationParameters impl = new EtherFiOperationParameters(); | ||
UUPSProxy proxy = new UUPSProxy(address(impl), ""); | ||
|
||
EtherFiOperationParameters instance = EtherFiOperationParameters(payable(proxy)); | ||
|
||
instance.updateTagAdmin("ORACLE", 0x566E58ac0F2c4BCaF6De63760C56cC3f825C48f5, true); | ||
instance.updateTagAdmin("EIGENPOD", 0x566E58ac0F2c4BCaF6De63760C56cC3f825C48f5, true); | ||
// instance.updateTagKeyValue("ORACLE", "WITHDRAWAL_TARGET_GAS_PRICE", "12.5"); // 12.5 gwei | ||
// instance.updateTagKeyValue("ORACLE", "TARGET_LIQUIDITY_IN_PERCENT_OF_TVL", "2.0"); // 2.0 % of TVL | ||
// instance.updateTagKeyValue("EIGENPOD", "PROOF_SUBMIT_TARGET_GAS_PRICE", "12.5"); // 12.5 gwei | ||
} | ||
|
||
vm.stopBroadcast(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.13; | ||
|
||
import "@openzeppelin-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol"; | ||
import "@openzeppelin-upgradeable/contracts/access/OwnableUpgradeable.sol"; | ||
|
||
contract EtherFiOperationParameters is UUPSUpgradeable, OwnableUpgradeable { | ||
mapping(string => mapping(address => bool)) public tagAdmins; | ||
mapping(string => mapping(string => string)) public tagKeyValues; | ||
|
||
event UpdatedAdmin(string tag, address admin, bool allowed); | ||
event UpdatedKeyValue(string tag, string key, string old_value, string new_value); | ||
|
||
/// @custom:oz-upgrades-unsafe-allow constructor | ||
constructor() { | ||
_disableInitializers(); | ||
} | ||
|
||
function initialize() external initializer { | ||
__Ownable_init(); | ||
__UUPSUpgradeable_init(); | ||
} | ||
|
||
function updateTagAdmin(string memory tag, address admin, bool allowed) external onlyOwner { | ||
tagAdmins[tag][admin] = allowed; | ||
|
||
emit UpdatedAdmin(tag, admin, allowed); | ||
} | ||
|
||
function updateTagKeyValue(string memory tag, string memory key, string memory value) external onlyAdmin(tag) { | ||
string memory old_value = tagKeyValues[tag][key]; | ||
tagKeyValues[tag][key] = value; | ||
|
||
emit UpdatedKeyValue(tag, key, old_value, value); | ||
} | ||
|
||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} | ||
|
||
function getImplementation() external view returns (address) { | ||
return _getImplementation(); | ||
} | ||
|
||
modifier onlyAdmin(string memory tag) { | ||
require(tagAdmins[tag][msg.sender], "Only admin can call"); | ||
_; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.13; | ||
|
||
import "./TestSetup.sol"; | ||
import "forge-std/Test.sol"; | ||
|
||
import "../src/helpers/EtherFiOperationParameters.sol"; | ||
import "../src/UUPSProxy.sol"; | ||
|
||
contract EtherFiOperationParametersTest is TestSetup { | ||
|
||
EtherFiOperationParameters operationParameters; | ||
address rando1 = address(0x1); // Non-owner account for testing | ||
address rando2 = address(0x2); // Another non-owner account | ||
|
||
function setUp() public { | ||
EtherFiOperationParameters impl = new EtherFiOperationParameters(); | ||
UUPSProxy proxy = new UUPSProxy(address(impl), ""); | ||
|
||
operationParameters = EtherFiOperationParameters(address(proxy)); | ||
operationParameters.initialize(); | ||
} | ||
|
||
function testFuzz_updateTagAdmin( | ||
string calldata tag, | ||
address admin, | ||
bool allowed | ||
) public { | ||
operationParameters.updateTagAdmin(tag, admin, allowed); | ||
assertEq(operationParameters.tagAdmins(tag, admin), allowed); | ||
} | ||
|
||
function testFuzz_updateTagKeyValue( | ||
string calldata tag, | ||
string calldata key, | ||
string calldata value1, | ||
string calldata value2 | ||
) public { | ||
vm.expectRevert(); | ||
operationParameters.updateTagKeyValue(tag, key, value1); | ||
|
||
vm.prank(operationParameters.owner()); | ||
operationParameters.updateTagAdmin(tag, admin, true); | ||
|
||
vm.prank(admin); | ||
operationParameters.updateTagKeyValue(tag, key, value1); | ||
assertEq(operationParameters.tagKeyValues(tag, key), value1); | ||
|
||
vm.prank(admin); | ||
operationParameters.updateTagKeyValue(tag, key, value2); | ||
assertEq(operationParameters.tagKeyValues(tag, key), value2); | ||
} | ||
|
||
// Test that only the owner can call updateTagAdmin | ||
function testFuzz_updateTagAdmin_onlyOwner( | ||
string calldata tag, | ||
address admin, | ||
bool allowed | ||
) public { | ||
vm.prank(rando1); // Attempt to call from a non-owner account | ||
vm.expectRevert("Ownable: caller is not the owner"); | ||
operationParameters.updateTagAdmin(tag, admin, allowed); | ||
|
||
// Owner can successfully call the function | ||
vm.prank(operationParameters.owner()); | ||
operationParameters.updateTagAdmin(tag, admin, allowed); | ||
assertEq(operationParameters.tagAdmins(tag, admin), allowed); | ||
} | ||
|
||
// Test that only an admin can call updateTagKeyValue | ||
function testFuzz_updateTagKeyValue_onlyAdmin( | ||
string calldata tag, | ||
string calldata key, | ||
string calldata value | ||
) public { | ||
// Attempt to call without being an admin | ||
vm.prank(rando1); | ||
vm.expectRevert("Only admin can call"); | ||
operationParameters.updateTagKeyValue(tag, key, value); | ||
|
||
// Assign admin role to rando1 for the tag | ||
vm.prank(operationParameters.owner()); | ||
operationParameters.updateTagAdmin(tag, rando1, true); | ||
|
||
// Alice can now update the key value | ||
vm.prank(rando1); | ||
operationParameters.updateTagKeyValue(tag, key, value); | ||
assertEq(operationParameters.tagKeyValues(tag, key), value); | ||
} | ||
|
||
// Test the updateTagKeyValue function with multiple updates by an admin | ||
function testFuzz_updateTagKeyValue_asAdmin( | ||
string calldata tag, | ||
string calldata key, | ||
string calldata value1, | ||
string calldata value2 | ||
) public { | ||
// Assign admin role to rando2 for the tag | ||
operationParameters.updateTagAdmin(tag, rando2, true); | ||
|
||
// Bob updates the key value | ||
vm.prank(rando2); | ||
operationParameters.updateTagKeyValue(tag, key, value1); | ||
assertEq(operationParameters.tagKeyValues(tag, key), value1); | ||
|
||
// Bob updates the key value again | ||
vm.prank(rando2); | ||
operationParameters.updateTagKeyValue(tag, key, value2); | ||
assertEq(operationParameters.tagKeyValues(tag, key), value2); | ||
} | ||
|
||
// Test that only the owner can upgrade the contract | ||
function test_upgrade_onlyOwner() public { | ||
address newImplementation = address(new EtherFiOperationParameters()); | ||
|
||
// Attempt to upgrade from a non-owner account | ||
vm.prank(rando1); | ||
vm.expectRevert("Ownable: caller is not the owner"); | ||
operationParameters.upgradeTo(newImplementation); | ||
|
||
// Owner upgrades successfully | ||
operationParameters.upgradeTo(newImplementation); | ||
assertEq(operationParameters.getImplementation(), newImplementation); | ||
} | ||
|
||
function test_upgrade() public { | ||
address newImplementation = address(new EtherFiOperationParameters()); | ||
operationParameters.upgradeTo(newImplementation); | ||
assertEq(operationParameters.getImplementation(), newImplementation); | ||
} | ||
} |