From 00dd89bf3244d9f2c7a9c604e27825363776b615 Mon Sep 17 00:00:00 2001 From: taylorferran Date: Tue, 10 Jun 2025 14:20:20 +0100 Subject: [PATCH 1/3] Fix signatures and add latestTask details --- .../middleware/examples/ethPriceOracle.sol | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/bapp-contracts/src/middleware/examples/ethPriceOracle.sol b/bapp-contracts/src/middleware/examples/ethPriceOracle.sol index befe540..f8b29d7 100644 --- a/bapp-contracts/src/middleware/examples/ethPriceOracle.sol +++ b/bapp-contracts/src/middleware/examples/ethPriceOracle.sol @@ -25,14 +25,22 @@ contract EthPriceOracle is OwnableBasedApp { event NewTaskCreated(uint32 indexed taskIndex, bytes32 taskHash); event TaskResponded(uint32 indexed taskIndex, bytes32 taskHash, address responder, uint256 ethPrice); event BAppOptedInByStrategy(uint32 indexed strategyId, address indexed bApp, bytes data, address[] tokens, uint32[] obligationPercentages); - event DebugOptIn(uint32 indexed strategyId, address signer, address testOneAddress, address testTwoAddress); + + // Structs + struct Task { + uint32 taskNumber; + uint256 price; + address responder; + } // Storage mapping(uint32 => bytes32) public allTaskHashes; mapping(address => mapping(uint32 => bytes)) public allTaskResponses; - uint32 public latestTaskNum; + uint32 public latestTaskNum; // Tracks the current task + uint32 public nextTaskNumber; // Tracks the next task to be created uint256 public mostRecentPrice; mapping(uint32 => address) public strategySigner; + Task public latestCompleteTask; // Stores the latest completed task details ISSVBasedApps public immutable ssvBasedApps; constructor( @@ -46,9 +54,10 @@ contract EthPriceOracle is OwnableBasedApp { bytes32 taskHash = keccak256(abi.encodePacked(block.number, msg.sender)); // store hash of task on-chain, emit event, and increase taskNum - allTaskHashes[latestTaskNum] = taskHash; - emit NewTaskCreated(latestTaskNum, taskHash); - latestTaskNum = latestTaskNum + 1; + allTaskHashes[nextTaskNumber] = taskHash; + emit NewTaskCreated(nextTaskNumber, taskHash); + latestTaskNum = nextTaskNumber; + nextTaskNumber = nextTaskNumber + 1; return taskHash; } @@ -59,26 +68,25 @@ contract EthPriceOracle is OwnableBasedApp { uint256 ethPrice, bytes[] calldata signatures, address[] calldata signers, - uint32 strategyId + uint32[] calldata strategyIds ) external { // check that the task is valid and hasn't been responded to yet if (taskHash != allTaskHashes[taskNumber]) { revert TaskMismatch(); } if (allTaskResponses[msg.sender][taskNumber].length != 0) { revert AlreadyResponded(); } if (ethPrice <= 0) { revert InvalidPrice(); } - if (signatures.length != signers.length) { revert InvalidSignature(); } + if (signatures.length != signers.length || signatures.length != strategyIds.length) { revert InvalidSignature(); } // Create the message that was signed (task num + price) bytes32 messageHash = keccak256(abi.encodePacked(taskNumber, ethPrice)); - - // Get the strategy signer - address strategySignerAddress = strategySigner[strategyId]; // Verify each signature for (uint i = 0; i < signatures.length; i++) { - // Recover the signer address from the signature address recoveredSigner = messageHash.recover(signatures[i]); + // Get the strategy signer for this specific strategy + address strategySignerAddress = strategySigner[strategyIds[i]]; + if (strategySignerAddress != address(0)) { // if strategy has a signer set, verify this signer is the correct one if (strategySignerAddress != signers[i]) { @@ -87,7 +95,7 @@ contract EthPriceOracle is OwnableBasedApp { } else { // if strategy has no signer set, check the signer is the owner of the strategy uint32 derivedStrategyId = IAccountBAppStrategy(address(ssvBasedApps)).accountBAppStrategy(recoveredSigner, address(this)); - if (derivedStrategyId != strategyId) { + if (derivedStrategyId != strategyIds[i]) { revert NotOptedIn(); } } @@ -96,6 +104,14 @@ contract EthPriceOracle is OwnableBasedApp { // Store the response allTaskResponses[msg.sender][taskNumber] = abi.encode(ethPrice); mostRecentPrice = ethPrice; + latestTaskNum = taskNumber; + + // Update the latest complete task + latestCompleteTask = Task({ + taskNumber: taskNumber, + price: ethPrice, + responder: msg.sender + }); // Emit event with the ETH price emit TaskResponded(taskNumber, taskHash, msg.sender, ethPrice); @@ -112,7 +128,6 @@ contract EthPriceOracle is OwnableBasedApp { // Store the address in the mapping strategySigner[strategyId] = signer; - emit DebugOptIn(strategyId, signer, testOne[1], testTwo[2]); return true; } From 932a056691c50178bbd81875a3c25dfa92c95878 Mon Sep 17 00:00:00 2001 From: taylorferran Date: Wed, 11 Jun 2025 11:35:37 +0100 Subject: [PATCH 2/3] Riccardo comment updates --- bapp-contracts/src/middleware/examples/ethPriceOracle.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bapp-contracts/src/middleware/examples/ethPriceOracle.sol b/bapp-contracts/src/middleware/examples/ethPriceOracle.sol index f8b29d7..aaf8180 100644 --- a/bapp-contracts/src/middleware/examples/ethPriceOracle.sol +++ b/bapp-contracts/src/middleware/examples/ethPriceOracle.sol @@ -28,8 +28,8 @@ contract EthPriceOracle is OwnableBasedApp { // Structs struct Task { - uint32 taskNumber; uint256 price; + uint32 taskNumber; address responder; } @@ -80,7 +80,7 @@ contract EthPriceOracle is OwnableBasedApp { bytes32 messageHash = keccak256(abi.encodePacked(taskNumber, ethPrice)); // Verify each signature - for (uint i = 0; i < signatures.length; i++) { + for (uint256 i = 0; i < signatures.length; i++) { // Recover the signer address from the signature address recoveredSigner = messageHash.recover(signatures[i]); @@ -108,8 +108,8 @@ contract EthPriceOracle is OwnableBasedApp { // Update the latest complete task latestCompleteTask = Task({ - taskNumber: taskNumber, price: ethPrice, + taskNumber: taskNumber, responder: msg.sender }); From d8c69eadda9efab48828c153acbfcf9fdcf2a949 Mon Sep 17 00:00:00 2001 From: taylorferran Date: Thu, 12 Jun 2025 08:59:14 +0100 Subject: [PATCH 3/3] Use latestTaskNum in event --- bapp-contracts/src/middleware/examples/ethPriceOracle.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bapp-contracts/src/middleware/examples/ethPriceOracle.sol b/bapp-contracts/src/middleware/examples/ethPriceOracle.sol index aaf8180..ca9d048 100644 --- a/bapp-contracts/src/middleware/examples/ethPriceOracle.sol +++ b/bapp-contracts/src/middleware/examples/ethPriceOracle.sol @@ -55,9 +55,9 @@ contract EthPriceOracle is OwnableBasedApp { // store hash of task on-chain, emit event, and increase taskNum allTaskHashes[nextTaskNumber] = taskHash; - emit NewTaskCreated(nextTaskNumber, taskHash); latestTaskNum = nextTaskNumber; nextTaskNumber = nextTaskNumber + 1; + emit NewTaskCreated(latestTaskNum, taskHash); return taskHash; }