Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script/map token anima #48

Open
wants to merge 4 commits into
base: testnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../factories/factory-maptoken-mainchain.s.sol";
import "./base-maptoken.s.sol";
import "@ronin/contracts/libraries/Ballot.sol";
import { console2 } from "forge-std/console2.sol";
import { StdStyle } from "forge-std/StdStyle.sol";
import { MainchainBridgeAdminUtils } from "test/helpers/MainchainBridgeAdminUtils.t.sol";
import { SignatureConsumer } from "@ronin/contracts/interfaces/consumers/SignatureConsumer.sol";
import { Proposal } from "@ronin/contracts/libraries/Proposal.sol";
import { MainchainBridgeManager } from "@ronin/contracts/mainchain/MainchainBridgeManager.sol";

contract Migration__20242606_MapTokenAnimaMainchain is Base__MapToken, Factory__MapTokensMainchain {
MainchainBridgeAdminUtils _mainchainProposalUtils;

function setUp() public virtual override {
_mainchainGatewayV3 = 0x06855f31dF1d3D25cE486CF09dB49bDa535D2a9e;
_mainchainBridgeManager = 0x603075B625cc2cf69FbB3546C6acC2451FE792AF;

_governorPKs = new uint256[](4);
_governorPKs[3] = 0x0;
_governorPKs[2] = 0x0;
_governorPKs[0] = 0x0;
_governorPKs[1] = 0x0;

_governors = new address[](4);
_governors[3] = 0xd24D87DDc1917165435b306aAC68D99e0F49A3Fa;
_governors[2] = 0xb033ba62EC622dC54D0ABFE0254e79692147CA26;
_governors[0] = 0x087D08e3ba42e64E3948962dd1371F906D1278b9;
_governors[1] = 0x52ec2e6BBcE45AfFF8955Da6410bb13812F4289F;
}

function _initCaller() internal override(Base__MapToken, Factory__MapTokensMainchain) returns (address) {
return Base__MapToken._initCaller();
}

function _initTokenList() internal override(Base__MapToken, Factory__MapTokensMainchain) 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
// _cheatStorage(_governors);
_relayProposal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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";
import { Proposal } from "@ronin/contracts/libraries/Proposal.sol";

contract Migration__20242606_MapTokenAnimaRoninTestnet is Base__MapToken, Factory__MapTokensRoninchain {
function setUp() public virtual override {
super.setUp();
_governors = new address[](4);
_governors[3] = 0xd24D87DDc1917165435b306aAC68D99e0F49A3Fa;
_governors[2] = 0xb033ba62EC622dC54D0ABFE0254e79692147CA26;
_governors[0] = 0x087D08e3ba42e64E3948962dd1371F906D1278b9;
_governors[1] = 0x52ec2e6BBcE45AfFF8955Da6410bb13812F4289F;
}

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();
}
}
20 changes: 20 additions & 0 deletions script/20240626-maptoken-anima/base-maptoken.s.sol
Original file line number Diff line number Diff line change
@@ -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;
}
}
6 changes: 6 additions & 0 deletions script/20240626-maptoken-anima/caller-configs.s.sol
Original file line number Diff line number Diff line change
@@ -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
}
18 changes: 18 additions & 0 deletions script/20240626-maptoken-anima/maptoken-anima-configs.s.sol
Original file line number Diff line number Diff line change
@@ -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`)
}
}
154 changes: 118 additions & 36 deletions script/factories/factory-maptoken-mainchain.s.sol
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@ronin/contracts/libraries/Ballot.sol";
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 { Proposal } from "@ronin/contracts/libraries/Proposal.sol";
import { LibTokenInfo, TokenStandard } from "@ronin/contracts/libraries/LibTokenInfo.sol";
import { Contract } from "../utils/Contract.sol";
import { Migration } from "../Migration.s.sol";
import { Network } from "../utils/Network.sol";
import { Network, TNetwork } from "../utils/Network.sol";
import { Contract } from "../utils/Contract.sol";
import { IGeneralConfigExtended } from "../interfaces/IGeneralConfigExtended.sol";

import { SignatureConsumer } from "@ronin/contracts/interfaces/consumers/SignatureConsumer.sol";
import { MapTokenInfo } from "../libraries/MapTokenInfo.sol";
import { LibCompanionNetwork } from "script/shared/libraries/LibCompanionNetwork.sol";
import { MainchainBridgeAdminUtils } from "test/helpers/MainchainBridgeAdminUtils.t.sol";
import { MainchainBridgeManager } from "@ronin/contracts/mainchain/MainchainBridgeManager.sol";
import { LibProposal } from "script/shared/libraries/LibProposal.sol";

abstract contract Factory__MapTokensMainchain is Migration {
using LibCompanionNetwork for *;

RoninBridgeManager internal _roninBridgeManager;
address internal _mainchainGatewayV3;
address internal _mainchainBridgeManager;
address private _governor;
address internal _governor;
address[] internal _governors;
uint256[] internal _governorPKs;

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

_roninBridgeManager = RoninBridgeManager(config.getAddressFromCurrentNetwork(Contract.RoninBridgeManager.key()));
Expand All @@ -34,62 +41,137 @@ abstract contract Factory__MapTokensMainchain is Migration {
_governor = _initCaller();
}

function run() public virtual {
_proposeProposal();
}

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();
function _proposeProposal() internal virtual {
Proposal.ProposalDetail memory proposal = _createAndVerifyProposal();

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);
vm.broadcast(_governor);
_roninBridgeManager.propose(
proposal.chainId, proposal.expiryTimestamp, proposal.executor, proposal.targets, proposal.values, proposal.calldatas, proposal.gasAmounts
);
}

function _relayProposal() internal {
Proposal.ProposalDetail memory proposal = _createAndVerifyProposal();

MainchainBridgeAdminUtils mainchainProposalUtils =
new MainchainBridgeAdminUtils(2021, _governorPKs, MainchainBridgeManager(_mainchainBridgeManager), _governors[0]);

Ballot.VoteType[] memory supports_ = new Ballot.VoteType[](_governors.length);
require(_governors.length > 0 && _governors.length == _governorPKs.length, "Invalid governors information");

for (uint256 i; i < _governors.length; ++i) {
supports_[i] = 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);
}

function _createAndVerifyProposal() internal returns (Proposal.ProposalDetail memory proposal) {
(address[] memory mainchainTokens, address[] memory roninTokens, TokenStandard[] memory standards, uint256[][4] memory thresholds) =
_prepareMapTokensAndThresholds();
bytes memory innerData = abi.encodeCall(IMainchainGatewayV3.mapTokensAndThresholds, (mainchainTokens, roninTokens, standards, thresholds));
bytes memory proxyData = abi.encodeWithSignature("functionDelegateCall(bytes)", innerData);

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);

// ================ APERIOS AND YGG ERC-20 ======================
targets[0] = _mainchainGatewayV3;
values[0] = 0;
calldatas[0] = proxyData;
gasAmounts[0] = 1_000_000;

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;
}
uint256 nonce = (block.chainid == 2021 || block.chainid == 2020) ? 0 : MainchainBridgeManager(_mainchainBridgeManager).round(11155111) + 1;

// Verify gas when call from mainchain.
LibProposal.verifyProposalGasAmount(address(_mainchainBridgeManager), targets, values, calldatas, gasAmounts);

// // Verify gas when call from ronin.
// (uint256 companionChainId, TNetwork companionNetwork) = network().companionNetworkData();
// address companionManager = config.getAddress(companionNetwork, Contract.MainchainBridgeManager.key());
// LibProposal.verifyMainchainProposalGasAmount(companionNetwork, companionManager, targets, values, calldatas, gasAmounts);

proposal = Proposal.ProposalDetail({
nonce: nonce,
chainId: block.chainid,
expiryTimestamp: expiredTime,
executor: address(0),
targets: targets,
values: values,
calldatas: calldatas,
gasAmounts: gasAmounts
});
}

function _prepareMapTokensAndThresholds()
internal
returns (address[] memory mainchainTokens, address[] memory roninTokens, TokenStandard[] memory standards, uint256[][4] memory thresholds)
{
// function mapTokensAndThresholds(
// address[] calldata _mainchainTokens,
// address[] calldata _roninTokens,
// TokenStandard[] calldata _standards,
// TokenStandard.ERC20[] calldata _standards,
// uint256[][4] calldata _thresholds
// )
(uint256 N, MapTokenInfo[] memory tokenInfos) = _initTokenList();

bytes memory innerData = abi.encodeCall(IMainchainGatewayV3.mapTokensAndThresholds, (mainchainTokens, roninTokens, standards, thresholds));
mainchainTokens = new address[](N);
roninTokens = new address[](N);
standards = new TokenStandard[](N);

bytes memory proxyData = abi.encodeWithSignature("functionDelegateCall(bytes)", innerData);
thresholds[0] = new uint256[](N);
thresholds[1] = new uint256[](N);
thresholds[2] = new uint256[](N);
thresholds[3] = new uint256[](N);

targets[0] = _mainchainGatewayV3;
values[0] = 0;
calldatas[0] = proxyData;
gasAmounts[0] = 1_000_000;
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;
}
}

// ================ VERIFY AND EXECUTE PROPOSAL ===============
function _cheatStorage(address[] memory governors) internal {
// ================ Cheat Storage ===============

// _verifyMainchainProposalGasAmount(targets, values, calldatas, gasAmounts);
bytes32 governorsSlot = keccak256(abi.encode(0xc648703095712c0419b6431ae642c061f0a105ac2d7c3d9604061ef4ebc38300));
uint256 length = governors.length;
//cheat governors addresses
for (uint256 i; i < length; ++i) {
bytes32 governorSlotId = bytes32(uint256(governorsSlot) + uint256(i));
vm.store(_mainchainBridgeManager, governorSlotId, bytes32(uint256(uint160(governors[i]))));
}
//after cheat
for (uint256 i; i < length; ++i) {
bytes32 governorSlotId = bytes32(uint256(governorsSlot) + uint256(i));
bytes32 afterCheatData = vm.load(_mainchainBridgeManager, bytes32(uint256(governorsSlot) + uint256(i)));

uint256 chainId = network().companionChainId();
assertEq(afterCheatData, bytes32(uint256(uint160(governors[i]))));
}

vm.broadcast(_governor);
_roninBridgeManager.propose(chainId, expiredTime, address(0), targets, values, calldatas, gasAmounts);
//cheat governors weights
bytes32 governorsWeightSlot = bytes32(uint256(0xc648703095712c0419b6431ae642c061f0a105ac2d7c3d9604061ef4ebc38300) + uint256(2));
for (uint256 i; i < length; ++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)));
}
}
Loading
Loading