From 827de18127d7603b3b1438209a6af46dc33b97f0 Mon Sep 17 00:00:00 2001 From: William Cory Date: Mon, 24 Sep 2018 18:30:12 -0700 Subject: [PATCH 1/3] prototype consensusWithdraw --- contracts/LedgerChannel.sol | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/contracts/LedgerChannel.sol b/contracts/LedgerChannel.sol index b56bbc8..071bd50 100644 --- a/contracts/LedgerChannel.sol +++ b/contracts/LedgerChannel.sol @@ -48,6 +48,18 @@ contract LedgerChannel { uint256 updateLCtimeout ); + event DidLCWithdrawal( + bytes32 indexed lcID, + address withdrawalAddress, + uint256 sequence, + uint256 ethBalanceA, + uint256 ethBalanceI, + uint256 tokenBalanceA, + uint256 tokenBalanceI, + uint256 ethWithdrawalAmount, + uint256 tokenWithdrawalAmount + ); + event DidLCClose ( bytes32 indexed channelId, uint256 sequence, @@ -233,7 +245,89 @@ contract LedgerChannel { emit DidLCDeposit(_lcID, recipient, _balance, isToken); } + + // A consensus withdraw is essentially doing a consensus close for a partial amount and then opening a new channel with the remaining balances + // we are doing it while keeping the same channel by changing initialDeposit + + // We may want to change initialDeposit to a different variable name like lastCheckedInBalances + // multiple consensusWithdraws can happen offchain before submitting to chain as long as both parties remain smart about what the balances truly are. + + // if multiple consensus withdraws happen off chain before getting submitted to chain some issues happen when trying to batch them. + // for example: partyA withdraws, partyI then wishes to batch their own withdraw with patyA. But now partyI can submit their first withdrawal to chain and invalidate the 2nd one whenever they wish + // this would also invalidate all state updates after the first withdrawal. + function consensusWithdraw( + bytes32 _lcID, + uint256[7] withdrawParams, // [sequence, ethBalanceA, ethBalanceI, tokenBalanceA, tokenBalanceI, ethWithdrawal, tokenWithdrawal] + address _withdrawalAddress, + string _sigA, + string _sigI + ) + public + { + // first we make sure the channel is open and the balances all add up. This means that the consensusWithdraw must be submitted to chain before trying to closeChannel or + // both parties can ignore the consensusWithdraw and submit a consensusClose for the correct balances (batching together the withdraw and the close) + require(Channels[_lcID].isOpen == true); + require(Channels[_lcID].initialDeposit[0] + Channels[_lcID].ethBalances[2] + Channels[_lcID].ethBalances[3] == withdrawParams[1] + withdrawParams[2] + withdrawParams[5]); + require(Channels[_lcID].initialDeposit[1] + Channels[_lcID].erc20Balances[2] + Channels[_lcID].erc20Balances[3] == withdrawParams[3] + withdrawParams[4] + withdrawParams[6]); + + // prevent replay attacks + require(withdrawParams[0] > Channels[_lcID].sequence); + + // verify sigs + bytes32 _state = keccak256( + abi.encodePacked( + _lcID, + true, + withdrawParams[0], + // what are these 2? + uint256(0), + bytes32(0x0), + Channels[_lcID].partyAddresses[0], + Channels[_lcID].partyAddresses[1], + withdrawParams[1], + withdrawParams[2], + withdrawParams[3], + withdrawParams[4], + withdrawParams[5], + withdrawParams[6] + ) + ); + require(Channels[_lcID].partyAddresses[0] == ECTools.recoverSigner(_state, _sigA)); + require(Channels[_lcID].partyAddresses[1] == ECTools.recoverSigner(_state, _sigI)); + + // transfer eth + if(withdrawParams[5] != 0) { + _withdrawalAddress.transfer(withdrawParams[5]); + } + + // transfer Tokens + if(withdrawParams[6] != 0) { + require(Channels[_lcID].token.transfer(_withdrawalAddress, withdrawParams[6]), "happyWithdrawlChannel: token transfer failure"); + } + + // update the new channel as if it just now got created with the current sequence + Channels[_lcID].sequence = withdrawParams[0]; + Channels[_lcID].initialDeposit = [withdrawParams[1] + withdrawParams[2], withdrawParams[3] + withdrawParams[4]]; + + + + Channels[_lcID].ethBalances = [withdrawParams[1], withdrawParams[2]]; + Channels[_lcID].erc20Balances = [withdrawParams[3], withdrawParams[4]]; + + emit DidLCWithdrawal( + _lcID, + _withdrawalAddress, + withdrawParams[0], + withdrawParams[1], + withdrawParams[2], + withdrawParams[3], + withdrawParams[4], + withdrawParams[5], + withdrawParams[6] + ); + } + // TODO: Check there are no open virtual channels, the client should have cought this before signing a close LC state update function consensusCloseChannel( bytes32 _lcID, From 3c60f1efeb0e3eda33a3408082e92d3e01f678a1 Mon Sep 17 00:00:00 2001 From: William Cory Date: Mon, 24 Sep 2018 19:03:33 -0700 Subject: [PATCH 2/3] fix stack to deep error --- contracts/LedgerChannel.sol | 180 ++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/contracts/LedgerChannel.sol b/contracts/LedgerChannel.sol index 071bd50..5721ce8 100644 --- a/contracts/LedgerChannel.sol +++ b/contracts/LedgerChannel.sol @@ -3,7 +3,7 @@ pragma solidity ^0.4.23; import "./lib/ECTools.sol"; import "./lib/token/HumanStandardToken.sol"; -/// @title Set Virtual Channels - A layer2 hub and spoke payment network +/// @title Set Virtual Channels - A layer2 hub and spoke payment network /// @author Nathan Ginnever contract LedgerChannel { @@ -37,9 +37,9 @@ contract LedgerChannel { ); event DidLCUpdateState ( - bytes32 indexed channelId, - uint256 sequence, - uint256 numOpenVc, + bytes32 indexed channelId, + uint256 sequence, + uint256 numOpenVc, uint256 ethBalanceA, uint256 tokenBalanceA, uint256 ethBalanceI, @@ -58,8 +58,8 @@ contract LedgerChannel { uint256 tokenBalanceI, uint256 ethWithdrawalAmount, uint256 tokenWithdrawalAmount - ); - + ); + event DidLCClose ( bytes32 indexed channelId, uint256 sequence, @@ -70,30 +70,30 @@ contract LedgerChannel { ); event DidVCInit ( - bytes32 indexed lcId, - bytes32 indexed vcId, - bytes proof, - uint256 sequence, - address partyA, - address partyB, - uint256 balanceA, - uint256 balanceB + bytes32 indexed lcId, + bytes32 indexed vcId, + bytes proof, + uint256 sequence, + address partyA, + address partyB, + uint256 balanceA, + uint256 balanceB ); event DidVCSettle ( - bytes32 indexed lcId, + bytes32 indexed lcId, bytes32 indexed vcId, - uint256 updateSeq, - uint256 updateBalA, + uint256 updateSeq, + uint256 updateBalA, uint256 updateBalB, address challenger, uint256 updateVCtimeout ); event DidVCClose( - bytes32 indexed lcId, - bytes32 indexed vcId, - uint256 balanceA, + bytes32 indexed lcId, + bytes32 indexed vcId, + uint256 balanceA, uint256 balanceB ); @@ -140,15 +140,15 @@ contract LedgerChannel { uint256 _confirmTime, address _token, uint256[2] _balances // [eth, token] - ) + ) public - payable + payable { require(Channels[_lcID].partyAddresses[0] == address(0), "Channel has already been created."); require(_partyI != 0x0, "No partyI address provided to LC creation"); require(_balances[0] >= 0 && _balances[1] >= 0, "Balances cannot be negative"); // Set initial ledger channel state - // Alice must execute this and we assume the initial state + // Alice must execute this and we assume the initial state // to be signed from this requirement // Alternative is to check a sig as in joinChannel Channels[_lcID].partyAddresses[0] = msg.sender; @@ -157,7 +157,7 @@ contract LedgerChannel { if(_balances[0] != 0) { require(msg.value == _balances[0], "Eth balance does not match sent value"); Channels[_lcID].ethBalances[0] = msg.value; - } + } if(_balances[1] != 0) { Channels[_lcID].token = HumanStandardToken(_token); require(Channels[_lcID].token.transferFrom(msg.sender, this, _balances[1]),"CreateChannel: token transfer failure"); @@ -166,7 +166,7 @@ contract LedgerChannel { Channels[_lcID].sequence = 0; Channels[_lcID].confirmTime = _confirmTime; - // is close flag, lc state sequence, number open vc, vc root hash, partyA... + // is close flag, lc state sequence, number open vc, vc root hash, partyA... //Channels[_lcID].stateHash = keccak256(uint256(0), uint256(0), uint256(0), bytes32(0x0), bytes32(msg.sender), bytes32(_partyI), balanceA, balanceI); Channels[_lcID].LCopenTimeout = now + _confirmTime; Channels[_lcID].initialDeposit = _balances; @@ -180,7 +180,7 @@ contract LedgerChannel { if(Channels[_lcID].initialDeposit[0] != 0) { Channels[_lcID].partyAddresses[0].transfer(Channels[_lcID].ethBalances[0]); - } + } if(Channels[_lcID].initialDeposit[1] != 0) { require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[0], Channels[_lcID].erc20Balances[0]),"CreateChannel: token transfer failure"); } @@ -199,10 +199,10 @@ contract LedgerChannel { if(_balances[0] != 0) { require(msg.value == _balances[0], "state balance does not match sent value"); Channels[_lcID].ethBalances[1] = msg.value; - } + } if(_balances[1] != 0) { require(Channels[_lcID].token.transferFrom(msg.sender, this, _balances[1]),"joinChannel: token transfer failure"); - Channels[_lcID].erc20Balances[1] = _balances[1]; + Channels[_lcID].erc20Balances[1] = _balances[1]; } Channels[_lcID].initialDeposit[0]+=_balances[0]; @@ -239,13 +239,13 @@ contract LedgerChannel { Channels[_lcID].erc20Balances[3] += _balance; } else { require(msg.value == _balance, "state balance does not match sent value"); - Channels[_lcID].ethBalances[3] += msg.value; + Channels[_lcID].ethBalances[3] += msg.value; } } - + emit DidLCDeposit(_lcID, recipient, _balance, isToken); } - + // A consensus withdraw is essentially doing a consensus close for a partial amount and then opening a new channel with the remaining balances // we are doing it while keeping the same channel by changing initialDeposit @@ -284,7 +284,7 @@ contract LedgerChannel { bytes32(0x0), Channels[_lcID].partyAddresses[0], Channels[_lcID].partyAddresses[1], - withdrawParams[1], + // withdrawParams[1], // commenting this out because it's determinstic still (balances must add up to total) and getting a stack too deep error withdrawParams[2], withdrawParams[3], withdrawParams[4], @@ -326,17 +326,17 @@ contract LedgerChannel { withdrawParams[5], withdrawParams[6] ); - } - + } + // TODO: Check there are no open virtual channels, the client should have cought this before signing a close LC state update function consensusCloseChannel( - bytes32 _lcID, - uint256 _sequence, + bytes32 _lcID, + uint256 _sequence, uint256[4] _balances, // 0: ethBalanceA 1:ethBalanceI 2:tokenBalanceA 3:tokenBalanceI - string _sigA, + string _sigA, string _sigI - ) - public + ) + public { // assume num open vc is 0 and root hash is 0x0 //require(Channels[_lcID].sequence < _sequence); @@ -353,9 +353,9 @@ contract LedgerChannel { _sequence, uint256(0), bytes32(0x0), - Channels[_lcID].partyAddresses[0], - Channels[_lcID].partyAddresses[1], - _balances[0], + Channels[_lcID].partyAddresses[0], + Channels[_lcID].partyAddresses[1], + _balances[0], _balances[1], _balances[2], _balances[3] @@ -374,7 +374,7 @@ contract LedgerChannel { if(_balances[2] != 0 || _balances[3] != 0) { require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[0], _balances[2]),"happyCloseChannel: token transfer failure"); - require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[1], _balances[3]),"happyCloseChannel: token transfer failure"); + require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[1], _balances[3]),"happyCloseChannel: token transfer failure"); } numChannels--; @@ -385,13 +385,13 @@ contract LedgerChannel { // Byzantine functions function updateLCstate( - bytes32 _lcID, + bytes32 _lcID, uint256[6] updateParams, // [sequence, numOpenVc, ethbalanceA, ethbalanceI, tokenbalanceA, tokenbalanceI] - bytes32 _VCroot, - string _sigA, + bytes32 _VCroot, + string _sigA, string _sigI - ) - public + ) + public { Channel storage channel = Channels[_lcID]; require(channel.isOpen); @@ -399,22 +399,22 @@ contract LedgerChannel { require(channel.ethBalances[0] + channel.ethBalances[1] >= updateParams[2] + updateParams[3]); require(channel.erc20Balances[0] + channel.erc20Balances[1] >= updateParams[4] + updateParams[5]); - if(channel.isUpdateLCSettling == true) { + if(channel.isUpdateLCSettling == true) { require(channel.updateLCtimeout > now); } - + bytes32 _state = keccak256( abi.encodePacked( _lcID, - false, - updateParams[0], - updateParams[1], - _VCroot, - channel.partyAddresses[0], - channel.partyAddresses[1], - updateParams[2], + false, + updateParams[0], + updateParams[1], + _VCroot, + channel.partyAddresses[0], + channel.partyAddresses[1], + updateParams[2], updateParams[3], - updateParams[4], + updateParams[4], updateParams[5] ) ); @@ -436,30 +436,30 @@ contract LedgerChannel { // make settlement flag emit DidLCUpdateState ( - _lcID, - updateParams[0], - updateParams[1], - updateParams[2], + _lcID, + updateParams[0], + updateParams[1], + updateParams[2], updateParams[3], updateParams[4], - updateParams[5], + updateParams[5], _VCroot, channel.updateLCtimeout ); } - // supply initial state of VC to "prime" the force push game + // supply initial state of VC to "prime" the force push game function initVCstate( - bytes32 _lcID, - bytes32 _vcID, - bytes _proof, - address _partyA, - address _partyB, + bytes32 _lcID, + bytes32 _vcID, + bytes _proof, + address _partyA, + address _partyB, uint256[2] _bond, uint256[4] _balances, // 0: ethBalanceA 1:ethBalanceI 2:tokenBalanceA 3:tokenBalanceI string sigA - ) - public + ) + public { require(Channels[_lcID].isOpen, "LC is closed."); // sub-channel must be open @@ -494,18 +494,18 @@ contract LedgerChannel { } //TODO: verify state transition since the hub did not agree to this state - // make sure the A/B balances are not beyond ingrids bonds + // make sure the A/B balances are not beyond ingrids bonds // Params: vc init state, vc final balance, vcID function settleVC( - bytes32 _lcID, - bytes32 _vcID, - uint256 updateSeq, - address _partyA, + bytes32 _lcID, + bytes32 _vcID, + uint256 updateSeq, + address _partyA, address _partyB, uint256[4] updateBal, // [ethupdateBalA, ethupdateBalB, tokenupdateBalA, tokenupdateBalB] string sigA - ) - public + ) + public { require(Channels[_lcID].isOpen, "LC is closed."); // sub-channel must be open @@ -517,7 +517,7 @@ contract LedgerChannel { ); require( virtualChannels[_vcID].bond[0] == updateBal[0] + updateBal[1] && - virtualChannels[_vcID].bond[1] == updateBal[2] + updateBal[3], + virtualChannels[_vcID].bond[1] == updateBal[2] + updateBal[3], "Incorrect balances for bonded amount"); // Check time has passed on updateLCtimeout and has not passed the time to store a vc state // virtualChannels[_vcID].updateVCtimeout should be 0 on uninitialized vc state, and this should @@ -527,15 +527,15 @@ contract LedgerChannel { bytes32 _updateState = keccak256( abi.encodePacked( - _vcID, - updateSeq, - _partyA, - _partyB, - virtualChannels[_vcID].bond[0], - virtualChannels[_vcID].bond[1], - updateBal[0], - updateBal[1], - updateBal[2], + _vcID, + updateSeq, + _partyA, + _partyB, + virtualChannels[_vcID].bond[0], + virtualChannels[_vcID].bond[1], + updateBal[0], + updateBal[1], + updateBal[2], updateBal[3] ) ); @@ -603,7 +603,7 @@ contract LedgerChannel { uint256 totalEthDeposit = channel.initialDeposit[0] + channel.ethBalances[2] + channel.ethBalances[3]; uint256 totalTokenDeposit = channel.initialDeposit[1] + channel.erc20Balances[2] + channel.erc20Balances[3]; - uint256 possibleTotalEthBeforeDeposit = channel.ethBalances[0] + channel.ethBalances[1]; + uint256 possibleTotalEthBeforeDeposit = channel.ethBalances[0] + channel.ethBalances[1]; uint256 possibleTotalTokenBeforeDeposit = channel.erc20Balances[0] + channel.erc20Balances[1]; if(possibleTotalEthBeforeDeposit < totalEthDeposit) { @@ -644,7 +644,7 @@ contract LedgerChannel { require( channel.token.transfer(channel.partyAddresses[1], tokenbalanceI), "byzantineCloseChannel: token transfer failure" - ); + ); } channel.isOpen = false; From 4246bf22c4d31b31996513267059c3322458c00f Mon Sep 17 00:00:00 2001 From: William Cory Date: Mon, 24 Sep 2018 20:07:20 -0700 Subject: [PATCH 3/3] remove vs code auto trimming --- contracts/LedgerChannel.sol | 171 ++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 85 deletions(-) diff --git a/contracts/LedgerChannel.sol b/contracts/LedgerChannel.sol index 5721ce8..cf4446d 100644 --- a/contracts/LedgerChannel.sol +++ b/contracts/LedgerChannel.sol @@ -3,7 +3,7 @@ pragma solidity ^0.4.23; import "./lib/ECTools.sol"; import "./lib/token/HumanStandardToken.sol"; -/// @title Set Virtual Channels - A layer2 hub and spoke payment network +/// @title Set Virtual Channels - A layer2 hub and spoke payment network /// @author Nathan Ginnever contract LedgerChannel { @@ -37,9 +37,9 @@ contract LedgerChannel { ); event DidLCUpdateState ( - bytes32 indexed channelId, - uint256 sequence, - uint256 numOpenVc, + bytes32 indexed channelId, + uint256 sequence, + uint256 numOpenVc, uint256 ethBalanceA, uint256 tokenBalanceA, uint256 ethBalanceI, @@ -60,6 +60,7 @@ contract LedgerChannel { uint256 tokenWithdrawalAmount ); + event DidLCClose ( bytes32 indexed channelId, uint256 sequence, @@ -70,30 +71,30 @@ contract LedgerChannel { ); event DidVCInit ( - bytes32 indexed lcId, - bytes32 indexed vcId, - bytes proof, - uint256 sequence, - address partyA, - address partyB, - uint256 balanceA, - uint256 balanceB + bytes32 indexed lcId, + bytes32 indexed vcId, + bytes proof, + uint256 sequence, + address partyA, + address partyB, + uint256 balanceA, + uint256 balanceB ); event DidVCSettle ( - bytes32 indexed lcId, + bytes32 indexed lcId, bytes32 indexed vcId, - uint256 updateSeq, - uint256 updateBalA, + uint256 updateSeq, + uint256 updateBalA, uint256 updateBalB, address challenger, uint256 updateVCtimeout ); event DidVCClose( - bytes32 indexed lcId, - bytes32 indexed vcId, - uint256 balanceA, + bytes32 indexed lcId, + bytes32 indexed vcId, + uint256 balanceA, uint256 balanceB ); @@ -140,15 +141,15 @@ contract LedgerChannel { uint256 _confirmTime, address _token, uint256[2] _balances // [eth, token] - ) + ) public - payable + payable { require(Channels[_lcID].partyAddresses[0] == address(0), "Channel has already been created."); require(_partyI != 0x0, "No partyI address provided to LC creation"); require(_balances[0] >= 0 && _balances[1] >= 0, "Balances cannot be negative"); // Set initial ledger channel state - // Alice must execute this and we assume the initial state + // Alice must execute this and we assume the initial state // to be signed from this requirement // Alternative is to check a sig as in joinChannel Channels[_lcID].partyAddresses[0] = msg.sender; @@ -157,7 +158,7 @@ contract LedgerChannel { if(_balances[0] != 0) { require(msg.value == _balances[0], "Eth balance does not match sent value"); Channels[_lcID].ethBalances[0] = msg.value; - } + } if(_balances[1] != 0) { Channels[_lcID].token = HumanStandardToken(_token); require(Channels[_lcID].token.transferFrom(msg.sender, this, _balances[1]),"CreateChannel: token transfer failure"); @@ -166,7 +167,7 @@ contract LedgerChannel { Channels[_lcID].sequence = 0; Channels[_lcID].confirmTime = _confirmTime; - // is close flag, lc state sequence, number open vc, vc root hash, partyA... + // is close flag, lc state sequence, number open vc, vc root hash, partyA... //Channels[_lcID].stateHash = keccak256(uint256(0), uint256(0), uint256(0), bytes32(0x0), bytes32(msg.sender), bytes32(_partyI), balanceA, balanceI); Channels[_lcID].LCopenTimeout = now + _confirmTime; Channels[_lcID].initialDeposit = _balances; @@ -180,7 +181,7 @@ contract LedgerChannel { if(Channels[_lcID].initialDeposit[0] != 0) { Channels[_lcID].partyAddresses[0].transfer(Channels[_lcID].ethBalances[0]); - } + } if(Channels[_lcID].initialDeposit[1] != 0) { require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[0], Channels[_lcID].erc20Balances[0]),"CreateChannel: token transfer failure"); } @@ -199,10 +200,10 @@ contract LedgerChannel { if(_balances[0] != 0) { require(msg.value == _balances[0], "state balance does not match sent value"); Channels[_lcID].ethBalances[1] = msg.value; - } + } if(_balances[1] != 0) { require(Channels[_lcID].token.transferFrom(msg.sender, this, _balances[1]),"joinChannel: token transfer failure"); - Channels[_lcID].erc20Balances[1] = _balances[1]; + Channels[_lcID].erc20Balances[1] = _balances[1]; } Channels[_lcID].initialDeposit[0]+=_balances[0]; @@ -239,10 +240,10 @@ contract LedgerChannel { Channels[_lcID].erc20Balances[3] += _balance; } else { require(msg.value == _balance, "state balance does not match sent value"); - Channels[_lcID].ethBalances[3] += msg.value; + Channels[_lcID].ethBalances[3] += msg.value; } } - + emit DidLCDeposit(_lcID, recipient, _balance, isToken); } @@ -327,16 +328,16 @@ contract LedgerChannel { withdrawParams[6] ); } - + // TODO: Check there are no open virtual channels, the client should have cought this before signing a close LC state update function consensusCloseChannel( - bytes32 _lcID, - uint256 _sequence, + bytes32 _lcID, + uint256 _sequence, uint256[4] _balances, // 0: ethBalanceA 1:ethBalanceI 2:tokenBalanceA 3:tokenBalanceI - string _sigA, + string _sigA, string _sigI - ) - public + ) + public { // assume num open vc is 0 and root hash is 0x0 //require(Channels[_lcID].sequence < _sequence); @@ -353,9 +354,9 @@ contract LedgerChannel { _sequence, uint256(0), bytes32(0x0), - Channels[_lcID].partyAddresses[0], - Channels[_lcID].partyAddresses[1], - _balances[0], + Channels[_lcID].partyAddresses[0], + Channels[_lcID].partyAddresses[1], + _balances[0], _balances[1], _balances[2], _balances[3] @@ -374,7 +375,7 @@ contract LedgerChannel { if(_balances[2] != 0 || _balances[3] != 0) { require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[0], _balances[2]),"happyCloseChannel: token transfer failure"); - require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[1], _balances[3]),"happyCloseChannel: token transfer failure"); + require(Channels[_lcID].token.transfer(Channels[_lcID].partyAddresses[1], _balances[3]),"happyCloseChannel: token transfer failure"); } numChannels--; @@ -385,13 +386,13 @@ contract LedgerChannel { // Byzantine functions function updateLCstate( - bytes32 _lcID, + bytes32 _lcID, uint256[6] updateParams, // [sequence, numOpenVc, ethbalanceA, ethbalanceI, tokenbalanceA, tokenbalanceI] - bytes32 _VCroot, - string _sigA, + bytes32 _VCroot, + string _sigA, string _sigI - ) - public + ) + public { Channel storage channel = Channels[_lcID]; require(channel.isOpen); @@ -399,22 +400,22 @@ contract LedgerChannel { require(channel.ethBalances[0] + channel.ethBalances[1] >= updateParams[2] + updateParams[3]); require(channel.erc20Balances[0] + channel.erc20Balances[1] >= updateParams[4] + updateParams[5]); - if(channel.isUpdateLCSettling == true) { + if(channel.isUpdateLCSettling == true) { require(channel.updateLCtimeout > now); } - + bytes32 _state = keccak256( abi.encodePacked( _lcID, - false, - updateParams[0], - updateParams[1], - _VCroot, - channel.partyAddresses[0], - channel.partyAddresses[1], - updateParams[2], + false, + updateParams[0], + updateParams[1], + _VCroot, + channel.partyAddresses[0], + channel.partyAddresses[1], + updateParams[2], updateParams[3], - updateParams[4], + updateParams[4], updateParams[5] ) ); @@ -436,30 +437,30 @@ contract LedgerChannel { // make settlement flag emit DidLCUpdateState ( - _lcID, - updateParams[0], - updateParams[1], - updateParams[2], + _lcID, + updateParams[0], + updateParams[1], + updateParams[2], updateParams[3], updateParams[4], - updateParams[5], + updateParams[5], _VCroot, channel.updateLCtimeout ); } - // supply initial state of VC to "prime" the force push game + // supply initial state of VC to "prime" the force push game function initVCstate( - bytes32 _lcID, - bytes32 _vcID, - bytes _proof, - address _partyA, - address _partyB, + bytes32 _lcID, + bytes32 _vcID, + bytes _proof, + address _partyA, + address _partyB, uint256[2] _bond, uint256[4] _balances, // 0: ethBalanceA 1:ethBalanceI 2:tokenBalanceA 3:tokenBalanceI string sigA - ) - public + ) + public { require(Channels[_lcID].isOpen, "LC is closed."); // sub-channel must be open @@ -494,18 +495,18 @@ contract LedgerChannel { } //TODO: verify state transition since the hub did not agree to this state - // make sure the A/B balances are not beyond ingrids bonds + // make sure the A/B balances are not beyond ingrids bonds // Params: vc init state, vc final balance, vcID function settleVC( - bytes32 _lcID, - bytes32 _vcID, - uint256 updateSeq, - address _partyA, + bytes32 _lcID, + bytes32 _vcID, + uint256 updateSeq, + address _partyA, address _partyB, uint256[4] updateBal, // [ethupdateBalA, ethupdateBalB, tokenupdateBalA, tokenupdateBalB] string sigA - ) - public + ) + public { require(Channels[_lcID].isOpen, "LC is closed."); // sub-channel must be open @@ -517,7 +518,7 @@ contract LedgerChannel { ); require( virtualChannels[_vcID].bond[0] == updateBal[0] + updateBal[1] && - virtualChannels[_vcID].bond[1] == updateBal[2] + updateBal[3], + virtualChannels[_vcID].bond[1] == updateBal[2] + updateBal[3], "Incorrect balances for bonded amount"); // Check time has passed on updateLCtimeout and has not passed the time to store a vc state // virtualChannels[_vcID].updateVCtimeout should be 0 on uninitialized vc state, and this should @@ -527,15 +528,15 @@ contract LedgerChannel { bytes32 _updateState = keccak256( abi.encodePacked( - _vcID, - updateSeq, - _partyA, - _partyB, - virtualChannels[_vcID].bond[0], - virtualChannels[_vcID].bond[1], - updateBal[0], - updateBal[1], - updateBal[2], + _vcID, + updateSeq, + _partyA, + _partyB, + virtualChannels[_vcID].bond[0], + virtualChannels[_vcID].bond[1], + updateBal[0], + updateBal[1], + updateBal[2], updateBal[3] ) ); @@ -603,7 +604,7 @@ contract LedgerChannel { uint256 totalEthDeposit = channel.initialDeposit[0] + channel.ethBalances[2] + channel.ethBalances[3]; uint256 totalTokenDeposit = channel.initialDeposit[1] + channel.erc20Balances[2] + channel.erc20Balances[3]; - uint256 possibleTotalEthBeforeDeposit = channel.ethBalances[0] + channel.ethBalances[1]; + uint256 possibleTotalEthBeforeDeposit = channel.ethBalances[0] + channel.ethBalances[1]; uint256 possibleTotalTokenBeforeDeposit = channel.erc20Balances[0] + channel.erc20Balances[1]; if(possibleTotalEthBeforeDeposit < totalEthDeposit) { @@ -644,7 +645,7 @@ contract LedgerChannel { require( channel.token.transfer(channel.partyAddresses[1], tokenbalanceI), "byzantineCloseChannel: token transfer failure" - ); + ); } channel.isOpen = false;