From 953e76852e1cc698a93943d6f56d6c62737e675a Mon Sep 17 00:00:00 2001 From: Jaro Date: Mon, 14 Mar 2022 14:11:53 +0200 Subject: [PATCH 1/3] Deleting unused `requestExit` function --- contracts/ChannelImplementation.sol | 39 --------- test/channel.js | 89 -------------------- test/contracts/TestChannelImplementation.sol | 4 - 3 files changed, 132 deletions(-) diff --git a/contracts/ChannelImplementation.sol b/contracts/ChannelImplementation.sol index 6291b4c..7942a6f 100644 --- a/contracts/ChannelImplementation.sol +++ b/contracts/ChannelImplementation.sol @@ -13,7 +13,6 @@ contract ChannelImplementation is FundsRecovery, Utils { using ECDSA for bytes32; string constant EXIT_PREFIX = "Exit request:"; - uint256 constant DELAY_SECONDS = 345600; // 4 days uint256 internal lastNonce; @@ -115,44 +114,6 @@ contract ChannelImplementation is FundsRecovery, Utils { emit PromiseSettled(hermes.contractAddress, _unpaidAmount, hermes.settled, _lock); } - // Returns timestamp until which exit request should be locked - function getTimelock() internal view virtual returns (uint256) { - return block.timestamp + DELAY_SECONDS; - } - - // Start withdrawal of deposited but still not settled funds - // NOTE _validUntil is needed for replay protection - function requestExit(address _beneficiary, uint256 _validUntil, bytes memory _signature) public { - uint256 _timelock = getTimelock(); - - require(exitRequest.timelock == 0, "Channel: new exit can be requested only when old one was finalised"); - require(_validUntil >= block.timestamp, "Channel: valid until have to be greater than or equal to current block timestamp"); - require(_timelock > _validUntil, "Channel: request have to be valid shorter than DELAY_SECONDS"); - require(_beneficiary != address(0), "Channel: beneficiary can't be zero address"); - - if (msg.sender != operator) { - address _channelId = address(this); - address _signer = keccak256(abi.encodePacked(EXIT_PREFIX, _channelId, _beneficiary, _validUntil)).recover(_signature); - require(_signer == operator, "Channel: have to be signed by operator"); - } - - exitRequest = ExitRequest(_timelock, _beneficiary); - - emit ExitRequested(_timelock); - } - - // Anyone can finalize exit request after timelock block passed - function finalizeExit() public { - require(exitRequest.timelock != 0 && block.timestamp >= exitRequest.timelock, "Channel: exit have to be requested and timelock have to be in past"); - - // Exit with all not settled funds - uint256 _amount = token.balanceOf(address(this)); - token.transfer(exitRequest.beneficiary, _amount); - emit Withdraw(exitRequest.beneficiary, _amount); - - exitRequest = ExitRequest(0, address(0)); // deleting request - } - // Fast funds withdrawal is possible when hermes agrees that given amount of funds can be withdrawn function fastExit(uint256 _amount, uint256 _transactorFee, address _beneficiary, uint256 _validUntil, bytes memory _operatorSignature, bytes memory _hermesSignature) public { require(_validUntil >= block.timestamp, "Channel: _validUntil have to be greater than or equal to current block timestamp"); diff --git a/test/channel.js b/test/channel.js index ed59a2e..c04d5fa 100644 --- a/test/channel.js +++ b/test/channel.js @@ -120,95 +120,6 @@ contract('Channel Contract Implementation tests', ([txMaker, ...otherAccounts]) await wallet.sendTx(channel.address, constructPayload(promise), hermes).should.be.rejected }) - /** - * Testing channel exit scenarios - */ - - let firstExitRequest - it("should successfully request exit channel", async () => { - const beneficiary = otherAccounts[1] - const { validUntil, signature } = await signExitRequest(channel, beneficiary, identity) - await channel.requestExit(beneficiary, validUntil, signature) - - const exitRequest = await channel.exitRequest() - expect(exitRequest.beneficiary).to.be.equal(beneficiary) - - // This will be needed in later requests - firstExitRequest = { beneficiary, validUntil, signature } - }) - - it("should fail requesting exit channel, when previous request is still active", async () => { - const beneficiary = otherAccounts[2] // different beneficiary - const { validUntil, signature } = await signExitRequest(channel, beneficiary, identity) - await channel.requestExit(beneficiary, validUntil, signature).should.be.rejected - - const exitRequest = await channel.exitRequest() - expect(exitRequest.beneficiary).to.be.not.equal(beneficiary) - }) - - it("finalise exit should fail if requested before timelock", async () => { - const expectedTxBlockNumber = (await web3.eth.getBlock('latest')).number - const timelock = (await channel.exitRequest()).timelock - expect(timelock.toNumber()).to.be.above(expectedTxBlockNumber) - - await channel.finalizeExit().should.be.rejected - }) - - it("during exit waiting period, receiving party should be able to settle latest promise", async () => { - const channelState = Object.assign({}, await channel.hermes(), { channelId: channel.address }) - const channelBalanceBefore = await token.balanceOf(channel.address) - const hermesBalanceBefore = await token.balanceOf(channelState.contractAddress) - - const promise = generatePromise(OneToken, new BN(0), channelState, identity) - await channel.settlePromise(promise.amount, promise.fee, promise.lock, promise.signature) - - const channelBalanceAfter = await token.balanceOf(channel.address) - channelBalanceAfter.should.be.bignumber.equal(channelBalanceBefore.sub(OneToken)) - - const hermesBalanceAfter = await token.balanceOf(channelState.contractAddress) - hermesBalanceAfter.should.be.bignumber.equal(hermesBalanceBefore.add(OneToken)) - }) - - it("should finalise exit request and send tokens into beneficiary address", async () => { - const beneficiary = otherAccounts[1] - const channelTokensBefore = await token.balanceOf(channel.address) - const delay = 3.5 // seconds - - // Transaction's block time should be bigger or equal to timelock block - const expectedTxBlockTime = (await web3.eth.getBlock('latest')).timestamp + delay - const timelock = (await channel.exitRequest()).timelock - expect(expectedTxBlockTime).to.be.at.least(timelock.toNumber()) - - // Finalise request should be successful - await sleep(delay * 1000) // we have to wait at least `delay` seconds before doing next transaction - await channel.finalizeExit() - - // All the left in channel tokens have to be sent into beneficiary address - expect((await token.balanceOf(channel.address)).toNumber()).to.be.equal(0) - - const beneficiaryBalance = await token.balanceOf(beneficiary) - beneficiaryBalance.should.be.bignumber.equal(channelTokensBefore) - - const exitRequest = await channel.exitRequest() - expect(exitRequest.timelock.toNumber()).to.be.equal(0) - }) - - it("should fail requesting exit with already used signature", async () => { - const { beneficiary, validUntil, signature } = firstExitRequest - await channel.requestExit(beneficiary, validUntil, signature).should.be.rejected - - const exitRequest = await channel.exitRequest() - expect(exitRequest.timelock.toNumber()).to.be.equal(0) - }) - - it("should be possible to request new exit", async () => { - const { beneficiary, validUntil, signature } = await signExitRequest(channel, otherAccounts[0], identity) - await channel.requestExit(beneficiary, validUntil, signature) - - const exitRequest = await channel.exitRequest() - expect(exitRequest.beneficiary).to.be.equal(beneficiary) - }) - /** * Testing topup with ETH via DEX */ diff --git a/test/contracts/TestChannelImplementation.sol b/test/contracts/TestChannelImplementation.sol index 6c34aca..6f7747a 100644 --- a/test/contracts/TestChannelImplementation.sol +++ b/test/contracts/TestChannelImplementation.sol @@ -12,10 +12,6 @@ contract TestChannelImplementation is ChannelImplementation { initialize(_token, _dex, _identityHash, _hermesAddress, _fee); } - function getTimelock() internal view override returns (uint256) { - return block.timestamp + TEST_DELAY_TIME; - } - function getNow() public view returns (uint256) { return block.timestamp; } From f3689c878df9d6a1e5c4ec78f53c8690a743de17 Mon Sep 17 00:00:00 2001 From: Jaro Date: Mon, 14 Mar 2022 14:12:08 +0200 Subject: [PATCH 2/3] Updated package-lock --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80f8fe1..42f63be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "payments-smart-contracts", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "payments-smart-contracts", - "version": "2.1.0", + "version": "2.2.0", "license": "GPL-3.0", "dependencies": { "@ethereumjs/tx": "^3.3.2", From 30857d883ab4e41dec48677fe837f733f739920a Mon Sep 17 00:00:00 2001 From: Jaro Date: Mon, 14 Mar 2022 14:13:50 +0200 Subject: [PATCH 3/3] Update flattened version --- .../ChannelImplementation.sol.flattened | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/contracts/flattened/ChannelImplementation.sol.flattened b/contracts/flattened/ChannelImplementation.sol.flattened index a44aae0..41e247f 100644 --- a/contracts/flattened/ChannelImplementation.sol.flattened +++ b/contracts/flattened/ChannelImplementation.sol.flattened @@ -610,7 +610,6 @@ contract ChannelImplementation is FundsRecovery, Utils { using ECDSA for bytes32; string constant EXIT_PREFIX = "Exit request:"; - uint256 constant DELAY_SECONDS = 345600; // 4 days uint256 internal lastNonce; @@ -712,44 +711,6 @@ contract ChannelImplementation is FundsRecovery, Utils { emit PromiseSettled(hermes.contractAddress, _unpaidAmount, hermes.settled, _lock); } - // Returns timestamp until which exit request should be locked - function getTimelock() internal view virtual returns (uint256) { - return block.timestamp + DELAY_SECONDS; - } - - // Start withdrawal of deposited but still not settled funds - // NOTE _validUntil is needed for replay protection - function requestExit(address _beneficiary, uint256 _validUntil, bytes memory _signature) public { - uint256 _timelock = getTimelock(); - - require(exitRequest.timelock == 0, "Channel: new exit can be requested only when old one was finalised"); - require(_validUntil >= block.timestamp, "Channel: valid until have to be greater than or equal to current block timestamp"); - require(_timelock > _validUntil, "Channel: request have to be valid shorter than DELAY_SECONDS"); - require(_beneficiary != address(0), "Channel: beneficiary can't be zero address"); - - if (msg.sender != operator) { - address _channelId = address(this); - address _signer = keccak256(abi.encodePacked(EXIT_PREFIX, _channelId, _beneficiary, _validUntil)).recover(_signature); - require(_signer == operator, "Channel: have to be signed by operator"); - } - - exitRequest = ExitRequest(_timelock, _beneficiary); - - emit ExitRequested(_timelock); - } - - // Anyone can finalize exit request after timelock block passed - function finalizeExit() public { - require(exitRequest.timelock != 0 && block.timestamp >= exitRequest.timelock, "Channel: exit have to be requested and timelock have to be in past"); - - // Exit with all not settled funds - uint256 _amount = token.balanceOf(address(this)); - token.transfer(exitRequest.beneficiary, _amount); - emit Withdraw(exitRequest.beneficiary, _amount); - - exitRequest = ExitRequest(0, address(0)); // deleting request - } - // Fast funds withdrawal is possible when hermes agrees that given amount of funds can be withdrawn function fastExit(uint256 _amount, uint256 _transactorFee, address _beneficiary, uint256 _validUntil, bytes memory _operatorSignature, bytes memory _hermesSignature) public { require(_validUntil >= block.timestamp, "Channel: _validUntil have to be greater than or equal to current block timestamp");