forked from axieinfinity/ronin-dpos-contracts
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(RoninBridgeManager): add test cast vote for adding bridge operators
- Loading branch information
1 parent
0de12b4
commit 381c48f
Showing
8 changed files
with
396 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ src = 'src' | |
out = 'out' | ||
optimizer = true | ||
optimizer_runs = 200 | ||
ffi = true | ||
|
||
libs = [ | ||
'lib', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/** | ||
* @title LibArray | ||
* @dev A library for array-related utility functions in Solidity. | ||
*/ | ||
library LibArray { | ||
/** | ||
* @dev Error indicating a length mismatch between two arrays. | ||
*/ | ||
error LengthMismatch(); | ||
|
||
function toUint256s(uint8[] memory self) internal pure returns (uint256[] memory uint256s) { | ||
assembly ("memory-safe") { | ||
uint256s := self | ||
} | ||
} | ||
|
||
function toUint8sUnsafe(uint256[] memory self) internal pure returns (uint8[] memory uint8s) { | ||
assembly ("memory-safe") { | ||
uint8s := self | ||
} | ||
} | ||
|
||
function arange(uint256 length) internal pure returns (uint256[] memory data) { | ||
data = new uint256[](length); | ||
for (uint256 i; i < length; ++i) { | ||
data[i] = i; | ||
} | ||
} | ||
|
||
/** | ||
* @dev Converts an array of uint256 to an array of bytes32. | ||
* @param self The array of uint256. | ||
* @return bytes32s The resulting array of bytes32. | ||
*/ | ||
function toBytes32s(uint256[] memory self) internal pure returns (bytes32[] memory bytes32s) { | ||
assembly ("memory-safe") { | ||
bytes32s := self | ||
} | ||
} | ||
|
||
function hash(uint256[] memory data) internal pure returns (bytes32 digest) { | ||
assembly ("memory-safe") { | ||
digest := keccak256(add(data, 0x20), mload(data)) | ||
} | ||
} | ||
|
||
/** | ||
* @dev Calculates the sum of an array of uint256 values. | ||
* @param data The array of uint256 values for which the sum is calculated. | ||
* @return result The sum of the provided array of uint256 values. | ||
*/ | ||
function sum(uint256[] memory data) internal pure returns (uint256 result) { | ||
assembly ("memory-safe") { | ||
// Load the length (first 32 bytes) | ||
let len := mload(data) | ||
let dataElementLocation := add(data, 0x20) | ||
|
||
// Iterate until the bound is not met. | ||
for { let end := add(dataElementLocation, mul(len, 0x20)) } lt(dataElementLocation, end) { | ||
dataElementLocation := add(dataElementLocation, 0x20) | ||
} { result := add(result, mload(dataElementLocation)) } | ||
} | ||
} | ||
|
||
/** | ||
* @dev Converts an array of bytes32 to an array of uint256. | ||
* @param self The array of bytes32. | ||
* @return uint256s The resulting array of uint256. | ||
*/ | ||
function toUint256s(bytes32[] memory self) internal pure returns (uint256[] memory uint256s) { | ||
assembly ("memory-safe") { | ||
uint256s := self | ||
} | ||
} | ||
|
||
/** | ||
* @dev Converts an array of uint64 to an array of uint256. | ||
* @param self The array of bytes32. | ||
* @return uint256s The resulting array of uint256. | ||
*/ | ||
function toUint256s(uint64[] memory self) internal pure returns (uint256[] memory uint256s) { | ||
assembly ("memory-safe") { | ||
uint256s := self | ||
} | ||
} | ||
|
||
/** | ||
* @dev Converts an array of address to an array of uint256. | ||
* @param self The array of address. | ||
* @return uint256s The resulting array of uint256. | ||
*/ | ||
function toUint256s(address[] memory self) internal pure returns (uint256[] memory uint256s) { | ||
assembly ("memory-safe") { | ||
uint256s := self | ||
} | ||
} | ||
|
||
/** | ||
* @dev Sorts an array of uint256 values based on a corresponding array of values using the specified sorting mode. | ||
* @param self The array to be sorted. | ||
* @param values The corresponding array of values used for sorting. | ||
* @notice This function modify `self` and `values` | ||
* @return sorted The sorted array. | ||
*/ | ||
function inlineSortByValue(uint256[] memory self, uint256[] memory values) | ||
internal | ||
pure | ||
returns (uint256[] memory sorted) | ||
{ | ||
return inlineQuickSortByValue(self, values); | ||
} | ||
|
||
/** | ||
* @dev Sorts an array of uint256 based on a corresponding array of values. | ||
* @param self The array to be sorted. | ||
* @param values The corresponding array of values used for sorting. | ||
* @notice This function modify `self` and `values` | ||
* @return sorted The sorted array. | ||
*/ | ||
function inlineQuickSortByValue(uint256[] memory self, uint256[] memory values) | ||
internal | ||
pure | ||
returns (uint256[] memory sorted) | ||
{ | ||
uint256 length = self.length; | ||
if (length != values.length) revert LengthMismatch(); | ||
unchecked { | ||
if (length > 1) inlineQuickSortByValue(self, values, 0, int256(length - 1)); | ||
} | ||
|
||
assembly ("memory-safe") { | ||
sorted := self | ||
} | ||
} | ||
|
||
/** | ||
* @dev Internal function to perform quicksort on an array of uint256 values based on a corresponding array of values. | ||
* @param arr The array to be sorted. | ||
* @param values The corresponding array of values used for sorting. | ||
* @param left The left index of the subarray to be sorted. | ||
* @param right The right index of the subarray to be sorted. | ||
* @notice This function modify `arr` and `values` | ||
*/ | ||
function inlineQuickSortByValue(uint256[] memory arr, uint256[] memory values, int256 left, int256 right) | ||
private | ||
pure | ||
{ | ||
unchecked { | ||
if (left == right) return; | ||
int256 i = left; | ||
int256 j = right; | ||
uint256 pivot = values[uint256(left + right) >> 1]; | ||
|
||
while (i <= j) { | ||
while (pivot > values[uint256(i)]) ++i; | ||
while (pivot < values[uint256(j)]) --j; | ||
|
||
if (i <= j) { | ||
(arr[uint256(i)], arr[uint256(j)]) = (arr[uint256(j)], arr[uint256(i)]); | ||
(values[uint256(i)], values[uint256(j)]) = (values[uint256(j)], values[uint256(i)]); | ||
++i; | ||
--j; | ||
} | ||
} | ||
|
||
if (left < j) inlineQuickSortByValue(arr, values, left, j); | ||
if (i < right) inlineQuickSortByValue(arr, values, i, right); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
.../bridge/integration/bridge-manager/set-voting/voteBridgeOperator.RoninBridgeManager.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import { console2 as console } from "forge-std/console2.sol"; | ||
import { GlobalProposal } from "@ronin/contracts/libraries/GlobalProposal.sol"; | ||
import { Ballot } from "@ronin/contracts/libraries/Ballot.sol"; | ||
import { ContractType } from "@ronin/contracts/utils/ContractType.sol"; | ||
import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; | ||
import { SignatureConsumer } from "@ronin/contracts/interfaces/consumers/SignatureConsumer.sol"; | ||
import { LibSort } from "solady/utils/LibSort.sol"; | ||
import "../../BaseIntegration.t.sol"; | ||
|
||
contract VoteBridgeOperator_RoninBridgeManager_Test is BaseIntegration_Test { | ||
using LibSort for address[]; | ||
|
||
uint256 _nonce; | ||
uint256 _proposalExpiryDuration; | ||
uint256 _addingOperatorNum; | ||
address[] _addingOperators; | ||
address[] _addingGovernors; | ||
uint96[] _voteWeights; | ||
|
||
address[] _beforeRelayedOperators; | ||
address[] _beforeRelayedGovernors; | ||
|
||
Ballot.VoteType[] _supports; | ||
|
||
function setUp() public virtual override { | ||
super.setUp(); | ||
|
||
_nonce = 1; | ||
_proposalExpiryDuration = 60; | ||
_addingOperatorNum = 3; | ||
|
||
_beforeRelayedOperators = _param.roninBridgeManager.bridgeOperators; | ||
_beforeRelayedGovernors = _param.roninBridgeManager.governors; | ||
|
||
_supports = new Ballot.VoteType[](_beforeRelayedOperators.length); | ||
for (uint256 i; i < _beforeRelayedGovernors.length; i++) { | ||
_supports[i] = Ballot.VoteType.For; | ||
} | ||
|
||
for (uint256 i; i < _addingOperatorNum; i++) { | ||
_addingOperators.push(makeAddr(string.concat("adding-operator", vm.toString(i)))); | ||
_addingGovernors.push(makeAddr(string.concat("adding-governor", vm.toString(i)))); | ||
_voteWeights.push(uint96(uint256(100))); | ||
} | ||
} | ||
|
||
function test_voteBridgeOperators() public { | ||
GlobalProposal.GlobalProposalDetail memory globalProposal = _bridgeAdminInterface.createGlobalProposal({ | ||
expiryTimestamp: block.timestamp + _proposalExpiryDuration, | ||
targetOption: GlobalProposal.TargetOption.BridgeManager, | ||
value: 0, | ||
calldata_: abi.encodeCall(IBridgeManager.addBridgeOperators, (_voteWeights, _addingOperators, _addingGovernors)), | ||
gasAmount: 500_000, | ||
nonce: _nonce | ||
}); | ||
|
||
SignatureConsumer.Signature[] memory signatures = | ||
_bridgeAdminInterface.generateSignaturesGlobal(globalProposal, _param.test.governorPKs); | ||
|
||
vm.prank(_param.roninBridgeManager.governors[0]); | ||
_roninBridgeManager.proposeGlobalProposalStructAndCastVotes(globalProposal, _supports, signatures); | ||
} | ||
} |
Oops, something went wrong.