Skip to content

Commit c3318fa

Browse files
authored
Remove channel id array (#1)
* feat(.sol): Change channelID array to singular channelID and remove unnecessary functions Signed-off-by: Sophia Koehler <sophia@perun.network> * fix(Assetholder): Remove immutable flag fix(ci.yaml): Add immutable-state to slither exclusion Signed-off-by: Sophia Koehler <sophia@perun.network> --------- Signed-off-by: Sophia Koehler <sophia@perun.network>
1 parent 1410701 commit c3318fa

File tree

7 files changed

+53
-110
lines changed

7 files changed

+53
-110
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
- name: Static analysis
4343
run: |
4444
pip3 install slither-analyzer==0.10.4
45-
slither --exclude solc-version,timestamp,boolean-equality,unimplemented-functions,locked-ether --filter-paths vendor/ .
45+
slither --exclude solc-version,timestamp,boolean-equality,unimplemented-functions,locked-ether,immutable-states --filter-paths vendor/ .
4646
# Alternatively, one can use Docker:
4747
# WORKDIR=/share docker run --rm -v $(pwd):$WORKDIR -w $WORKDIR --entrypoint slither trailofbits/eth-security-toolbox [insert slither parameters here]
4848

contracts/Adjudicator.sol

+14-38
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ contract Adjudicator {
121121
locked[s],
122122
_channel.state
123123
);
124-
require(Channel.areBytes32ArraysEqual(subAlloc.ID, _state.channelID), "invalid sub-channel id");
124+
require(subAlloc.ID == _state.channelID, "invalid sub-channel id");
125125

126126
uint256[] memory _outcome;
127127
(_outcome, nextIndex) = registerRecursive(
@@ -159,10 +159,7 @@ contract Adjudicator {
159159
}
160160

161161
// If registered, require newer version and refutation timeout not passed.
162-
(Dispute memory dispute, bool registered) = getDispute(state.channelID[Channel.findBackendIndex(
163-
state.channelID,
164-
state.outcome.backends
165-
)]);
162+
(Dispute memory dispute, bool registered) = getDispute(state.channelID);
166163
if (registered) {
167164
if (dispute.stateHash == hashState(state)) {
168165
// Skip if same state.
@@ -206,10 +203,7 @@ contract Adjudicator {
206203
uint256 actorIdx,
207204
bytes memory sig
208205
) external {
209-
Dispute storage dispute = requireGetDispute(state.channelID[Channel.findBackendIndex(
210-
state.channelID,
211-
state.outcome.backends
212-
)]);
206+
Dispute storage dispute = requireGetDispute(state.channelID);
213207
if (dispute.phase == uint8(DisputePhase.DISPUTE)) {
214208
// solhint-disable-next-line not-rely-on-time
215209
require(block.timestamp >= dispute.timeout, "timeout not passed");
@@ -292,10 +286,7 @@ contract Adjudicator {
292286
Channel.validateSignatures(params, state, sigs);
293287

294288
// If registered, require not concluded.
295-
(Dispute storage dispute, bool registered) = getDispute(state.channelID[Channel.findBackendIndex(
296-
state.channelID,
297-
state.outcome.backends
298-
)]);
289+
(Dispute storage dispute, bool registered) = getDispute(state.channelID);
299290
if (registered) {
300291
require(
301292
dispute.phase != uint8(DisputePhase.CONCLUDED),
@@ -343,10 +334,7 @@ contract Adjudicator {
343334
Channel.Params memory params,
344335
Channel.State memory state
345336
) internal pure {
346-
require(state.channelID[Channel.findBackendIndex(
347-
state.channelID,
348-
state.outcome.backends
349-
)] == channelID(params), "invalid params");
337+
require(state.channelID == channelID(params), "invalid params");
350338
}
351339

352340
/**
@@ -361,11 +349,7 @@ contract Adjudicator {
361349
Channel.State memory state,
362350
DisputePhase disputePhase
363351
) internal {
364-
uint256 zeroIndex = Channel.findBackendIndex(
365-
state.channelID,
366-
state.outcome.backends
367-
);
368-
(Dispute storage dispute, bool registered) = getDispute(state.channelID[zeroIndex]);
352+
(Dispute storage dispute, bool registered) = getDispute(state.channelID);
369353

370354
dispute.challengeDuration = uint64(params.challengeDuration);
371355
dispute.version = state.version;
@@ -386,7 +370,7 @@ contract Adjudicator {
386370
dispute.timeout = uint64(block.timestamp) + dispute.challengeDuration;
387371
}
388372

389-
setDispute(state.channelID[zeroIndex], dispute);
373+
setDispute(state.channelID, dispute);
390374
}
391375

392376
/**
@@ -465,11 +449,7 @@ contract Adjudicator {
465449
* Reverts if the channel is already concluded.
466450
*/
467451
function concludeSingle(Channel.State memory state) internal {
468-
uint64 zeroIndex = Channel.findBackendIndex(
469-
state.channelID,
470-
state.outcome.backends
471-
);
472-
Dispute storage dispute = requireGetDispute(state.channelID[zeroIndex]);
452+
Dispute storage dispute = requireGetDispute(state.channelID);
473453
require(dispute.stateHash == hashState(state), "invalid state");
474454
require(
475455
dispute.phase != uint8(DisputePhase.CONCLUDED),
@@ -485,7 +465,7 @@ contract Adjudicator {
485465
require(block.timestamp >= dispute.timeout, "timeout not passed yet");
486466
dispute.phase = uint8(DisputePhase.CONCLUDED);
487467

488-
setDispute(state.channelID[zeroIndex], dispute);
468+
setDispute(state.channelID, dispute);
489469
}
490470

491471
/**
@@ -520,7 +500,7 @@ contract Adjudicator {
520500
for (uint256 i = 0; i < locked.length; ++i) {
521501
Channel.SubAlloc memory subAlloc = locked[i];
522502
Channel.State memory subState = subStates[nextIndex++];
523-
require(Channel.areBytes32ArraysEqual(subAlloc.ID, subState.channelID), "invalid subchannel id");
503+
require(subAlloc.ID == subState.channelID, "invalid subchannel id");
524504

525505
uint256[][] memory subOutcome;
526506
(subOutcome, nextIndex) = forceConcludeRecursive(
@@ -546,23 +526,19 @@ contract Adjudicator {
546526
* Reverts if the channel is not registered.
547527
*/
548528
function forceConcludeSingle(Channel.State memory state) internal {
549-
uint64 zeroIndex = Channel.findBackendIndex(
550-
state.channelID,
551-
state.outcome.backends
552-
);
553-
Dispute storage dispute = requireGetDispute(state.channelID[zeroIndex]);
529+
Dispute storage dispute = requireGetDispute(state.channelID);
554530
require(dispute.stateHash == hashState(state), "invalid state");
555531
if (dispute.phase != uint8(DisputePhase.CONCLUDED)) {
556532
dispute.phase = uint8(DisputePhase.CONCLUDED);
557-
setDispute(state.channelID[zeroIndex], dispute);
533+
setDispute(state.channelID, dispute);
558534
}
559535
}
560536

561537
/**
562538
* @dev pushOutcome sets the outcome at the asset holders.
563539
*/
564540
function pushOutcome(
565-
bytes32[] memory channel,
541+
bytes32 channel,
566542
Channel.Asset[] memory assets,
567543
Channel.Participant[] memory participants,
568544
uint256[][] memory outcome
@@ -573,7 +549,7 @@ contract Adjudicator {
573549
if (asset.ethHolder != address(0)) {
574550
// solhint-disable-next-line calls-loop
575551
AssetHolder(asset.ethHolder).setOutcome(
576-
channel[a],
552+
channel,
577553
participants,
578554
outcome[a]
579555
);

contracts/AssetHolder.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ abstract contract AssetHolder {
6161
* @notice Address of the adjudicator contract that can call setOutcome.
6262
* @dev Set by the constructor.
6363
*/
64-
address public immutable adjudicator;
64+
address public adjudicator;
6565

6666
/**
6767
* @notice The onlyAdjudicator modifier specifies functions that can only be called from the adjudicator contract.

contracts/Channel.sol

+3-30
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ library Channel {
3636
}
3737

3838
struct State {
39-
bytes32[] channelID;
39+
bytes32 channelID;
4040
uint64 version;
4141
Allocation outcome;
4242
bytes appData;
@@ -59,7 +59,7 @@ library Channel {
5959

6060
struct SubAlloc {
6161
// ID is the channelID of the subchannel
62-
bytes32[] ID; // solhint-disable-line var-name-mixedcase
62+
bytes32 ID; // solhint-disable-line var-name-mixedcase
6363
// balances holds the total balance of the subchannel of every asset.
6464
uint256[] balances;
6565
// indexMap maps each sub-channel participant to a parent channel
@@ -125,38 +125,11 @@ library Channel {
125125
SubAlloc memory a,
126126
SubAlloc memory b
127127
) internal pure {
128-
require(areBytes32ArraysEqual(a.ID, b.ID), "SubAlloc: unequal ID");
128+
require(a.ID == b.ID, "SubAlloc: unequal ID");
129129
Array.requireEqualUint256Array(a.balances, b.balances);
130130
Array.requireEqualUint16Array(a.indexMap, b.indexMap);
131131
}
132132

133-
// @dev areBytes32ArraysEqual checks if two arrays of bytes32 are equal.
134-
function areBytes32ArraysEqual(bytes32[] memory arr1, bytes32[] memory arr2) internal pure returns (bool) {
135-
if (arr1.length != arr2.length) {
136-
return false;
137-
}
138-
for (uint i = 0; i < arr1.length; ++i) {
139-
if (arr1[i] != arr2[i]) {
140-
return false;
141-
}
142-
}
143-
return true;
144-
}
145-
146-
/**
147-
* @dev findBackendIndex finds out which of the channelIDs corresponds to the ethereum encoded channelID.
148-
* Reverts if none of the channelIDs has a zero backend.
149-
* Optimized for the common case of only one zero backend.
150-
*/
151-
function findBackendIndex(bytes32[] memory channel, uint256[] memory backends) internal pure returns (uint64) {
152-
require(channel.length == backends.length, "Array lengths mismatch");
153-
154-
if (backends[0] == 1) return 0;
155-
if (backends.length > 1 && backends[1] == 1) return 1;
156-
157-
return 0;
158-
}
159-
160133
/// @dev Asserts that a and b are equal.
161134
function requireEqualAsset(Asset memory a, Asset memory b) internal pure {
162135
require(a.chainID == b.chainID, "unequal chainID");

hardhat.config.ts

-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ import "solidity-coverage";
1010
const config: HardhatUserConfig = {
1111
solidity: {
1212
version: "0.8.28",
13-
settings: {
14-
optimizer: {
15-
enabled: true,
16-
runs: 200,
17-
},
18-
},
1913
},
2014
};
2115

0 commit comments

Comments
 (0)