From 86643b4f115eb8176b9eeb857f1a8fad82b5a049 Mon Sep 17 00:00:00 2001 From: tringuyenskymavis Date: Wed, 26 Jun 2024 15:46:37 +0700 Subject: [PATCH] script: mapping Anima token --- .../20240626-maptoken-anima-mainchain.s.sol | 20 +++ ...0240626-maptoken-anima-ronin-testnet.s.sol | 21 +++ .../base-maptoken.s.sol | 20 +++ .../caller-configs.s.sol | 6 + .../maptoken-anima-configs.s.sol | 18 +++ .../factory-maptoken-mainchain-testnet.s.sol | 150 ++++++++++++++++++ 6 files changed, 235 insertions(+) create mode 100644 script/20240626-maptoken-anima/20240626-maptoken-anima-mainchain.s.sol create mode 100644 script/20240626-maptoken-anima/20240626-maptoken-anima-ronin-testnet.s.sol create mode 100644 script/20240626-maptoken-anima/base-maptoken.s.sol create mode 100644 script/20240626-maptoken-anima/caller-configs.s.sol create mode 100644 script/20240626-maptoken-anima/maptoken-anima-configs.s.sol create mode 100644 script/factories/factory-maptoken-mainchain-testnet.s.sol diff --git a/script/20240626-maptoken-anima/20240626-maptoken-anima-mainchain.s.sol b/script/20240626-maptoken-anima/20240626-maptoken-anima-mainchain.s.sol new file mode 100644 index 00000000..e39b80e1 --- /dev/null +++ b/script/20240626-maptoken-anima/20240626-maptoken-anima-mainchain.s.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "../factories/factory-maptoken-mainchain-testnet.s.sol"; +import "./base-maptoken.s.sol"; + +contract Migration__20240308_MapTokenAnimaMainchain is Base__MapToken, Factory__MapTokensMainchain_Testnet { + function _initCaller() internal override(Base__MapToken, Factory__MapTokensMainchain_Testnet) returns (address) { + return Base__MapToken._initCaller(); + } + + function _initTokenList() internal override(Base__MapToken, Factory__MapTokensMainchain_Testnet) returns (uint256 totalToken, MapTokenInfo[] memory infos) { + return Base__MapToken._initTokenList(); + } + + function run() public override { + console2.log("nonce", vm.getNonce(SM_GOVERNOR)); // Log nonce for workaround of nonce increase when switch network + super.run(); + } +} diff --git a/script/20240626-maptoken-anima/20240626-maptoken-anima-ronin-testnet.s.sol b/script/20240626-maptoken-anima/20240626-maptoken-anima-ronin-testnet.s.sol new file mode 100644 index 00000000..bf3356b0 --- /dev/null +++ b/script/20240626-maptoken-anima/20240626-maptoken-anima-ronin-testnet.s.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import { console2 } from "forge-std/console2.sol"; +import "../factories/factory-maptoken-roninchain.s.sol"; +import "./base-maptoken.s.sol"; + +contract Migration__20240308_MapTokenAnimaRoninchain is Base__MapToken, Factory__MapTokensRoninchain { + function _initCaller() internal override(Base__MapToken, Factory__MapTokensRoninchain) returns (address) { + return Base__MapToken._initCaller(); + } + + function _initTokenList() internal override(Base__MapToken, Factory__MapTokensRoninchain) returns (uint256 totalToken, MapTokenInfo[] memory infos) { + return Base__MapToken._initTokenList(); + } + + function run() public override { + console2.log("nonce", vm.getNonce(SM_GOVERNOR)); // Log nonce for workaround of nonce increase when switch network + super.run(); + } +} diff --git a/script/20240626-maptoken-anima/base-maptoken.s.sol b/script/20240626-maptoken-anima/base-maptoken.s.sol new file mode 100644 index 00000000..82565522 --- /dev/null +++ b/script/20240626-maptoken-anima/base-maptoken.s.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "forge-std/console2.sol"; + +import "./caller-configs.s.sol"; +import "./maptoken-anima-configs.s.sol"; + +contract Base__MapToken is Migration__Caller_Config, Migration__MapToken_Anima_Config { + function _initCaller() internal virtual returns (address) { + return SM_GOVERNOR; + } + + function _initTokenList() internal virtual returns (uint256 totalToken, MapTokenInfo[] memory infos) { + totalToken = 1; + + infos = new MapTokenInfo[](totalToken); + infos[0] = _animaInfo; + } +} diff --git a/script/20240626-maptoken-anima/caller-configs.s.sol b/script/20240626-maptoken-anima/caller-configs.s.sol new file mode 100644 index 00000000..1e3428d5 --- /dev/null +++ b/script/20240626-maptoken-anima/caller-configs.s.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +contract Migration__Caller_Config { + address internal SM_GOVERNOR = 0xd24D87DDc1917165435b306aAC68D99e0F49A3Fa; // TODO: replace by address of the SV governor +} diff --git a/script/20240626-maptoken-anima/maptoken-anima-configs.s.sol b/script/20240626-maptoken-anima/maptoken-anima-configs.s.sol new file mode 100644 index 00000000..d59329bd --- /dev/null +++ b/script/20240626-maptoken-anima/maptoken-anima-configs.s.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import { MapTokenInfo } from "../libraries/MapTokenInfo.sol"; + +contract Migration__MapToken_Anima_Config { + MapTokenInfo _animaInfo; + + constructor() { + _animaInfo.roninToken = address(0x9F6a5cDc477e9f667d60424bFdb4E82089d9d72c); + _animaInfo.mainchainToken = address(0xEd52E203D2D44FAaEA0D9fB6A40220A63c743c80); + _animaInfo.minThreshold = 100 ether; + _animaInfo.highTierThreshold = 20_000_000 ether; + _animaInfo.lockedThreshold = 100_000_000 ether; + _animaInfo.dailyWithdrawalLimit = 50_000_000 ether; + _animaInfo.unlockFeePercentages = 10; // 0.001%. Max percentage is 100_0000, so 10 is 0.001% (`10 / 1e6 = 0.001 * 100`) + } +} diff --git a/script/factories/factory-maptoken-mainchain-testnet.s.sol b/script/factories/factory-maptoken-mainchain-testnet.s.sol new file mode 100644 index 00000000..d16ce76f --- /dev/null +++ b/script/factories/factory-maptoken-mainchain-testnet.s.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import { console2 } from "forge-std/console2.sol"; +import { StdStyle } from "forge-std/StdStyle.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 { LibTokenInfo, TokenStandard } from "@ronin/contracts/libraries/LibTokenInfo.sol"; +import { Contract } from "../utils/Contract.sol"; +import { Migration } from "../Migration.s.sol"; +import "@ronin/contracts/mainchain/MainchainBridgeManager.sol"; +import { Network } from "../utils/Network.sol"; +import { Contract } from "../utils/Contract.sol"; +import { IGeneralConfigExtended } from "../interfaces/IGeneralConfigExtended.sol"; +import { MainchainBridgeAdminUtils } from "test/helpers/MainchainBridgeAdminUtils.t.sol"; +import { SignatureConsumer } from "@ronin/contracts/interfaces/consumers/SignatureConsumer.sol"; +import { MapTokenInfo } from "../libraries/MapTokenInfo.sol"; +import { LibCompanionNetwork } from "script/shared/libraries/LibCompanionNetwork.sol"; + +abstract contract Factory__MapTokensMainchain_Testnet is Migration { + using LibCompanionNetwork for *; + + address internal _mainchainGatewayV3; + address internal _mainchainBridgeManager; + address private _governor; + MainchainBridgeAdminUtils _mainchainProposalUtils; + + function setUp() public override { + super.setUp(); + + _mainchainGatewayV3 = 0x06855f31dF1d3D25cE486CF09dB49bDa535D2a9e; + _mainchainBridgeManager = 0x603075B625cc2cf69FbB3546C6acC2451FE792AF; + _governor = _initCaller(); + } + + function _initCaller() internal virtual returns (address); + function _initTokenList() internal virtual returns (uint256 totalToken, MapTokenInfo[] memory infos); + + function run() public virtual { + (uint256 N, MapTokenInfo[] memory tokenInfos) = _initTokenList(); + + address[] memory mainchainTokens = new address[](N); + address[] memory roninTokens = new address[](N); + TokenStandard[] memory standards = new TokenStandard[](N); + uint256[][4] memory thresholds; + thresholds[0] = new uint256[](N); + thresholds[1] = new uint256[](N); + thresholds[2] = new uint256[](N); + thresholds[3] = new uint256[](N); + + uint256 expiredTime = block.timestamp + 14 days; + address[] memory targets = new address[](1); + uint256[] memory values = new uint256[](1); + bytes[] memory calldatas = new bytes[](1); + uint256[] memory gasAmounts = new uint256[](1); + + // ================ ERC-20 ====================== + + for (uint256 i; i < N; ++i) { + mainchainTokens[i] = tokenInfos[i].mainchainToken; + roninTokens[i] = tokenInfos[i].roninToken; + standards[i] = TokenStandard.ERC20; + thresholds[0][i] = tokenInfos[i].highTierThreshold; + thresholds[1][i] = tokenInfos[i].lockedThreshold; + thresholds[2][i] = tokenInfos[i].unlockFeePercentages; + thresholds[3][i] = tokenInfos[i].dailyWithdrawalLimit; + } + + // function mapTokensAndThresholds( + // address[] calldata _mainchainTokens, + // address[] calldata _roninTokens, + // TokenStandard[] 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); + + targets[0] = _mainchainGatewayV3; + values[0] = 0; + calldatas[0] = proxyData; + gasAmounts[0] = 1_000_000; + + // TODO: Replace with real governors, this is for local simulation only. + uint256[] memory governorPKs = new uint256[](4); + governorPKs[3] = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; + governorPKs[2] = 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6; + governorPKs[0] = 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a; + governorPKs[1] = 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d; + + address[] memory governors = new address[](4); + governors[3] = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; + governors[2] = 0x90F79bf6EB2c4f870365E785982E1f101E93b906; + governors[0] = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; + governors[1] = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; + + // ================ Cheat Storage =============== + + + bytes32 governorsSlot = keccak256(abi.encode(0xc648703095712c0419b6431ae642c061f0a105ac2d7c3d9604061ef4ebc38300)); + + //cheat governors addresses + for (uint256 i; i < 4; ++i) { + bytes32 governorSlotId = bytes32(uint256(governorsSlot) + uint256(i)); + vm.store(_mainchainBridgeManager, governorSlotId, bytes32(uint256(uint160(governors[i])))); + } + //after cheat + for (uint256 i; i < 4; ++i) { + bytes32 governorSlotId = bytes32(uint256(governorsSlot) + uint256(i)); + bytes32 afterCheatData = vm.load(_mainchainBridgeManager, bytes32(uint256(governorsSlot) + uint256(i))); + + assertEq(afterCheatData, bytes32(uint256(uint160(governors[i])))); + } + + //cheat governors weights + bytes32 governorsWeightSlot = bytes32(uint256(0xc648703095712c0419b6431ae642c061f0a105ac2d7c3d9604061ef4ebc38300) + uint256(2)); + for (uint256 i; i < 4; ++i) { + address key = governors[i]; + bytes32 valueSlot = keccak256(abi.encode(key, governorsWeightSlot)); + vm.store(_mainchainBridgeManager, valueSlot, bytes32(uint256(uint96(100)))); + } + bytes32 governorsWeightData = vm.load(_mainchainBridgeManager, keccak256(abi.encode(0x087D08e3ba42e64E3948962dd1371F906D1278b9, governorsWeightSlot))); + + // ================ VERIFY AND EXECUTE PROPOSAL =============== + _mainchainProposalUtils = new MainchainBridgeAdminUtils(2021, governorPKs, MainchainBridgeManager(_mainchainBridgeManager), governors[0]); + + Proposal.ProposalDetail memory proposal = Proposal.ProposalDetail({ + nonce: MainchainBridgeManager(_mainchainBridgeManager).round(11155111) + 1, + chainId: block.chainid, + expiryTimestamp: expiredTime, + executor: address(0), + targets: targets, + values: values, + calldatas: calldatas, + gasAmounts: gasAmounts + }); + + Ballot.VoteType[] memory supports_ = new Ballot.VoteType[](4); + supports_[0] = Ballot.VoteType.For; + supports_[1] = Ballot.VoteType.For; + supports_[2] = Ballot.VoteType.For; + supports_[3] = Ballot.VoteType.For; + + SignatureConsumer.Signature[] memory signatures = _mainchainProposalUtils.generateSignatures(proposal, governorPKs); + vm.broadcast(governors[0]); + MainchainBridgeManager(_mainchainBridgeManager).relayProposal{ gas: 2_000_000 }(proposal, supports_, signatures); + } +}