85 lines
3.6 KiB
Solidity
85 lines
3.6 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import { Test } from "forge-std/Test.sol";
|
|
import { GenericStateChannelManager } from "../../contracts/channels/GenericStateChannelManager.sol";
|
|
import { IGenericStateChannelManager } from "../../contracts/channels/IGenericStateChannelManager.sol";
|
|
|
|
contract GenericStateChannelManagerTest is Test {
|
|
GenericStateChannelManager public manager;
|
|
address public admin;
|
|
address public alice;
|
|
address public bob;
|
|
uint256 public alicePk;
|
|
uint256 public bobPk;
|
|
uint256 constant CHALLENGE_WINDOW = 1 hours;
|
|
|
|
function _signState(
|
|
uint256 channelId,
|
|
bytes32 stateHash,
|
|
uint256 nonce,
|
|
uint256 balanceA,
|
|
uint256 balanceB,
|
|
uint256 pk
|
|
) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
|
|
bytes32 stateHashInner = keccak256(abi.encodePacked(channelId, stateHash, nonce, balanceA, balanceB));
|
|
bytes32 ethSigned = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", stateHashInner));
|
|
(v, r, s) = vm.sign(pk, ethSigned);
|
|
}
|
|
|
|
function setUp() public {
|
|
admin = address(0x1);
|
|
(alice, alicePk) = makeAddrAndKey("alice");
|
|
(bob, bobPk) = makeAddrAndKey("bob");
|
|
manager = new GenericStateChannelManager(admin, CHALLENGE_WINDOW);
|
|
vm.deal(alice, 100 ether);
|
|
vm.deal(bob, 100 ether);
|
|
}
|
|
|
|
function test_OpenFundCloseCooperative_WithStateHash() public {
|
|
vm.prank(alice);
|
|
uint256 channelId = manager.openChannel{ value: 10 ether }(bob);
|
|
vm.prank(bob);
|
|
manager.fundChannel{ value: 10 ether }(channelId);
|
|
|
|
bytes32 stateHash = keccak256("game-result-v1");
|
|
uint256 balanceA = 12 ether;
|
|
uint256 balanceB = 8 ether;
|
|
uint256 nonce = 1;
|
|
(uint8 vA, bytes32 rA, bytes32 sA) = _signState(channelId, stateHash, nonce, balanceA, balanceB, alicePk);
|
|
(uint8 vB, bytes32 rB, bytes32 sB) = _signState(channelId, stateHash, nonce, balanceA, balanceB, bobPk);
|
|
|
|
uint256 aliceBefore = alice.balance;
|
|
uint256 bobBefore = bob.balance;
|
|
vm.prank(alice);
|
|
manager.closeChannelCooperative(channelId, stateHash, nonce, balanceA, balanceB, vA, rA, sA, vB, rB, sB);
|
|
|
|
assertEq(alice.balance, aliceBefore + balanceA);
|
|
assertEq(bob.balance, bobBefore + balanceB);
|
|
IGenericStateChannelManager.Channel memory ch = manager.getChannel(channelId);
|
|
assertEq(uint256(ch.status), uint256(IGenericStateChannelManager.ChannelStatus.Closed));
|
|
}
|
|
|
|
function test_SubmitCloseAndFinalize_WithStateHash() public {
|
|
vm.prank(alice);
|
|
uint256 channelId = manager.openChannel{ value: 10 ether }(bob);
|
|
vm.prank(bob);
|
|
manager.fundChannel{ value: 10 ether }(channelId);
|
|
|
|
bytes32 stateHash = keccak256("attestation");
|
|
uint256 balanceA = 5 ether;
|
|
uint256 balanceB = 15 ether;
|
|
uint256 nonce = 1;
|
|
(uint8 vA, bytes32 rA, bytes32 sA) = _signState(channelId, stateHash, nonce, balanceA, balanceB, alicePk);
|
|
(uint8 vB, bytes32 rB, bytes32 sB) = _signState(channelId, stateHash, nonce, balanceA, balanceB, bobPk);
|
|
vm.prank(bob);
|
|
manager.submitClose(channelId, stateHash, nonce, balanceA, balanceB, vA, rA, sA, vB, rB, sB);
|
|
|
|
IGenericStateChannelManager.Channel memory ch = manager.getChannel(channelId);
|
|
assertEq(ch.disputeStateHash, stateHash);
|
|
vm.warp(block.timestamp + CHALLENGE_WINDOW + 1);
|
|
manager.finalizeClose(channelId);
|
|
assertEq(uint256(manager.getChannel(channelId).status), uint256(IGenericStateChannelManager.ChannelStatus.Closed));
|
|
}
|
|
}
|