Skip to content

Commit

Permalink
feat(e2e/admin): added portal fee oracle upgrade action (#2522)
Browse files Browse the repository at this point in the history
This adds an admin command to upgrade the `feeOracle` address on the
OmniPortal contracts to the FeeOracleV2 address.

issue: #1951
  • Loading branch information
Zodomo authored Dec 2, 2024
1 parent 6e0ca93 commit 54f3e71
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 7 deletions.
25 changes: 23 additions & 2 deletions contracts/bindings/admin.go

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions contracts/core/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Admin_Test:test_pause_unpause() (gas: 32315662)
Admin_Test:test_pause_unpause_bridge() (gas: 27345415)
Admin_Test:test_pause_unpause_xcall() (gas: 32269636)
Admin_Test:test_pause_unpause_xsubmit() (gas: 32269343)
Admin_Test:test_upgrade() (gas: 36350837)
Admin_Test:test_pause_unpause() (gas: 33933914)
Admin_Test:test_pause_unpause_bridge() (gas: 28963667)
Admin_Test:test_pause_unpause_xcall() (gas: 33887888)
Admin_Test:test_pause_unpause_xsubmit() (gas: 33887595)
Admin_Test:test_upgrade() (gas: 37969089)
AllocPredeploys_Test:test_num_allocs() (gas: 1181319043)
AllocPredeploys_Test:test_predeploys() (gas: 1181300853)
AllocPredeploys_Test:test_preinstalls() (gas: 1182017269)
Expand Down
22 changes: 22 additions & 0 deletions contracts/core/script/admin/Admin.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Script } from "forge-std/Script.sol";
import { BridgeL1PostUpgradeTest } from "./BridgeL1PostUpgradeTest.sol";
import { BridgeNativePostUpgradeTest } from "./BridgeNativePostUpgradeTest.sol";
import { StakingPostUpgradeTest } from "./StakingPostUpgradeTest.sol";
import { FeeOracleV2PostUpdateTest } from "./FeeOracleV2PostUpdateTest.sol";

/**
* @title Admin
Expand Down Expand Up @@ -382,6 +383,27 @@ contract Admin is Script {
// TODO: add post upgrade tests
}

/**
* @notice Sets the OmniPortal's fee oracle to the new FeeOracleV2 contract.
* @param admin The address of the admin account, owner of the OmniPortal contract.
* @param portal The address of the OmniPortal contract.
* @param newFeeOracle The address of the new FeeOracleV2 contract.
*/
function setPortalFeeOracleV2(address admin, address portal, address newFeeOracle) public {
address oldFeeOracle = OmniPortal(portal).feeOracle();
require(oldFeeOracle != newFeeOracle, "new fee oracle required");

vm.startBroadcast(admin);
OmniPortal(portal).setFeeOracle(newFeeOracle);
vm.stopBroadcast();

require(OmniPortal(portal).feeOracle() == newFeeOracle, "portal assignment failed");
require(FeeOracleV2(newFeeOracle).manager() != address(0), "fee oracle not initialized");
require(FeeOracleV2(newFeeOracle).version() == 2, "fee oracle not FeeOracleV2");

new FeeOracleV2PostUpdateTest().run(newFeeOracle);
}

/**
* @notice Upgrade a proxy contract.
* @param admin The address of the admin account, owner of the proxy admin
Expand Down
95 changes: 95 additions & 0 deletions contracts/core/script/admin/FeeOracleV2PostUpdateTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.24;

import { FeeOracleV2 } from "src/xchain/FeeOracleV2.sol";
import { IFeeOracleV2 } from "src/interfaces/IFeeOracleV2.sol";
import { Test } from "forge-std/Test.sol";
import { VmSafe } from "forge-std/Vm.sol";
import { EnumerableSetLib } from "solady/src/utils/EnumerableSetLib.sol";

contract FeeOracleV2PostUpdateTest is Test {
using EnumerableSetLib for EnumerableSetLib.Uint256Set;

FeeOracleV2 feeOracle;

EnumerableSetLib.Uint256Set testnetChainIds;
EnumerableSetLib.Uint256Set mainnetChainIds;

// Make sure these match the gas token IDs in `lib/contracts/feeoraclev2/gastokens.go`
uint16 constant OMNI = 1;
uint16 constant ETH = 2;

enum Network {
Invalid,
Testnet,
Mainnet
}

function run(address oracle) public {
(VmSafe.CallerMode mode,,) = vm.readCallers();
require(mode == VmSafe.CallerMode.None, "no broadcast");

Network network = _setup(oracle);
_testFeeParams(network);
_testDataCostParams(network);
_testToNativeRateParams();
}

function _setup(address oracle) internal returns (Network) {
feeOracle = FeeOracleV2(oracle);

// Testnet chain ids
testnetChainIds.add(164); // Omni Omega
testnetChainIds.add(17_000); // Ethereum Holesky
testnetChainIds.add(84_532); // Base Sepolia
testnetChainIds.add(421_614); // Arbitrum Sepolia
testnetChainIds.add(11_155_420); // Optimism Sepolia

// Mainnet chain ids
mainnetChainIds.add(1); // Ethereum Mainnet
mainnetChainIds.add(10); // Optimism Mainnet
mainnetChainIds.add(166); // Omni Mainnet
mainnetChainIds.add(8453); // Base Mainnet
mainnetChainIds.add(42_161); // Arbitrum Mainnet

if (testnetChainIds.contains(block.chainid)) {
return Network.Testnet;
} else if (mainnetChainIds.contains(block.chainid)) {
return Network.Mainnet;
} else {
revert("invalid network");
}
}

function _testFeeParams(Network network) internal view {
uint256[] memory chainIds = network == Network.Testnet ? testnetChainIds.values() : mainnetChainIds.values();
for (uint256 i; i < chainIds.length; i++) {
uint64 chainId = uint64(chainIds[i]);
IFeeOracleV2.FeeParams memory feeParams = feeOracle.feeParams(chainId);
assertGt(feeParams.gasToken, 0, "gas token must be set");
assertGt(feeParams.chainId, 0, "chain id must be set");
assertGt(feeParams.gasPrice, 0, "gas price must be set");
assertGt(feeParams.dataCostId, 0, "data cost id must be set");
}
}

function _testDataCostParams(Network network) internal view {
uint256[] memory chainIds = network == Network.Testnet ? testnetChainIds.values() : mainnetChainIds.values();
for (uint256 i; i < chainIds.length; i++) {
uint64 chainId = uint64(chainIds[i]);
IFeeOracleV2.DataCostParams memory dataCostParams = feeOracle.dataCostParams(chainId);
assertGt(dataCostParams.gasToken, 0, "gas token must be set");
assertGt(dataCostParams.id, 0, "data cost id must be set");
assertGt(dataCostParams.gasPrice, 0, "gas price must be set");
assertGt(dataCostParams.gasPerByte, 0, "gas per byte must be set");
}
}

function _testToNativeRateParams() internal view {
uint256 omniNativeRate = feeOracle.tokenToNativeRate(uint16(OMNI));
uint256 ethNativeRate = feeOracle.tokenToNativeRate(uint16(ETH));

assertGt(omniNativeRate, 0, "omni native rate must be set");
assertGt(ethNativeRate, 0, "eth native rate must be set");
}
}
26 changes: 26 additions & 0 deletions e2e/app/admin/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ func UpgradePortalRegistry(ctx context.Context, def app.Definition, cfg Config)
return upgradePortalRegistry(ctx, s, c)
}

// SetPortalFeeOracleV2 upgrades the OmniPortal's FeeOracle to the FeeOracleV2 contract.
func SetPortalFeeOracleV2(ctx context.Context, def app.Definition, cfg Config) error {
return setup(def, cfg).run(ctx, setPortalFeeOracleV2)
}

func upgradePortal(ctx context.Context, s shared, c chain) error {
// TODO: replace if re-initialization is required
initializer := []byte{}
Expand Down Expand Up @@ -313,3 +318,24 @@ func upgradePortalRegistry(ctx context.Context, s shared, c chain) error {

return nil
}

func setPortalFeeOracleV2(ctx context.Context, s shared, c chain) error {
addrs, err := contracts.GetAddresses(ctx, s.testnet.Network)
if err != nil {
return errors.Wrap(err, "get addresses")
}

calldata, err := adminABI.Pack("setPortalFeeOracleV2", s.manager, addrs.Portal, addrs.FeeOracleV2)
if err != nil {
return errors.Wrap(err, "pack calldata")
}

out, err := s.runForge(ctx, c.RPCEndpoint, calldata, s.manager)
if err != nil {
return errors.Wrap(err, "run forge", "out", out)
}

log.Info(ctx, "OmniPortal's FeeOracle upgraded to V2 ✅", "chain", c.Name, "addr", addrs.FeeOracleV2, "out", out)

return nil
}
13 changes: 13 additions & 0 deletions e2e/cmd/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func newAdminCmd(def *app.Definition) *cobra.Command {
newUpgradeBridgeNativeCmd(def, &cfg),
newUpgradeBridgeL1(def, &cfg),
newUpgradePortalRegistryCmd(def, &cfg),
newSetPortalFeeOracleV2Cmd(def, &cfg),
newAllowValidatorsCmd(def, &cfg),
newPlanUpgradeCmd(def, &cfg),
newAdminTestCmd(def),
Expand Down Expand Up @@ -194,6 +195,18 @@ func newUpgradePortalRegistryCmd(def *app.Definition, cfg *admin.Config) *cobra.
return cmd
}

func newSetPortalFeeOracleV2Cmd(def *app.Definition, cfg *admin.Config) *cobra.Command {
cmd := &cobra.Command{
Use: "set-portal-fee-oracle-v2",
Short: "Sets OmniPortal's FeeOracle to the FeeOracleV2 contract.",
RunE: func(cmd *cobra.Command, _ []string) error {
return admin.SetPortalFeeOracleV2(cmd.Context(), *def, *cfg)
},
}

return cmd
}

func newAdminTestCmd(def *app.Definition) *cobra.Command {
cmd := &cobra.Command{
Use: "test",
Expand Down

0 comments on commit 54f3e71

Please sign in to comment.