Skip to content

Commit

Permalink
Merge pull request #3 from minh-bq/map-AGG-token-v2
Browse files Browse the repository at this point in the history
chore: add scripts to map AGG token
  • Loading branch information
ducthotran2010 authored Dec 21, 2023
2 parents 2c628f0 + 982ab61 commit 610076e
Show file tree
Hide file tree
Showing 11 changed files with 415 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
[submodule "lib/foundry-deployment-kit"]
path = lib/foundry-deployment-kit
url = https://github.com/axieinfinity/foundry-deployment-kit
1 change: 1 addition & 0 deletions lib/foundry-deployment-kit
Submodule foundry-deployment-kit added at e17e26
3 changes: 2 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ hardhat/=node_modules/hardhat/
@ronin/test/=test/
@prb/test/=lib/prb-test/src/
@prb/math/=lib/prb-math/
solady/=lib/solady/src/
solady/=lib/solady/src/
foundry-deployment-kit/=lib/foundry-deployment-kit/script/
1 change: 1 addition & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
source lib/foundry-deployment-kit/run.sh
100 changes: 100 additions & 0 deletions script/20231218-maptoken/20231218-maptoken-mainchain.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { console2 } from "forge-std/console2.sol";
import { StdStyle } from "forge-std/StdStyle.sol";
import { BaseMigration } from "foundry-deployment-kit/BaseMigration.s.sol";
import { RoninBridgeManager } from "@ronin/contracts/ronin/gateway/RoninBridgeManager.sol";
import { IMainchainGatewayV3 } from "@ronin/contracts/interfaces/IMainchainGatewayV3.sol";
import { GlobalProposal } from "@ronin/contracts/libraries/GlobalProposal.sol";
import { Token } from "@ronin/contracts/libraries/Token.sol";
import { Contract } from "../utils/Contract.sol";
import { BridgeMigration } from "../BridgeMigration.sol";
import { Network } from "../utils/Network.sol";
import { Contract } from "../utils/Contract.sol";
import { IGeneralConfigExtended } from "../IGeneralConfigExtended.sol";

contract Migration__20231215_MapTokenMainchain is BridgeMigration {
RoninBridgeManager internal _roninBridgeManager;
address constant _aggRoninToken = address(0x294311a8C37F0744F99EB152c419D4D3D6FEC1C7);
address constant _aggMainchainToken = address(0xFB0489e9753B045DdB35e39c6B0Cc02EC6b99AC5);
address internal _mainchainGatewayV3;

// The decimal of AGG token is 18
uint256 constant _highTierThreshold = 200_000_000 ether;
uint256 constant _lockedThreshold = 800_000_000 ether;
// The MAX_PERCENTAGE is 1_000_000
uint256 constant _unlockFeePercentages = 10;
uint256 constant _dailyWithdrawalLimit = 500_000_000 ether;

function setUp() public override {
super.setUp();

_roninBridgeManager = RoninBridgeManager(_config.getAddressFromCurrentNetwork(Contract.RoninBridgeManager.key()));
_mainchainGatewayV3 = _config.getAddress(
_config.getCompanionNetwork(_config.getNetworkByChainId(block.chainid)).key(),
Contract.MainchainGatewayV3.key()
);
}

function run() public {
address[] memory mainchainTokens = new address[](1);
mainchainTokens[0] = _aggMainchainToken;
address[] memory roninTokens = new address[](1);
roninTokens[0] = _aggRoninToken;
Token.Standard[] memory standards = new Token.Standard[](1);
standards[0] = Token.Standard.ERC20;
uint256[][4] memory thresholds;
// highTierThreshold
thresholds[0] = new uint256[](1);
thresholds[0][0] = _highTierThreshold;
// lockedThreshold
thresholds[1] = new uint256[](1);
thresholds[1][0] = _lockedThreshold;
// unlockFeePercentages
thresholds[2] = new uint256[](1);
thresholds[2][0] = _unlockFeePercentages;
// dailyWithdrawalLimit
thresholds[3] = new uint256[](1);
thresholds[3][0] = _dailyWithdrawalLimit;

// function mapTokensAndThresholds(
// address[] calldata _mainchainTokens,
// address[] calldata _roninTokens,
// Token.Standard[] calldata _standards,
// uint256[][4] calldata _thresholds
// )

bytes memory innerData = abi.encodeCall(IMainchainGatewayV3.mapTokensAndThresholds, (
mainchainTokens,
roninTokens,
standards,
thresholds
));
bytes memory proxyData = abi.encodeWithSignature("functionDelegateCall(bytes)", innerData);

uint256 expiredTime = block.timestamp + 10 days;
address[] memory targets = new address[](1);
targets[0] = _mainchainGatewayV3;
uint256[] memory values = new uint256[](1);
values[0] = 0;
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = proxyData;
uint256[] memory gasAmounts = new uint256[](1);
gasAmounts[0] = 1_000_000;

_verifyMainchainProposalGasAmount(targets, values, calldatas, gasAmounts);

uint256 chainId = _config.getCompanionNetwork(_config.getNetworkByChainId(block.chainid)).chainId();

vm.broadcast(sender());
_roninBridgeManager.propose(
chainId,
expiredTime,
targets,
values,
calldatas,
gasAmounts
);
}
}
74 changes: 74 additions & 0 deletions script/20231218-maptoken/20231218-maptoken-roninchain.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { console2 } from "forge-std/console2.sol";
import { StdStyle } from "forge-std/StdStyle.sol";
import { BaseMigration } from "foundry-deployment-kit/BaseMigration.s.sol";
import { RoninBridgeManager } from "@ronin/contracts/ronin/gateway/RoninBridgeManager.sol";
import { IRoninGatewayV3 } from "@ronin/contracts/interfaces/IRoninGatewayV3.sol";
import { Token } from "@ronin/contracts/libraries/Token.sol";
import { Contract } from "../utils/Contract.sol";
import { BridgeMigration } from "../BridgeMigration.sol";
import { Network } from "../utils/Network.sol";
import { Contract } from "../utils/Contract.sol";
import { IGeneralConfigExtended } from "../IGeneralConfigExtended.sol";

contract Migration__20231215_MapTokenRoninchain is BridgeMigration {
RoninBridgeManager internal _roninBridgeManager;
address constant _aggRoninToken = address(0x294311a8C37F0744F99EB152c419D4D3D6FEC1C7);
address constant _aggMainchainToken = address(0xFB0489e9753B045DdB35e39c6B0Cc02EC6b99AC5);
address internal _roninGatewayV3;

function setUp() public override {
super.setUp();
_roninBridgeManager = RoninBridgeManager(_config.getAddressFromCurrentNetwork(Contract.RoninBridgeManager.key()));
_roninGatewayV3 = _config.getAddressFromCurrentNetwork(Contract.RoninGatewayV3.key());
}

function run() public {
address[] memory roninTokens = new address[](1);
roninTokens[0] = _aggRoninToken;
address[] memory mainchainTokens = new address[](1);
mainchainTokens[0] = _aggMainchainToken;
uint256[] memory chainIds = new uint256[](1);
chainIds[0] = _config.getCompanionNetwork(_config.getNetworkByChainId(block.chainid)).chainId();
Token.Standard[] memory standards = new Token.Standard[](1);
standards[0] = Token.Standard.ERC20;

// function mapTokens(
// address[] calldata _roninTokens,
// address[] calldata _mainchainTokens,
// uint256[] calldata chainIds,
// Token.Standard[] calldata _standards
// )
bytes memory innerData = abi.encodeCall(IRoninGatewayV3.mapTokens, (
roninTokens,
mainchainTokens,
chainIds,
standards
));
bytes memory proxyData = abi.encodeWithSignature("functionDelegateCall(bytes)", innerData);

uint256 expiredTime = block.timestamp + 10 days;
address[] memory targets = new address[](1);
targets[0] = _roninGatewayV3;
uint256[] memory values = new uint256[](1);
values[0] = 0;
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = proxyData;
uint256[] memory gasAmounts = new uint256[](1);
gasAmounts[0] = 1_000_000;

_verifyRoninProposalGasAmount(targets, values, calldatas, gasAmounts);

vm.broadcast(sender());
_roninBridgeManager.propose(
block.chainid,
expiredTime,
targets,
values,
calldatas,
gasAmounts
);
}
}
83 changes: 83 additions & 0 deletions script/BridgeMigration.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { console2 } from "forge-std/console2.sol";
import { BaseMigration } from "foundry-deployment-kit/BaseMigration.s.sol";
import { GeneralConfigExtended } from "./GeneralConfigExtended.sol";
import { RoninBridgeManager } from "@ronin/contracts/ronin/gateway/RoninBridgeManager.sol";
import { ErrorHandler } from "@ronin/contracts/libraries/ErrorHandler.sol";
import { IGeneralConfigExtended } from "./IGeneralConfigExtended.sol";
import { Network } from "./utils/Network.sol";
import { Contract } from "./utils/Contract.sol";
import { DefaultNetwork } from "foundry-deployment-kit/utils/DefaultNetwork.sol";

contract BridgeMigration is BaseMigration {
using ErrorHandler for bool;

error ErrProposalOutOfGas(bytes4 sig, uint256 expectedGas);

IGeneralConfigExtended internal constant _config = IGeneralConfigExtended(address(CONFIG));

function _configByteCode() internal virtual override returns (bytes memory) {
return abi.encodePacked(type(GeneralConfigExtended).creationCode);
}

function _sharedArguments() internal virtual override returns (bytes memory rawArgs) {
return "";
}

function _verifyRoninProposalGasAmount(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
uint256[] memory gasAmounts
) internal {
address roninBridgeManager = _config.getAddressFromCurrentNetwork(Contract.RoninBridgeManager.key());
uint256 snapshotId = vm.snapshot();
vm.startPrank(address(roninBridgeManager));
_verifyProposalGasAmount(roninBridgeManager, targets, values, calldatas, gasAmounts);
vm.stopPrank();
vm.revertTo(snapshotId);
}

function _verifyMainchainProposalGasAmount(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
uint256[] memory gasAmounts
) internal {
_config.createFork(Network.EthMainnet.key());
_config.switchTo(Network.EthMainnet.key());

address mainchainBridgeManager = _config.getAddressFromCurrentNetwork(Contract.MainchainBridgeManager.key());
uint256 snapshotId = vm.snapshot();

vm.startPrank(address(mainchainBridgeManager));
_verifyProposalGasAmount(mainchainBridgeManager, targets, values, calldatas, gasAmounts);
vm.stopPrank();
vm.revertTo(snapshotId);

_config.switchTo(DefaultNetwork.RoninMainnet.key());
}

function _verifyProposalGasAmount(
address bridgeManager,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
uint256[] memory gasAmounts
) private {
for (uint256 i; i < targets.length; i++) {
vm.deal(address(bridgeManager), values[i]);
uint256 gasUsed = gasleft();
(bool success, bytes memory returnOrRevertData) = targets[i].call{value: values[i]}(calldatas[i]);
gasUsed = gasUsed - gasleft();
success.handleRevert(bytes4(calldatas[i]), returnOrRevertData);

console2.log("Call", i, ": gasUsed", gasUsed);
if (gasUsed > gasAmounts[i]) {
revert ErrProposalOutOfGas(bytes4(calldatas[i]), gasUsed);
}
}
}
}
53 changes: 53 additions & 0 deletions script/GeneralConfigExtended.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { console2 as console } from "forge-std/console2.sol";
import { TContract } from "foundry-deployment-kit/types/Types.sol";
import { BaseGeneralConfig } from "foundry-deployment-kit/BaseGeneralConfig.sol";
import { TNetwork } from "foundry-deployment-kit/types/Types.sol";
import { DefaultNetwork } from "foundry-deployment-kit/utils/DefaultNetwork.sol";
import { Network } from "./utils/Network.sol";
import { Contract } from "./utils/Contract.sol";

contract GeneralConfigExtended is BaseGeneralConfig {
constructor() BaseGeneralConfig("", "deployments/") { }

function _setUpNetworks() internal virtual override {
setNetworkInfo(
Network.Goerli.chainId(),
Network.Goerli.key(),
Network.Goerli.chainAlias(),
Network.Goerli.deploymentDir(),
Network.Goerli.envLabel(),
Network.Goerli.explorer()
);
setNetworkInfo(
Network.EthMainnet.chainId(),
Network.EthMainnet.key(),
Network.EthMainnet.chainAlias(),
Network.EthMainnet.deploymentDir(),
Network.EthMainnet.envLabel(),
Network.EthMainnet.explorer()
);
}

function _setUpContracts() internal virtual override {
_mapContractname(Contract.BridgeReward);
_mapContractname(Contract.BridgeSlash);
_mapContractname(Contract.BridgeTracking);
_mapContractname(Contract.RoninBridgeManager);
_mapContractname(Contract.RoninGatewayV3);
_mapContractname(Contract.MainchainBridgeManager);
_mapContractname(Contract.MainchainGatewayV3);
}

function _mapContractname(Contract contractEnum) internal {
_contractNameMap[contractEnum.key()] = contractEnum.name();
}

function getCompanionNetwork(TNetwork network) external pure returns (Network) {
if (network == DefaultNetwork.RoninTestnet.key()) return Network.Goerli;
if (network == DefaultNetwork.RoninMainnet.key()) return Network.EthMainnet;
revert("Network: Unknown companion network");
}
}
17 changes: 17 additions & 0 deletions script/IGeneralConfigExtended.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { IGeneralConfig } from "foundry-deployment-kit/interfaces/IGeneralConfig.sol";
import { TNetwork } from "foundry-deployment-kit/types/Types.sol";
import { Network } from "./utils/Network.sol";

interface IGeneralConfigExtended is IGeneralConfig {
/**
* @dev Returns the companion mainchain network of a roninchain network
*
* Input: roninchain network
* Output: companion mainchain network of roninchain
*
*/
function getCompanionNetwork(TNetwork network) external pure returns (Network);
}
31 changes: 31 additions & 0 deletions script/utils/Contract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { LibString, TContract } from "foundry-deployment-kit/types/Types.sol";

enum Contract {
BridgeReward,
BridgeSlash,
BridgeTracking,
RoninBridgeManager,
RoninGatewayV3,
MainchainBridgeManager,
MainchainGatewayV3
}

using { key, name } for Contract global;

function key(Contract contractEnum) pure returns (TContract) {
return TContract.wrap(LibString.packOne(name(contractEnum)));
}

function name(Contract contractEnum) pure returns (string memory) {
if (contractEnum == Contract.BridgeReward) return "BridgeReward";
if (contractEnum == Contract.BridgeSlash) return "BridgeSlash";
if (contractEnum == Contract.BridgeTracking) return "BridgeTracking";
if (contractEnum == Contract.RoninBridgeManager) return "RoninBridgeManager";
if (contractEnum == Contract.RoninGatewayV3) return "RoninGatewayV3";
if (contractEnum == Contract.MainchainBridgeManager) return "MainchainBridgeManager";
if (contractEnum == Contract.MainchainGatewayV3) return "MainchainGatewayV3";
revert("Contract: Unknown contract");
}
Loading

0 comments on commit 610076e

Please sign in to comment.