From 5a003d70c1792e49d71a6df8939589147fd50cc8 Mon Sep 17 00:00:00 2001 From: Ivo Georgiev Date: Mon, 29 Apr 2024 17:33:08 +0300 Subject: [PATCH 1/3] add chainId to channelId: try 1 --- contracts/OUTPACE.sol | 12 ++++++------ contracts/libs/BytesLib.sol | 2 +- contracts/libs/MerkleProof.sol | 2 +- contracts/libs/SafeERC20.sol | 2 +- contracts/libs/SignatureValidator.sol | 2 +- contracts/libs/SignatureValidatorV2.sol | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contracts/OUTPACE.sol b/contracts/OUTPACE.sol index a2f41e77..eaab22e5 100644 --- a/contracts/OUTPACE.sol +++ b/contracts/OUTPACE.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; +pragma solidity 0.8.19; import "./libs/SafeERC20.sol"; import "./libs/MerkleProof.sol"; @@ -49,7 +49,7 @@ contract OUTPACE { // Functions function deposit(Channel calldata channel, address recipient, uint amount) external { - bytes32 channelId = keccak256(abi.encode(channel)); + bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); require(amount > 0, 'NO_DEPOSIT'); require(challenges[channelId] != CLOSED, 'CHANNEL_CLOSED'); remaining[channelId] += amount; @@ -79,7 +79,7 @@ contract OUTPACE { } function calcWithdrawAmount(address earner, Withdrawal calldata withdrawal) internal returns (uint) { - bytes32 channelId = keccak256(abi.encode(withdrawal.channel)); + bytes32 channelId = keccak256(abi.encode(withdrawal.channel, block.chainid)); // require that the is not closed uint challengeExpirationTime = challenges[channelId]; require(challengeExpirationTime != CLOSED, 'CHANNEL_CLOSED'); @@ -115,7 +115,7 @@ contract OUTPACE { // same applies for resuming //require(remaining[channelId] > 0, 'no funds to be distributed'); require(msg.sender == channel.leader || msg.sender == channel.follower || msg.sender == channel.guardian, 'NOT_AUTHORIZED'); - bytes32 channelId = keccak256(abi.encode(channel)); + bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); require(challenges[channelId] == 0, 'CHANNEL_ALREADY_CHALLENGED'); uint expires = block.timestamp + CHALLENGE_TIME; challenges[channelId] = expires; @@ -124,7 +124,7 @@ contract OUTPACE { } function resume(Channel calldata channel, bytes32[3] calldata sigLeader, bytes32[3] calldata sigFollower) external { - bytes32 channelId = keccak256(abi.encode(channel)); + bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); uint challengeExpires = challenges[channelId]; require(challengeExpires != 0 && challengeExpires != CLOSED, 'CHANNEL_NOT_CHALLENGED'); // NOTE: we can resume the channel by mutual consent even if it's closable, so we won't check whether challengeExpires is in the future @@ -140,7 +140,7 @@ contract OUTPACE { function close(Channel calldata channel) external { address guardian = channel.guardian; require(msg.sender == guardian, 'NOT_GUARDIAN'); - bytes32 channelId = keccak256(abi.encode(channel)); + bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); uint challengeExpires = challenges[channelId]; require(challengeExpires != 0 && challengeExpires != CLOSED, 'CHANNEL_NOT_CHALLENGED'); require(block.timestamp > challengeExpires, 'CHANNEL_NOT_CLOSABLE'); diff --git a/contracts/libs/BytesLib.sol b/contracts/libs/BytesLib.sol index ad4073af..6072822b 100644 --- a/contracts/libs/BytesLib.sol +++ b/contracts/libs/BytesLib.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; +pragma solidity 0.8.19; // @TODO: Formatting library LibBytes { diff --git a/contracts/libs/MerkleProof.sol b/contracts/libs/MerkleProof.sol index 174ed51f..0887750a 100644 --- a/contracts/libs/MerkleProof.sol +++ b/contracts/libs/MerkleProof.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; +pragma solidity 0.8.19; library MerkleProof { function isContained(bytes32 valueHash, bytes32[] memory proof, bytes32 root) internal pure returns (bool) { diff --git a/contracts/libs/SafeERC20.sol b/contracts/libs/SafeERC20.sol index 79907de6..bed0ce5b 100644 --- a/contracts/libs/SafeERC20.sol +++ b/contracts/libs/SafeERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; +pragma solidity 0.8.19; // NOTE: this interface lacks return values for transfer/transferFrom/approve on purpose, // as we use the SafeERC20 library to check the return value diff --git a/contracts/libs/SignatureValidator.sol b/contracts/libs/SignatureValidator.sol index 44992267..5444d5aa 100644 --- a/contracts/libs/SignatureValidator.sol +++ b/contracts/libs/SignatureValidator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; +pragma solidity 0.8.19; library SignatureValidator { enum SignatureMode { diff --git a/contracts/libs/SignatureValidatorV2.sol b/contracts/libs/SignatureValidatorV2.sol index 9c481394..80438c8d 100644 --- a/contracts/libs/SignatureValidatorV2.sol +++ b/contracts/libs/SignatureValidatorV2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.7; +pragma solidity 0.8.19; import "./BytesLib.sol"; From 1988d99685952884333e092fe2310dff11906936 Mon Sep 17 00:00:00 2001 From: Ivo Georgiev Date: Mon, 29 Apr 2024 17:34:46 +0300 Subject: [PATCH 2/3] add chainId to channelId: try 2, tests still not fixed --- contracts/OUTPACE.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/OUTPACE.sol b/contracts/OUTPACE.sol index eaab22e5..e52753c7 100644 --- a/contracts/OUTPACE.sol +++ b/contracts/OUTPACE.sol @@ -49,7 +49,7 @@ contract OUTPACE { // Functions function deposit(Channel calldata channel, address recipient, uint amount) external { - bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); + bytes32 channelId = keccak256(abi.encode(channel)); require(amount > 0, 'NO_DEPOSIT'); require(challenges[channelId] != CLOSED, 'CHANNEL_CLOSED'); remaining[channelId] += amount; @@ -79,7 +79,7 @@ contract OUTPACE { } function calcWithdrawAmount(address earner, Withdrawal calldata withdrawal) internal returns (uint) { - bytes32 channelId = keccak256(abi.encode(withdrawal.channel, block.chainid)); + bytes32 channelId = keccak256(abi.encode(withdrawal.channel)); // require that the is not closed uint challengeExpirationTime = challenges[channelId]; require(challengeExpirationTime != CLOSED, 'CHANNEL_CLOSED'); @@ -88,7 +88,7 @@ contract OUTPACE { if (challengeExpirationTime != 0) lastStateRoot[channelId] = withdrawal.stateRoot; // Check the signatures - bytes32 hashToSign = keccak256(abi.encode(address(this), channelId, withdrawal.stateRoot)); + bytes32 hashToSign = keccak256(abi.encode(address(this), channelId, withdrawal.stateRoot, block.chainid)); require(SignatureValidator.isValid(hashToSign, withdrawal.channel.leader, withdrawal.sigLeader), 'LEADER_SIG'); require(SignatureValidator.isValid(hashToSign, withdrawal.channel.follower, withdrawal.sigFollower), 'FOLLOWER_SIG'); // adds like 8k gas for 10 withdrawals (2% increase) @@ -115,7 +115,7 @@ contract OUTPACE { // same applies for resuming //require(remaining[channelId] > 0, 'no funds to be distributed'); require(msg.sender == channel.leader || msg.sender == channel.follower || msg.sender == channel.guardian, 'NOT_AUTHORIZED'); - bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); + bytes32 channelId = keccak256(abi.encode(channel)); require(challenges[channelId] == 0, 'CHANNEL_ALREADY_CHALLENGED'); uint expires = block.timestamp + CHALLENGE_TIME; challenges[channelId] = expires; @@ -124,11 +124,11 @@ contract OUTPACE { } function resume(Channel calldata channel, bytes32[3] calldata sigLeader, bytes32[3] calldata sigFollower) external { - bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); + bytes32 channelId = keccak256(abi.encode(channel)); uint challengeExpires = challenges[channelId]; require(challengeExpires != 0 && challengeExpires != CLOSED, 'CHANNEL_NOT_CHALLENGED'); // NOTE: we can resume the channel by mutual consent even if it's closable, so we won't check whether challengeExpires is in the future - bytes32 hashToSign = keccak256(abi.encodePacked('resume', channelId, challengeExpires)); + bytes32 hashToSign = keccak256(abi.encodePacked('resume', channelId, challengeExpires, block.chainid)); require(SignatureValidator.isValid(hashToSign, channel.leader, sigLeader), 'INVALID_LEADER_SIG'); require(SignatureValidator.isValid(hashToSign, channel.follower, sigFollower), 'INVALID_FOLLOWER_SIG'); @@ -140,7 +140,7 @@ contract OUTPACE { function close(Channel calldata channel) external { address guardian = channel.guardian; require(msg.sender == guardian, 'NOT_GUARDIAN'); - bytes32 channelId = keccak256(abi.encode(channel, block.chainid)); + bytes32 channelId = keccak256(abi.encode(channel)); uint challengeExpires = challenges[channelId]; require(challengeExpires != 0 && challengeExpires != CLOSED, 'CHANNEL_NOT_CHALLENGED'); require(block.timestamp > challengeExpires, 'CHANNEL_NOT_CLOSABLE'); From a1b4c3f49034605d83f54471b9a21d963780a665 Mon Sep 17 00:00:00 2001 From: Ivo Georgiev Date: Thu, 10 Oct 2024 09:54:24 +0300 Subject: [PATCH 3/3] README: update SupplyController info --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2862dfd6..729e1716 100644 --- a/README.md +++ b/README.md @@ -118,8 +118,9 @@ New V5 `SupplyController` (increased cap to account for the governance-induced b New V5 `SupplyController` (increase cap again to account for governance-induced burn): * Mainnet: https://etherscan.io/address/0xD4628FA47AAe2d0f4c8a204f36c2d93AA8dc31F5 -New V5 `SupplyController` (increase cap again to account for governance-induced burn and discount treasury tokens): +New V5 `SupplyController` (increase cap again to account for governance-induced burn by discounting treasury tokens): * Mainnet: https://etherscan.io/address/0x9B370599B2bf61806DDca1379257F26377472BEe +* Was later updated by setting the incentive rate on 05 Feb 2024 following another halving governance vote StakingPool: