Skip to content

Commit

Permalink
script: update script and post check
Browse files Browse the repository at this point in the history
  • Loading branch information
TuDo1403 committed Jan 3, 2025
1 parent e3ca7ba commit a30969d
Show file tree
Hide file tree
Showing 14 changed files with 1,182 additions and 183 deletions.
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ ronin-mainnet = "https://api-archived.roninchain.com/rpc"
ronin-testnet = "https://saigon-archive.roninchain.com/rpc"

[dependencies]
"@fdk" = { version = "0.3.1-beta", url = "https://github.com/axieinfinity/foundry-deployment-kit/archive/refs/tags/v0.3.1-beta.zip" }
"@fdk" = { version = "0.3.5-rc", url = "https://github.com/axieinfinity/foundry-deployment-kit/archive/refs/tags/v0.3.5-rc.zip" }
"@openzeppelin" = { version = "4.7.3", url = "https://github.com/OpenZeppelin/openzeppelin-contracts/archive/refs/tags/v4.7.3.zip" }
"@prb-math" = "4.0.3"
"@prb-test" = "0.6.5"
Expand Down
6 changes: 3 additions & 3 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
forge-std/=dependencies/@fdk-0.3.1-beta/dependencies/@forge-std-1.9.1/src/
forge-std/=dependencies/@fdk-0.3.5-rc/dependencies/forge-std-1.9.5/src/
@openzeppelin/=dependencies/@openzeppelin-4.7.3/
hardhat/=node_modules/hardhat/
@ronin/contracts/=src/
@ronin/test/=test/
solady/=dependencies/@fdk-0.3.1-beta/dependencies/@solady-0.0.228/src/
@fdk=dependencies/@fdk-0.3.1-beta/script/
solady/=dependencies/@fdk-0.3.5-rc/dependencies/solady-0.0.228/src/
@fdk=dependencies/@fdk-0.3.5-rc/script/
@prb/math/=lib/prb-math/
@prb/test/=dependencies/@prb-test-0.6.5/src/
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,28 @@ import { DefaultNetwork } from "@fdk/utils/DefaultNetwork.sol";
contract Migration_01_Deploy_PauseEnforcer_And_Gateway is Migrate_Assets_Base {
using LibCompanionNetwork for *;

address private constant _PRV_RON_PAUSE_ENFORCER = 0x2367cD5468c2b3cD18aA74AdB7e14E43426aF837;
address private constant _PRV_ETH_PAUSE_ENFORCER = 0xe514d9DEB7966c8BE0ca922de8a064264eA6bcd4;

address private _ronPauseEnforcer;
address private _ronGatewayV3Logic;

address private _ethPauseEnforcer;
address private _ethGatewayV3Logic;

function run() public virtual {
function run() public virtual override {
super.run();

MigrateConfig memory ronCfg = ronConfig();
MigrateConfig memory ethCfg = ethConfig();

require(ronCfg.prevPauseEnforcer != address(0), "[Ronin] prevPauseEnforcer is required");
require(ronCfg.newPauseEnforcer == address(0), "[Ronin] newPauseEnforcer must be empty");
require(ronCfg.newGatewayLogic == address(0), "[Ronin] newGatewayLogic must be empty");

require(ethCfg.prevPauseEnforcer != address(0), "[Ethereum] prevPauseEnforcer is required");
require(ethCfg.newPauseEnforcer == address(0), "[Ethereum] newPauseEnforcer must be empty");
require(ethCfg.newGatewayLogic == address(0), "[Ethereum] newGatewayLogic must be empty");

address ronGw = loadContract(Contract.RoninGatewayV3.key());
(address[] memory admins, address[] memory sentries) = _getAllSentriesFromPreviousPauseEnforcer(_PRV_RON_PAUSE_ENFORCER);
(address[] memory admins, address[] memory sentries) = _getAllSentriesFromPreviousPauseEnforcer(ronCfg.prevPauseEnforcer);

_ronPauseEnforcer = _deployImmutable(Contract.RoninPauseEnforcer.key(), abi.encode(ronGw, admins, sentries));
_ronGatewayV3Logic = _deployLogic(Contract.RoninGatewayV3.key());
Expand All @@ -38,12 +48,30 @@ contract Migration_01_Deploy_PauseEnforcer_And_Gateway is Migrate_Assets_Base {
(TNetwork prvNetwork, uint256 prvForkId) = switchTo(companionNetwork);

address ethGw = loadContract(Contract.MainchainGatewayV3.key());
(admins, sentries) = _getAllSentriesFromPreviousPauseEnforcer(_PRV_ETH_PAUSE_ENFORCER);
(admins, sentries) = _getAllSentriesFromPreviousPauseEnforcer(ethCfg.prevPauseEnforcer);

_ethPauseEnforcer = _deployImmutable(Contract.MainchainPauseEnforcer.key(), abi.encode(ethGw, admins, sentries));
_ethGatewayV3Logic = _deployLogic(Contract.MainchainGatewayV3.key());

switchBack(prvNetwork, prvForkId);

_saveToConfig();
}

function _saveToConfig() internal {
string memory path = configPath();

require(_ronPauseEnforcer != address(0), "Ronin Pause Enforcer is not deployed");
require(_ronGatewayV3Logic != address(0), "Ronin Gateway Logic is not deployed");

require(_ethPauseEnforcer != address(0), "Ethereum Pause Enforcer is not deployed");
require(_ethGatewayV3Logic != address(0), "Ethereum Gateway Logic is not deployed");

vm.writeJson(vm.toString(_ronPauseEnforcer), path, ".ronin.newPauseEnforcer");
vm.writeJson(vm.toString(_ronGatewayV3Logic), path, ".ronin.newGatewayLogic");

vm.writeJson(vm.toString(_ethPauseEnforcer), path, ".ethereum.newPauseEnforcer");
vm.writeJson(vm.toString(_ethGatewayV3Logic), path, ".ethereum.newGatewayLogic");
}

function _getAllSentriesFromPreviousPauseEnforcer(
Expand All @@ -60,28 +88,4 @@ contract Migration_01_Deploy_PauseEnforcer_And_Gateway is Migrate_Assets_Base {
sentries[i] = AccessControlEnumerable(pauseEnforcer).getRoleMember(keccak256("SENTRY_ROLE"), i);
}
}

function _getRoninMigratorAddress() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getEthereumMigratorAddress() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getRoninGatewayV3Logic() internal view virtual override returns (address) {
return _ronGatewayV3Logic;
}

function _getMainchainGatewayV3Logic() internal view virtual override returns (address) {
return _ethGatewayV3Logic;
}

function _getRoninPauseEnforcer() internal view virtual override returns (address) {
return _ronPauseEnforcer;
}

function _getEthereumPauseEnforcer() internal view virtual override returns (address) {
return _ethPauseEnforcer;
}
}
87 changes: 36 additions & 51 deletions script/20241217-migrate-assets/02_Propose_Upgrades.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,39 +38,9 @@ contract Migration_02_Propose_Upgrades is Migrate_Assets_Base {
IRoninBridgeManager internal _ronBM;
IMainchainBridgeManager internal _ethBM;

function _getProposalExecutor() internal view virtual override returns (address) {
return address(0);
}

function _getProposalProposer() internal view virtual override returns (address) {
return _ronBM.getGovernors()[0];
}

function _getRoninMigratorAddress() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getEthereumMigratorAddress() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getRoninGatewayV3Logic() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getMainchainGatewayV3Logic() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getRoninPauseEnforcer() internal view virtual override returns (address) {
revert("Not implemented");
}

function _getEthereumPauseEnforcer() internal view virtual override returns (address) {
revert("Not implemented");
}
function run() public virtual override {
super.run();

function run() public virtual {
(_companionChainId, _companionNetwork) = network().companionNetworkData();

_expiry = block.timestamp + _DEFAULT_EXPIRY_DURATION;
Expand All @@ -87,19 +57,27 @@ contract Migration_02_Propose_Upgrades is Migrate_Assets_Base {
uint256[] memory values = new uint256[](1);
uint256[] memory gasAmounts = new uint256[](1);

MigrateConfig memory cfg = ethConfig();
(address[] memory tokens, address[] memory recipients, uint64[] memory remoteChainSelectors) = toWhitelistData(cfg.whitelistInfos);

targets[0] = vme.getAddress(_companionNetwork, Contract.MainchainGatewayV3.key());
callDatas[0] = abi.encodeCall(
ITransparentUpgradeableProxyV2.upgradeToAndCall,
(_getMainchainGatewayV3Logic(), abi.encodeWithSignature("initializeV5(address,address)", _getEthereumMigratorAddress(), _getEthereumPauseEnforcer()))
(
cfg.newGatewayLogic,
abi.encodeWithSignature(
"initializeV5(address,address,address[],address[],uint64[])", cfg.migrator, cfg.newPauseEnforcer, tokens, recipients, remoteChainSelectors
)
)
);
values[0] = 0;
gasAmounts[0] = 1_000_000;

LibProposal.verifyMainchainProposalGasAmount(_companionNetwork, address(_ethBM), targets, values, callDatas, gasAmounts);

vm.broadcast(_getProposalProposer());
vm.broadcast(cfg.proposer);
vm.recordLogs();
_ronBM.propose(_companionChainId, _expiry, _getProposalExecutor(), targets, values, callDatas, gasAmounts);
_ronBM.propose(_companionChainId, _expiry, cfg.executor, targets, values, callDatas, gasAmounts);
Vm.Log[] memory recordedLogs = vm.getRecordedLogs();
for (uint256 i; i < recordedLogs.length; ++i) {
if (recordedLogs[i].emitter == address(_ronBM) && recordedLogs[i].topics[0] == IRoninBridgeManager.ProposalCreated.selector) {
Expand All @@ -117,13 +95,16 @@ contract Migration_02_Propose_Upgrades is Migrate_Assets_Base {
uint256[] memory values = new uint256[](1);
uint256[] memory gasAmounts = new uint256[](1);

MigrateConfig memory cfg = ronConfig();
(address[] memory tokens, address[] memory recipients, uint64[] memory remoteChainSelectors) = toWhitelistData(cfg.whitelistInfos);

targets[0] = gw;
callDatas[0] = abi.encodeCall(
ITransparentUpgradeableProxyV2.upgradeToAndCall,
(
_getRoninGatewayV3Logic(),
cfg.newGatewayLogic,
abi.encodeWithSignature(
"initializeV4(address,address,address)", loadContract(Contract.WRON.key()), _getRoninMigratorAddress(), _getRoninPauseEnforcer()
"initializeV4(address,address,address[],address[],uint64[])", cfg.migrator, cfg.newPauseEnforcer, tokens, recipients, remoteChainSelectors
)
)
);
Expand All @@ -132,47 +113,51 @@ contract Migration_02_Propose_Upgrades is Migrate_Assets_Base {

uint256 nonce = _ronBM.round(block.chainid) + 1;
_ronProposal = LibProposal.createProposal(address(_ronBM), nonce, _expiry, targets, values, callDatas, gasAmounts);
_ronProposal.executor = _getProposalExecutor();
_ronProposal.executor = cfg.executor;

vm.broadcast(cfg.proposer);
_ronBM.propose(block.chainid, _expiry, cfg.executor, targets, values, callDatas, gasAmounts);
}

vm.broadcast(_getProposalProposer());
_ronBM.propose(block.chainid, _expiry, _getProposalExecutor(), targets, values, callDatas, gasAmounts);
function postCheck() external {
_postCheck();
}

function _postCheck() internal virtual override {
// Simulate voting for the Ronin proposal
LibProposal.voteFor(_ronBM, _ronProposal);
if (_ronProposal.executor != address(0)) {
vm.prank(_ronProposal.executor);
_ronBM.execute(_ronProposal);
}

// Simulate voting for the Ethereum proposal
uint256 ronSnapshotId = vm.snapshot();
genMockBOs(address(_ronBM));
overrideMockBOs(address(_ronBM));

Signature[] memory sigs = LibProposal.voteForBySignature(_ronBM, _ethProposal, Ballot.VoteType.For);

(TNetwork prvNetwork, uint256 prvForkId) = switchTo(_companionNetwork);

uint256 ethSnapshotId = vm.snapshot();

overrideMockBOs(address(_ethBM));

MigrateConfig memory cfg = ethConfig();

// Cheat re-add executor as bridge operator since we assigned executor as bridge operator in the proposal
address[] memory ops = new address[](1);
ops[0] = makeAddr("cheat-re-added-sm-bo");
uint96[] memory vws = new uint96[](1);
vws[0] = 1;
address[] memory gvs = new address[](1);
gvs[0] = _getProposalExecutor();
// SkyMavis Gnosis Safe
vm.prank(0x51F6696Ae42C6C40CA9F5955EcA2aaaB1Cefb26e);
gvs[0] = cfg.executor;

address pa = LibProxy.getProxyAdmin(address(_ethBM));
vm.prank(pa);
ITransparentUpgradeableProxyV2(address(_ethBM)).functionDelegateCall(abi.encodeCall(IBridgeManager.addBridgeOperators, (vws, gvs, ops)));
vm.prank(_getProposalExecutor());
vm.prank(cfg.executor);
_ethBM.relayProposal(_ethProposal, new Ballot.VoteType[](sigs.length), sigs);

vm.revertTo(ethSnapshotId);

switchBack(prvNetwork, prvForkId);

vm.revertTo(ronSnapshotId);
}

function genMockBOs(
Expand Down
72 changes: 62 additions & 10 deletions script/20241217-migrate-assets/Migrate_Assets_Base.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,77 @@
pragma solidity ^0.8.23;

import { Migration } from "script/Migration.s.sol";
import { Network } from "script/utils/Network.sol";
import { DefaultNetwork } from "@fdk/utils/DefaultNetwork.sol";

abstract contract Migrate_Assets_Base is Migration {
function _getProposalExecutor() internal view virtual returns (address) {
return address(0);
struct WhitelistInfo {
address recipient;
uint64 remoteChainSelector;
address token;
}

function _getProposalProposer() internal view virtual returns (address) {
return address(0);
struct MigrateConfig {
address executor;
address migrator;
address newGatewayLogic;
address newPauseEnforcer;
address prevPauseEnforcer;
address proposer;
WhitelistInfo[] whitelistInfos;
}

function _getRoninMigratorAddress() internal view virtual returns (address);
string private constant CONFIG_PATH = "script/20241217-migrate-assets/config/config";

function _getEthereumMigratorAddress() internal view virtual returns (address);
function run() public virtual {
vm.makePersistent(address(this));
validateConfig(ronConfig());
validateConfig(ethConfig());
}

function configPath() public view returns (string memory) {
if (network() == DefaultNetwork.RoninMainnet.key() || network() == Network.EthMainnet.key()) {
return string.concat(CONFIG_PATH, ".mainnet.json");
} else if (network() == DefaultNetwork.RoninTestnet.key() || network() == Network.Sepolia.key()) {
return string.concat(CONFIG_PATH, ".testnet.json");
} else {
revert("Unsupported network");
}
}

function validateConfig(
MigrateConfig memory cfg
) public pure {
require(cfg.executor != address(0), "executor is required");
require(cfg.migrator != address(0), "migrator is required");
require(cfg.proposer != address(0), "proposer is required");
require(cfg.whitelistInfos.length > 0, "whitelistInfos is required");
}

function _getRoninGatewayV3Logic() internal view virtual returns (address);
function ronConfig() public view returns (MigrateConfig memory) {
return this.parseConfig(vm.readFile(configPath()), ".ronin");
}

function _getMainchainGatewayV3Logic() internal view virtual returns (address);
function ethConfig() public view returns (MigrateConfig memory) {
return this.parseConfig(vm.readFile(configPath()), ".ethereum");
}

function _getRoninPauseEnforcer() internal view virtual returns (address);
function parseConfig(string memory json, string memory key) external pure returns (MigrateConfig memory) {
MigrateConfig memory parsed = abi.decode(vm.parseJson(json, key), (MigrateConfig));
return parsed;
}

function _getEthereumPauseEnforcer() internal view virtual returns (address);
function toWhitelistData(
WhitelistInfo[] memory info
) public pure returns (address[] memory tokens, address[] memory recipients, uint64[] memory remoteChainSelectors) {
tokens = new address[](info.length);
recipients = new address[](info.length);
remoteChainSelectors = new uint64[](info.length);

for (uint256 i; i < info.length; ++i) {
tokens[i] = info[i].token;
recipients[i] = info[i].recipient;
remoteChainSelectors[i] = info[i].remoteChainSelector;
}
}
}
Loading

0 comments on commit a30969d

Please sign in to comment.